diff --git a/pynecone/utils.py b/pynecone/utils.py index 14e78feb7..acb016042 100644 --- a/pynecone/utils.py +++ b/pynecone/utils.py @@ -159,8 +159,16 @@ def _issubclass(cls: GenericType, cls_check: GenericType) -> bool: return True if cls in [Any, Callable]: return False + + # Get the base classes. cls_base = get_base_class(cls) cls_check_base = get_base_class(cls_check) + + # The class we're checking should not be a union. + if isinstance(cls_base, tuple): + return False + + # Check if the types match. return cls_check_base == Any or issubclass(cls_base, cls_check_base) diff --git a/tests/test_utils.py b/tests/test_utils.py index 878df7322..c373706b6 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,8 +1,9 @@ -import typing +from typing import Any, List, Union import pytest from pynecone import utils +from pynecone.var import Var @pytest.mark.parametrize( @@ -195,8 +196,8 @@ def test_merge_imports(): (int, False), (float, False), (bool, False), - (typing.List, True), - (typing.List[int], True), + (List, True), + (List[int], True), ], ) def test_is_generic_alias(cls: type, expected: bool): @@ -261,3 +262,24 @@ def test_setup_frontend(tmp_path, mocker): ) def test_is_backend_variable(input, output): assert utils.is_backend_variable(input) == output + + +@pytest.mark.parametrize( + "cls, cls_check, expected", + [ + (int, int, True), + (int, float, False), + (int, Union[int, float], True), + (float, Union[int, float], True), + (str, Union[int, float], False), + (List[int], List[int], True), + (List[int], List[float], True), + (Union[int, float], Union[int, float], False), + (Union[int, Var[int]], Var[int], False), + (int, Any, True), + (Any, Any, True), + (Union[int, float], Any, True), + ], +) +def test_issubclass(cls: type, cls_check: type, expected: bool): + assert utils._issubclass(cls, cls_check) == expected