Skip to content

Stubtest crashes on a stub with an overloaded method where the first overload is decorated with @final #14950

@AlexWaygood

Description

@AlexWaygood

Crash Report

If you run stubtest on a stub with a method like this, stubtest will crash:

from typing import final, overload

class C:
    @overload
    @final
    def foo(self, obj: str) -> int: ...
    @overload
    def foo(self, obj: int) -> str: ...

The crash occurs regardless of the order in which you stack the @final and @overload decorator on the first overload. (PEP 591 specifies that for overloaded definitions in stubs, the @final decorator should be placed on the first overload, but doesn't specify which order they should be stacked in.)

Traceback

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 1823, in <module>
    sys.exit(main())
             ^^^^^^
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 1819, in main
    return test_stubs(parse_options(sys.argv[1:]))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 1692, in test_stubs
    for error in test_module(module):
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 218, in test_module
    yield from verify(stub, runtime, [module_name])
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 396, in verify_mypyfile
    yield from verify(stub_entry, runtime_entry, object_path + [entry])
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 517, in verify_typeinfo
    yield from verify(stub_to_verify, runtime_attr, object_path + [entry])
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 1050, in verify_overloadedfuncdef
    stub_sig = Signature.from_overloadedfuncdef(stub)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\alexw\AppData\Local\Temp\tmp_p_nrkoa\Lib\site-packages\mypy\stubtest.py", line 756, in from_overloadedfuncdef
    assert func is not None
           ^^^^^^^^^^^^^^^^
AssertionError

To Reproduce

Two ways to reproduce:

(1) Apply this diff, and then run pytest mypy/test/teststubtest.py:

diff --git a/mypy/test/teststubtest.py b/mypy/test/teststubtest.py
index d39812b5f..b7f114b5e 100644
--- a/mypy/test/teststubtest.py
+++ b/mypy/test/teststubtest.py
@@ -1177,6 +1177,24 @@ class StubtestUnit(unittest.TestCase):
             """,
             error="C",
         )
+        yield Case(
+            stub="""
+            from typing import overload
+            from typing_extensions import final
+            class D:
+                @overload
+                @final
+                def foo(self, obj: int) -> str: ...
+                @overload
+                def foo(self, obj: str) -> int: ...
+            """,
+            runtime="""
+            class D:
+                def foo(self, obj):
+                    return 42 if isinstance(obj, str) else "foo"
+            """,
+            error=None
+        )

(2) With a typeshed clone checked out, apply this diff, then run python tests/stubtest_stdlib.py:

diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi
index 2c21cd95d..8cdcd3b6a 100644
--- a/stdlib/builtins.pyi
+++ b/stdlib/builtins.pyi
@@ -189,6 +189,7 @@ class type:

 class super:
     @overload
+    @final
     def __init__(self, __t: Any, __obj: Any) -> None: ...
     @overload
     def __init__(self, __t: Any) -> None: ...

Your Environment

Reproduced with mypy 1.1.1 and mypy @ bfa9eac

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions