Skip to content

Commit 7d9f20a

Browse files
authored
stubtest: check type aliases (#10908)
Fixes #10393 Co-authored-by: hauntsaninja <>
1 parent 7b0df28 commit 7d9f20a

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

mypy/stubtest.py

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,31 @@ def verify_decorator(
858858
def verify_typealias(
859859
stub: nodes.TypeAlias, runtime: MaybeMissing[Any], object_path: List[str]
860860
) -> Iterator[Error]:
861-
if False:
862-
yield None
861+
if isinstance(runtime, Missing):
862+
# ignore type aliases that don't have a runtime counterpart
863+
return
864+
stub_target = mypy.types.get_proper_type(stub.target)
865+
if isinstance(stub_target, mypy.types.Instance):
866+
yield from verify(stub_target.type, runtime, object_path)
867+
return
868+
if isinstance(stub_target, mypy.types.UnionType):
869+
if not getattr(runtime, "__origin__", None) is Union:
870+
yield Error(object_path, "is not a Union", stub, runtime, stub_desc=str(stub_target))
871+
# could check Union contents here...
872+
return
873+
if isinstance(stub_target, mypy.types.TupleType):
874+
if tuple not in getattr(runtime, "__mro__", ()):
875+
yield Error(
876+
object_path, "is not a subclass of tuple", stub, runtime,
877+
stub_desc=str(stub_target)
878+
)
879+
# could check Tuple contents here...
880+
return
881+
if isinstance(stub_target, mypy.types.AnyType):
882+
return
883+
yield Error(
884+
object_path, "is not a recognised type alias", stub, runtime, stub_desc=str(stub_target)
885+
)
863886

864887

865888
SPECIAL_DUNDERS = ("__init__", "__new__", "__call__", "__init_subclass__", "__class_getitem__")
@@ -887,10 +910,11 @@ def is_probably_a_function(runtime: Any) -> bool:
887910
def safe_inspect_signature(runtime: Any) -> Optional[inspect.Signature]:
888911
try:
889912
return inspect.signature(runtime)
890-
except (ValueError, RuntimeError, TypeError):
891-
# inspect.signature throws sometimes
913+
except Exception:
914+
# inspect.signature throws ValueError all the time
892915
# catch RuntimeError because of https://bugs.python.org/issue39504
893916
# catch TypeError because of https://github.com/python/typeshed/pull/5762
917+
# catch AttributeError because of inspect.signature(_curses.window.border)
894918
return None
895919

896920

mypy/test/teststubtest.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,30 @@ def __init__(self):
571571
error=None,
572572
)
573573

574+
@collect_cases
575+
def test_type_alias(self) -> Iterator[Case]:
576+
yield Case(
577+
stub="""
578+
class X:
579+
def f(self) -> None: ...
580+
Y = X
581+
""",
582+
runtime="""
583+
class X:
584+
def f(self) -> None: ...
585+
class Y: ...
586+
""",
587+
error="Y.f",
588+
)
589+
yield Case(
590+
stub="""
591+
from typing import Tuple
592+
A = Tuple[int, str]
593+
""",
594+
runtime="A = (int, str)",
595+
error="A",
596+
)
597+
574598
@collect_cases
575599
def test_enum(self) -> Iterator[Case]:
576600
yield Case(

0 commit comments

Comments
 (0)