diff --git a/reflex/utils/types.py b/reflex/utils/types.py index 0d6f878ec..7de4fe206 100644 --- a/reflex/utils/types.py +++ b/reflex/utils/types.py @@ -778,6 +778,24 @@ StateBases = get_base_class(StateVar) StateIterBases = get_base_class(StateIterVar) +def safe_issubclass(cls: Any, class_or_tuple: Any, /) -> bool: + """Check if a class is a subclass of another class or a tuple of classes. + + Args: + cls: The class to check. + class_or_tuple: The class or tuple of classes to check against. + + Returns: + Whether the class is a subclass of the other class or tuple of classes. + """ + try: + return issubclass(cls, class_or_tuple) + except TypeError as e: + raise TypeError( + f"Invalid arguments for issubclass: {cls}, {class_or_tuple}" + ) from e + + def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> bool: """Check if a type hint is a subclass of another type hint. @@ -798,7 +816,7 @@ def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> boo if provided_type_origin is None and accepted_type_origin is None: # In this case, we are dealing with a non-generic type, so we can use issubclass - return issubclass(possible_subclass, possible_superclass) + return safe_issubclass(possible_subclass, possible_superclass) # Remove this check when Python 3.10 is the minimum supported version if hasattr(types, "UnionType"): @@ -835,17 +853,17 @@ def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> boo iterable_type = accepted_args[0] if accepted_args else Any if provided_type_origin is None: - if not issubclass( + if not safe_issubclass( possible_subclass, (accepted_type_origin or possible_superclass) ): return False - if issubclass(possible_subclass, str) and not isinstance( + if safe_issubclass(possible_subclass, str) and not isinstance( iterable_type, TypeVar ): return typehint_issubclass(str, iterable_type) - if not issubclass( + if not safe_issubclass( provided_type_origin, (accepted_type_origin or possible_superclass) ): return False @@ -867,7 +885,7 @@ def typehint_issubclass(possible_subclass: Any, possible_superclass: Any) -> boo return True # Check if the origin of both types is the same (e.g., list for List[int]) - if not issubclass( + if not safe_issubclass( provided_type_origin or possible_subclass, accepted_type_origin or possible_superclass, ):