-
Notifications
You must be signed in to change notification settings - Fork 301
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 DU refinements: provide access to DU case constructors to python code #3558
base: main
Are you sure you want to change the base?
Python DU refinements: provide access to DU case constructors to python code #3558
Conversation
…ble into python-du-refinements # Conflicts: # src/Fable.Transforms/Python/Fable2Python.fs
…sts that emit the python calls and assert they are equivalent to the F# constructed values.
Note that I also intended to work on exposing I'm wondering if I should still go forward, because there is still no easy way to "pattern match" / branch on the DU values from consuming python code (AFAIK). |
Any opinion how those There is a bit of a conflict with the DU cases having the PascalCase "type" casing and this being an instance get property which would mandate snake_case. |
Experimenting with how we could support pattern matching of DUs from Python: class _U(Union):
def __init__(self, tag: int, *fields: Any) -> None:
super().__init__()
self.tag: int = tag or 0
self.fields: Array[Any] = list(fields)
@staticmethod
def cases() -> list[str]:
return ["Z", "Y"]
class Z(_U):
__match_args__ = ("value",)
def __init__(self, value: int) -> None:
self.value = value
super().__init__(0, value)
class Y(_U):
__match_args__ = ("name",)
def __init__(self, name: str) -> None:
self.name = name
super().__init__(1, name)
U = Z | Y
def create() -> U:
return Z(1)
u: U = create()
match u:
case Z(value=10):
print("Z")
case Y(name=name):
print("Y")
case _:
print("Not Z or Y") |
@dbrattli this looks interesting! Would it make more sense to put the cases as inner classes? I'm wondering because there is the concern of having DU cases that are named the same as outer type, which is possible in F#, but would likely cause some headaches on the python side. type Case1 = { a:int }
type Case2 = { b:string }
type DU =
| Case1 of Case1
| Case2 of Case2 |
Btw some reading I found:
We should investigate if we should leave the DUs as is and instead make a feature similar to |
I'd like to provide DU case constructors to the python code that interops with code generated by Fable.
This suggested PR seems to do what I want, albeit there is edge case of generic type annotation not being carried in the case constructor of union with generic type argument, it doesn't seem to cause an issue to the python interpreter (and I'm not clear those would be required either).
Short quick test:
Turned by Fable into:
cc: @dbrattli