Skip to content

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

Closed

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

Activity

  1. added a commit that references this issue on Nov 11, 2023
    92cce1f
  2. added a commit that references this issue on Nov 11, 2023
    8ae84ed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions