Jelajahi Sumber

improve _isinstance for var types (#5072)

Khaleel Al-Adhami 1 bulan lalu
induk
melakukan
077acd261b
2 mengubah file dengan 42 tambahan dan 1 penghapusan
  1. 11 1
      reflex/utils/types.py
  2. 31 0
      tests/units/utils/test_types.py

+ 11 - 1
reflex/utils/types.py

@@ -607,7 +607,7 @@ def _isinstance(
     if cls is None or cls is type(None):
         return obj is None
 
-    if cls and is_union(cls):
+    if cls is not None and is_union(cls):
         return any(
             _isinstance(obj, arg, nested=nested, treat_var_as_type=treat_var_as_type)
             for arg in get_args(cls)
@@ -643,6 +643,16 @@ def _isinstance(
         # cls is a simple generic class
         return isinstance(obj, origin)
 
+    if origin is Var and args:
+        # cls is a Var
+        return _isinstance(
+            obj,
+            args[0],
+            nested=nested,
+            treat_var_as_type=treat_var_as_type,
+            treat_mutable_obj_as_immutable=treat_mutable_obj_as_immutable,
+        )
+
     if nested > 0 and args:
         if origin is list:
             expected_class = Sequence if treat_mutable_obj_as_immutable else list

+ 31 - 0
tests/units/utils/test_types.py

@@ -3,6 +3,7 @@ from typing import Any, Literal
 import pytest
 
 from reflex.utils import types
+from reflex.vars.base import Var
 
 
 @pytest.mark.parametrize(
@@ -90,3 +91,33 @@ class ChildGenericDict(GenericDict):
 )
 def test_has_args(cls, expected: bool) -> None:
     assert types.has_args(cls) == expected
+
+
+@pytest.mark.parametrize(
+    ("value", "cls", "expected"),
+    [
+        (1, int, True),
+        (1, str, False),
+        (1, float, True),
+        ("1", str, True),
+        ("1", int, False),
+        (1.0, float, True),
+        (1.0, int, False),
+        ([], list[int], True),
+        ([1], list[int], True),
+        ([1.0], list[int], False),
+        ([1], list[str], False),
+        ({}, dict[str, str], True),
+        ({"a": "b"}, dict[str, str], True),
+        ({"a": 1}, dict[str, str], False),
+        (False, bool, True),
+        (False, Var[bool], True),
+        (False, Var[bool] | None, True),
+        (Var.create(False), bool, True),
+        (Var.create(False), Var[bool], True),
+        (Var.create(False), Var[bool] | None, True),
+        (Var.create(False), Var[bool] | str, True),
+    ],
+)
+def test_isinstance(value, cls, expected: bool) -> None:
+    assert types._isinstance(value, cls, nested=1, treat_var_as_type=True) == expected