widgetti / solara

A Pure Python, React-style Framework for Scaling Your Jupyter and Web Apps
https://solara.dev
MIT License
1.62k stars 105 forks source link

feat: avoid use of Ref, make use of descriptor to add reactive behavior #49

Open maartenbreddels opened 1 year ago

maartenbreddels commented 1 year ago

If you have a dataclass like:

@dataclasses.dataclass(frozen=True)
class Bears:
    type: str
    count: int = dataclasses.field()

And you transform it to:

@dataclasses.dataclass(frozen=True)
class Bears:
    count: Field[int]
    type: Field[str] = field(dataclasses.field(default_factory=str))

You get the same runtime behavior, but get a type-safe reactive wrapper around this type:

    bears = Reactive(Bears(type="brown", count=1))
    def on_change(bears: Bears):
        print("new bears", bears)
    bears.subscribe(on_change)

    def on_count_change(count: str):
        print("new count", count)
    bears.fields.count.subscribe(on_count_change) # <-- type error, subscribe expects (int) -> None

This already works with pyright due to: https://github.com/microsoft/pyright/issues/3245

but mypy does not yet support this: https://github.com/python/mypy/issues/13856

See also: https://github.com/python/mypy/issues/14868

ping @manzt and @tlambert03 for a less boilerplate way of having a type safe event/update/etc system

railway-app[bot] commented 1 year ago

This PR is being deployed to Railway 🚅

web: ◻️ REMOVED