reflex icon indicating copy to clipboard operation
reflex copied to clipboard

don't use _outer_type if we don't have to

Open adhami3310 opened this issue 1 year ago β€’ 1 comments

turns out _outer_type strips out None

adhami3310 avatar Dec 12 '24 14:12 adhami3310

I get these errors when I test with this code:

from typing import Optional

import reflex as rx


class State(rx.State):
    foo: rx.Field[Optional[str]] = rx.field(None) # throws a compile time error (see below)
    simple: rx.Field[str | None] = rx.field(None) # throws a compile time error (see below)
    bar: str | None = "world" # runtime error(see below)
    name: rx.Field[str | None] = rx.field(None) # compile time error(see below)


def index() -> rx.Component:
    return rx.container(
        rx.button("Clear", on_click=lambda: State.set_name(None)),
        rx.text("rx.input"),
        rx.input(value=State.name, on_change=State.set_name),
        rx.text("rx.el.input"),
        rx.el.input(value=State.name),
    )


app = rx.App()
app.add_page(index)


foo: rx.Field[Optional[str]]

  File "/Users/eli/Documents/work/Pynecone-io/pynecone-forks/reflex/demos/oct-04-24/fourth/fourth/fourth.py", line 16, in <module>
    class State(rx.State):
  File "pydantic/main.py", line 282, in pydantic.main.ModelMetaclass.__new__
  File "<frozen abc>", line 106, in __new__
  File "/Users/eli/Documents/work/Pynecone-io/pynecone-forks/reflex/reflex/state.py", line 574, in __init_subclass__
    cls._init_var(prop)
  File "/Users/eli/Documents/work/Pynecone-io/pynecone-forks/reflex/reflex/state.py", line 991, in _init_var
    raise VarTypeError(
reflex.utils.exceptions.VarTypeError: State vars must be primitive Python types, Plotly figures, Pandas dataframes, or subclasses of rx.Base. Found var "reflex___state____state__fourth___fourth____state.foo" with type typing.Optional[reflex.vars.base.Field[typing.Optional[str]]].

simple: rx.Field[str | None] = rx.field(None) [same as above]

    class State(rx.State):
  File "pydantic/main.py", line 282, in pydantic.main.ModelMetaclass.__new__
  File "<frozen abc>", line 106, in __new__
  File "/Users/eli/Documents/work/Pynecone-io/pynecone-forks/reflex/reflex/state.py", line 574, in __init_subclass__
    cls._init_var(prop)
  File "/Users/eli/Documents/work/Pynecone-io/pynecone-forks/reflex/reflex/state.py", line 991, in _init_var
    raise VarTypeError(
reflex.utils.exceptions.VarTypeError: State vars must be primitive Python types, Plotly figures, Pandas dataframes, or subclasses of rx.Base. Found var "reflex___state____state__fourth___fourth____state.simple" with type typing.Optional[reflex.vars.base.Field[str | None]].

bar: str | None = "world"

Task exception was never retrieved
future: <Task finished name='Task-18' coro=<AsyncServer._handle_event_internal() done, defined at /Users/eli/Library/Caches/pypoetry/virtualenvs/reflex-K7o9YeT9-py3.11/lib/python3.11/site-packages/socketio/asyncio_server.py:522> exception=AttributeError("'str' object has no attribute 'items'")>
Traceback (most recent call last):
  File "/Users/eli/Library/Caches/pypoetry/virtualenvs/reflex-K7o9YeT9-py3.11/lib/python3.11/site-packages/socketio/asyncio_server.py", line 524, in _handle_event_internal
    r = await server._trigger_event(data[0], namespace, sid, *data[1:])
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eli/Library/Caches/pypoetry/virtualenvs/reflex-K7o9YeT9-py3.11/lib/python3.11/site-packages/socketio/asyncio_server.py", line 569, in _trigger_event
    return await self.namespace_handlers[namespace].trigger_event(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/eli/Library/Caches/pypoetry/virtualenvs/reflex-K7o9YeT9-py3.11/lib/python3.11/site-packages/socketio/asyncio_namespace.py", line 37, in trigger_event
    ret = await handler(*args)
          ^^^^^^^^^^^^^^^^^^^^
  File "/Users/eli/Documents/work/Pynecone-io/pynecone-forks/reflex/reflex/app.py", line 1567, in on_event
    **{k: v for k, v in fields.items() if k not in ("handler", "event_actions")}
                        ^^^^^^^^^^^^
AttributeError: 'str' object has no attribute 'items'

name: rx.Field[str | None] = rx.field(None) [same as simple]

ElijahAhianyo avatar Dec 12 '24 19:12 ElijahAhianyo

This seems to come from setting parent_state to None in BaseState.init, but it's annotated as an Optional so passing None should be legitimate

So this issue is annoying, it's almost impossible to know if something is truly optional or not, one thing we could check is if annotation starts with Optional ?

adhami3310 avatar Dec 13 '24 20:12 adhami3310

got unblocked on pyright, will investigate later to see if it's working

adhami3310 avatar Dec 18 '24 18:12 adhami3310

CodSpeed Performance Report

Merging #4528 will improve performances by Γ—2.4

Comparing don't-use-_outer_type-if-we-don't-have-to (0721200) with main (d97d1d9)

Summary

⚑ 3 improvements
βœ… 9 untouched benchmarks

Benchmarks breakdown

Benchmark BASE HEAD Change
⚑ test_evaluate_page[_complicated_page] 168.8 ms 81.3 ms Γ—2.1
⚑ test_evaluate_page[_simple_page] 2.8 ms 1.2 ms Γ—2.4
⚑ test_evaluate_page[_stateful_page] 23.4 ms 11.1 ms Γ—2.1

codspeed-hq[bot] avatar Mar 04 '25 22:03 codspeed-hq[bot]