fix: async default setters break setvar (#4169)
* fix: async default setters break setvar * fix unit test
This commit is contained in:
parent
d0c1eb7488
commit
c0ed8b7d91
@ -220,6 +220,7 @@ class EventHandlerSetVar(EventHandler):
|
|||||||
Raises:
|
Raises:
|
||||||
AttributeError: If the given Var name does not exist on the state.
|
AttributeError: If the given Var name does not exist on the state.
|
||||||
EventHandlerValueError: If the given Var name is not a str
|
EventHandlerValueError: If the given Var name is not a str
|
||||||
|
NotImplementedError: If the setter for the given Var is async
|
||||||
"""
|
"""
|
||||||
from reflex.utils.exceptions import EventHandlerValueError
|
from reflex.utils.exceptions import EventHandlerValueError
|
||||||
|
|
||||||
@ -228,11 +229,20 @@ class EventHandlerSetVar(EventHandler):
|
|||||||
raise EventHandlerValueError(
|
raise EventHandlerValueError(
|
||||||
f"Var name must be passed as a string, got {args[0]!r}"
|
f"Var name must be passed as a string, got {args[0]!r}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
handler = getattr(self.state_cls, constants.SETTER_PREFIX + args[0], None)
|
||||||
|
|
||||||
# Check that the requested Var setter exists on the State at compile time.
|
# Check that the requested Var setter exists on the State at compile time.
|
||||||
if getattr(self.state_cls, constants.SETTER_PREFIX + args[0], None) is None:
|
if handler is None:
|
||||||
raise AttributeError(
|
raise AttributeError(
|
||||||
f"Variable `{args[0]}` cannot be set on `{self.state_cls.get_full_name()}`"
|
f"Variable `{args[0]}` cannot be set on `{self.state_cls.get_full_name()}`"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if asyncio.iscoroutinefunction(handler.fn):
|
||||||
|
raise NotImplementedError(
|
||||||
|
f"Setter for {args[0]} is async, which is not supported."
|
||||||
|
)
|
||||||
|
|
||||||
return super().__call__(*args)
|
return super().__call__(*args)
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,6 +106,7 @@ class TestState(BaseState):
|
|||||||
fig: Figure = Figure()
|
fig: Figure = Figure()
|
||||||
dt: datetime.datetime = datetime.datetime.fromisoformat("1989-11-09T18:53:00+01:00")
|
dt: datetime.datetime = datetime.datetime.fromisoformat("1989-11-09T18:53:00+01:00")
|
||||||
_backend: int = 0
|
_backend: int = 0
|
||||||
|
asynctest: int = 0
|
||||||
|
|
||||||
@ComputedVar
|
@ComputedVar
|
||||||
def sum(self) -> float:
|
def sum(self) -> float:
|
||||||
@ -129,6 +130,14 @@ class TestState(BaseState):
|
|||||||
"""Do something."""
|
"""Do something."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def set_asynctest(self, value: int):
|
||||||
|
"""Set the asynctest value. Intentionally overwrite the default setter with an async one.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value: The new value.
|
||||||
|
"""
|
||||||
|
self.asynctest = value
|
||||||
|
|
||||||
|
|
||||||
class ChildState(TestState):
|
class ChildState(TestState):
|
||||||
"""A child state fixture."""
|
"""A child state fixture."""
|
||||||
@ -313,6 +322,7 @@ def test_class_vars(test_state):
|
|||||||
"upper",
|
"upper",
|
||||||
"fig",
|
"fig",
|
||||||
"dt",
|
"dt",
|
||||||
|
"asynctest",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -733,6 +743,7 @@ def test_reset(test_state, child_state):
|
|||||||
"mapping",
|
"mapping",
|
||||||
"dt",
|
"dt",
|
||||||
"_backend",
|
"_backend",
|
||||||
|
"asynctest",
|
||||||
}
|
}
|
||||||
|
|
||||||
# The dirty vars should be reset.
|
# The dirty vars should be reset.
|
||||||
@ -3179,6 +3190,13 @@ async def test_setvar(mock_app: rx.App, token: str):
|
|||||||
TestState.setvar(42, 42)
|
TestState.setvar(42, 42)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_setvar_async_setter():
|
||||||
|
"""Test that overridden async setters raise Exception when used with setvar."""
|
||||||
|
with pytest.raises(NotImplementedError):
|
||||||
|
TestState.setvar("asynctest", 42)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif("REDIS_URL" not in os.environ, reason="Test requires redis")
|
@pytest.mark.skipif("REDIS_URL" not in os.environ, reason="Test requires redis")
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"expiration_kwargs, expected_values",
|
"expiration_kwargs, expected_values",
|
||||||
|
@ -601,6 +601,7 @@ formatted_router = {
|
|||||||
"sum": 3.14,
|
"sum": 3.14,
|
||||||
"upper": "",
|
"upper": "",
|
||||||
"router": formatted_router,
|
"router": formatted_router,
|
||||||
|
"asynctest": 0,
|
||||||
},
|
},
|
||||||
ChildState.get_full_name(): {
|
ChildState.get_full_name(): {
|
||||||
"count": 23,
|
"count": 23,
|
||||||
|
Loading…
Reference in New Issue
Block a user