Sfoglia il codice sorgente

convert event return types to type hints (#4331)

Khaleel Al-Adhami 6 mesi fa
parent
commit
4c4c59bf04
1 ha cambiato i file con 37 aggiunte e 1 eliminazioni
  1. 37 1
      reflex/state.py

+ 37 - 1
reflex/state.py

@@ -11,6 +11,7 @@ import inspect
 import json
 import json
 import pickle
 import pickle
 import sys
 import sys
+import typing
 import uuid
 import uuid
 from abc import ABC, abstractmethod
 from abc import ABC, abstractmethod
 from collections import defaultdict
 from collections import defaultdict
@@ -90,7 +91,13 @@ from reflex.utils.exceptions import (
 )
 )
 from reflex.utils.exec import is_testing_env
 from reflex.utils.exec import is_testing_env
 from reflex.utils.serializers import serializer
 from reflex.utils.serializers import serializer
-from reflex.utils.types import _isinstance, get_origin, override
+from reflex.utils.types import (
+    _isinstance,
+    get_origin,
+    is_union,
+    override,
+    value_inside_optional,
+)
 from reflex.vars import VarData
 from reflex.vars import VarData
 
 
 if TYPE_CHECKING:
 if TYPE_CHECKING:
@@ -1713,6 +1720,35 @@ class BaseState(Base, ABC, extra=pydantic.Extra.allow):
         # Get the function to process the event.
         # Get the function to process the event.
         fn = functools.partial(handler.fn, state)
         fn = functools.partial(handler.fn, state)
 
 
+        try:
+            type_hints = typing.get_type_hints(handler.fn)
+        except Exception:
+            type_hints = {}
+
+        for arg, value in list(payload.items()):
+            hinted_args = type_hints.get(arg, Any)
+            if hinted_args is Any:
+                continue
+            if is_union(hinted_args):
+                if value is None:
+                    continue
+                hinted_args = value_inside_optional(hinted_args)
+            if (
+                isinstance(value, dict)
+                and inspect.isclass(hinted_args)
+                and (
+                    dataclasses.is_dataclass(hinted_args)
+                    or issubclass(hinted_args, Base)
+                )
+            ):
+                payload[arg] = hinted_args(**value)
+            if isinstance(value, list) and (hinted_args is set or hinted_args is Set):
+                payload[arg] = set(value)
+            if isinstance(value, list) and (
+                hinted_args is tuple or hinted_args is Tuple
+            ):
+                payload[arg] = tuple(value)
+
         # Wrap the function in a try/except block.
         # Wrap the function in a try/except block.
         try:
         try:
             # Handle async functions.
             # Handle async functions.