Browse Source

Fix substate event handler conversions (#861)

Nikhil Rao 2 years ago
parent
commit
1029d3483a
3 changed files with 8 additions and 23 deletions
  1. 0 4
      pynecone/app.py
  2. 7 18
      pynecone/state.py
  3. 1 1
      tests/middleware/test_hydrate_middleware.py

+ 0 - 4
pynecone/app.py

@@ -397,7 +397,6 @@ class App(Base):
         compiler.compile_theme(self.style)
 
         # Compile the pages.
-        self.state.set_handlers()
         custom_components = set()
         for route, component in self.pages.items():
             component.add_style(self.style)
@@ -409,9 +408,6 @@ class App(Base):
         # Compile the custom components.
         compiler.compile_components(custom_components)
 
-        # To support calling event handlers from other handlers.
-        self.state.convert_handlers_to_fns()
-
 
 async def process(
     app: App, event: Event, sid: str, headers: Dict, client_ip: str

+ 7 - 18
pynecone/state.py

@@ -21,6 +21,7 @@ from typing import (
 )
 
 import cloudpickle
+import pydantic
 from redis import Redis
 
 from pynecone import constants
@@ -32,7 +33,7 @@ from pynecone.var import BaseVar, ComputedVar, PCDict, PCList, Var
 Delta = Dict[str, Any]
 
 
-class State(Base, ABC):
+class State(Base, ABC, extra=pydantic.Extra.allow):
     """The state of the app."""
 
     # A map from the var name to the var.
@@ -87,6 +88,11 @@ class State(Base, ABC):
         for substate in self.get_substates():
             self.substates[substate.get_name()] = substate().set(parent_state=self)
 
+        # Convert the event handlers to functions.
+        for name, event_handler in self.event_handlers.items():
+            setattr(self, name, event_handler.fn)
+
+        # Initialize the mutable fields.
         self._init_mutable_fields()
 
     def _init_mutable_fields(self):
@@ -189,23 +195,6 @@ class State(Base, ABC):
             if not name.startswith("_") and isinstance(fn, Callable)
         }
         cls.event_handlers = {name: EventHandler(fn=fn) for name, fn in events.items()}
-
-        cls.set_handlers()
-
-    @classmethod
-    def convert_handlers_to_fns(cls):
-        """Convert the event handlers to functions.
-
-        This is done so the state functions can be called as normal functions during runtime.
-        """
-        for name, event_handler in cls.event_handlers.items():
-            setattr(cls, name, event_handler.fn)
-        for substate in cls.get_substates():
-            substate.convert_handlers_to_fns()
-
-    @classmethod
-    def set_handlers(cls):
-        """Set the state class handlers."""
         for name, event_handler in cls.event_handlers.items():
             setattr(cls, name, event_handler)
 

+ 1 - 1
tests/middleware/test_hydrate_middleware.py

@@ -30,7 +30,7 @@ class TestState2(State):
             Chain of EventHandlers
         """
         self.num += 1
-        return [self.change_name()]
+        return self.change_name
 
     def change_name(self):
         """Test handler to change name."""