Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python: typematching against an Interface leads to incorrect pattern matches #3972

Open
kMutagene opened this issue Dec 9, 2024 · 1 comment
Labels
python Python

Comments

@kMutagene
Copy link

Description

It seems like, when typematching against an interface, incorrect match result code is generated.

Repro code

See REPL

or transpile this code:

type IInterface =
    abstract member LOL : int

let typeMatchSomeBoxedObject (o:obj) =
    match o with
    | :? int -> 1
    | :? IInterface -> 2
    | _ -> 3

let d = (typeMatchSomeBoxedObject "lol")

printfn "%A" d

the resulting python code:

from abc import abstractmethod
from typing import (Protocol, Any)
from fable_modules.fable_library.decimal_ import from_parts
from fable_modules.fable_library.string_ import (to_console, printf)
from fable_modules.fable_library.types import uint8

class IInterface(Protocol):
    @property
    @abstractmethod
    def LOL(self) -> int:
        ...

def type_match_some_boxed_object(o: Any=None) -> int:
    if str(type(o)) == "<class \'int\'>":
        return 1
    else: 
        return 2

d: int = type_match_some_boxed_object(from_parts(2, 0, 0, False, uint8(0)))

to_console(printf("%A"))(d)

Expected and actual results

Expected: A type that does not implement the interface does not match the second match case and therefore 3 is returned via wildcard match case. This is what happens when executing the F# code

Actual: 2 is returned, as the wildcard match case is not generated

Related information

  • Fable version: 4.24.0
@MangelMaxime
Copy link
Member

As a note, Fable for JavaScript is not able to type check against an interface and generates

export function typeMatchSomeBoxedObject(o) {
    if (typeof o === "number") {
        return 1;
    }
    else {
        return 3;
    }
}

but Fable JavaScript generates a warning when type checking against an interface to inform the user.


Going back to the Python target, looking at the code I suppose we should be able to type check against IInterface because the interface does generate an actual Python type.

Looking online, I see that we could use isinstance or type to do that. What should be used here? My supposition is isinstace because it will also check subclasses.

@MangelMaxime MangelMaxime added the python Python label Dec 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
python Python
Projects
None yet
Development

No branches or pull requests

2 participants