From a9ee9f6d44f51f06fa766cf706ed1652ab1dae7e Mon Sep 17 00:00:00 2001 From: Nikhil Rao Date: Thu, 27 Apr 2023 19:30:52 -0700 Subject: [PATCH] Fix event handler calls to handlers (#899) --- pynecone/state.py | 4 +++- scripts/integration.sh | 2 +- tests/test_state.py | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/pynecone/state.py b/pynecone/state.py index cded54416..54d060929 100644 --- a/pynecone/state.py +++ b/pynecone/state.py @@ -97,7 +97,9 @@ class State(Base, ABC, extra=pydantic.Extra.allow): # Convert the event handlers to functions. for name, event_handler in self.event_handlers.items(): - setattr(self, name, event_handler.fn) + fn = functools.partial(event_handler.fn, self) + fn.__qualname__ = event_handler.fn.__qualname__ # type: ignore + setattr(self, name, fn) # Initialize the mutable fields. self._init_mutable_fields() diff --git a/scripts/integration.sh b/scripts/integration.sh index 16ef90609..c2c666e80 100644 --- a/scripts/integration.sh +++ b/scripts/integration.sh @@ -15,7 +15,7 @@ while ! nc -z localhost 3000 || ! lsof -i :8000 >/dev/null; do echo "Error: Server process with PID $pid exited early" break fi - if ((wait_time >= 120)); then + if ((wait_time >= 200)); then echo "Error: Timeout waiting for ports 3000 and 8000 to become available" break fi diff --git a/tests/test_state.py b/tests/test_state.py index 4c3e8d868..87508980c 100644 --- a/tests/test_state.py +++ b/tests/test_state.py @@ -860,3 +860,39 @@ def test_conditional_computed_vars(): assert ms._dirty_computed_vars(from_vars={"flag"}) == {"rendered_var"} assert ms._dirty_computed_vars(from_vars={"t2"}) == {"rendered_var"} assert ms._dirty_computed_vars(from_vars={"t1"}) == {"rendered_var"} + + +def test_event_handlers_convert_to_fns(test_state, child_state): + """Test that when the state is initialized, event handlers are converted to fns. + + Args: + test_state: A state with event handlers. + child_state: A child state with event handlers. + """ + # The class instances should be event handlers. + assert isinstance(TestState.do_something, EventHandler) + assert isinstance(ChildState.change_both, EventHandler) + + # The object instances should be fns. + test_state.do_something() + + child_state.change_both(value="goose", count=9) + assert child_state.value == "GOOSE" + assert child_state.count == 18 + + +def test_event_handlers_call_other_handlers(): + """Test that event handlers can call other event handlers.""" + + class MainState(State): + v: int = 0 + + def set_v(self, v: int): + self.v = v + + def set_v2(self, v: int): + self.set_v(v) + + ms = MainState() + ms.set_v2(1) + assert ms.v == 1