Skip to content

mypy INTERNAL ERROR in subtyping #20326

@GalHorowitz

Description

@GalHorowitz

Crash Report

Mypy crashes with an internal error on some generic type aliases when used in some specific import state.

Traceback

repro\aliases.py: error: INTERNAL ERROR -- Please try using mypy master on GitHub:
https://mypy.readthedocs.io/en/stable/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 1.20.0+dev.ece4d41e2c1b8e67fd099291c54562020d24ae7e.dirty
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "mypy\test_venv\Scripts\mypy.exe\__main__.py", line 7, in <module>
    sys.exit(console_entry())
  File "mypy\mypy\__main__.py", line 15, in console_entry
    main()
  File "mypy\mypy\main.py", line 127, in main
    res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
  File "mypy\mypy\main.py", line 211, in run_build
    res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
  File "mypy\mypy\build.py", line 215, in build
    result = _build(
  File "mypy\mypy\build.py", line 294, in _build
    graph = dispatch(sources, manager, stdout)
  File "mypy\mypy\build.py", line 2945, in dispatch
    process_graph(graph, manager)
  File "mypy\mypy\build.py", line 3336, in process_graph
    done, still_working = manager.wait_for_done(graph)
  File "mypy\mypy\build.py", line 918, in wait_for_done
    process_stale_scc(graph, next_scc, self)
  File "mypy\mypy\build.py", line 3468, in process_stale_scc
    mypy.semanal_main.semantic_analysis_for_scc(graph, scc, manager.errors)
  File "mypy\mypy\semanal_main.py", line 103, in semantic_analysis_for_scc
    check_type_arguments(graph, scc, errors)
  File "mypy\mypy\semanal_main.py", line 447, in check_type_arguments
    with state.wrap_context():
  File "C:\Program Files\Python313\Lib\contextlib.py", line 162, in __exit__
    self.gen.throw(value)
  File "mypy\mypy\build.py", line 2075, in wrap_context
    yield
  File "mypy\mypy\semanal_main.py", line 449, in check_type_arguments
    state.tree.accept(analyzer)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "mypy\mypy\nodes.py", line 407, in accept
    return visitor.visit_mypy_file(self)
           ~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\semanal_typeargs.py", line 68, in visit_mypy_file
    super().visit_mypy_file(o)
    ~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "mypy\mypy\traverser.py", line 120, in visit_mypy_file
    d.accept(self)
    ~~~~~~~~^^^^^^
  File "mypy\mypy\nodes.py", line 1660, in accept
    return visitor.visit_assignment_stmt(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\mixedtraverser.py", line 84, in visit_assignment_stmt
    super().visit_assignment_stmt(o)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^
  File "mypy\mypy\traverser.py", line 170, in visit_assignment_stmt
    o.rvalue.accept(self)
    ~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\nodes.py", line 2353, in accept
    return visitor.visit_index_expr(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\traverser.py", line 336, in visit_index_expr
    o.analyzed.accept(self)
    ~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\nodes.py", line 3143, in accept
    return visitor.visit_type_alias_expr(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\mixedtraverser.py", line 56, in visit_type_alias_expr
    o.node.accept(self)
    ~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\nodes.py", line 4335, in accept
    return visitor.visit_type_alias(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\mixedtraverser.py", line 95, in visit_type_alias
    o.target.accept(self)
    ~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\types.py", line 421, in accept
    return visitor.visit_type_alias_type(self)
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\semanal_typeargs.py", line 92, in visit_type_alias_type
    is_error, is_invalid = self.validate_args(
                           ~~~~~~~~~~~~~~~~~~^
        t.alias.name, tuple(t.args), t.alias.alias_tvars, t
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "mypy\mypy\semanal_typeargs.py", line 207, in validate_args
    if not object_upper_bound and not is_subtype(arg, upper_bound):
                                      ~~~~~~~~~~^^^^^^^^^^^^^^^^^^
  File "mypy\mypy\subtypes.py", line 190, in is_subtype
    return _is_subtype(left, right, subtype_context, proper_subtype=False)
  File "mypy\mypy\subtypes.py", line 359, in _is_subtype
    return left.accept(SubtypeVisitor(orig_right, subtype_context, proper_subtype))
           ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "mypy\mypy\types.py", line 693, in accept
    return visitor.visit_type_var(self)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "mypy\mypy\subtypes.py", line 656, in visit_type_var
    return self._is_subtype(left.upper_bound, self.right)
           ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "mypy\mypy\subtypes.py", line 431, in _is_subtype
    return is_subtype(left, right, subtype_context=self.subtype_context)
  File "mypy\mypy\subtypes.py", line 190, in is_subtype
    return _is_subtype(left, right, subtype_context, proper_subtype=False)
  File "mypy\mypy\subtypes.py", line 359, in _is_subtype
    return left.accept(SubtypeVisitor(orig_right, subtype_context, proper_subtype))
           ~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "mypy\mypy\types.py", line 3634, in accept
    assert isinstance(visitor, SyntheticTypeVisitor), visitor
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: <mypy.subtypes.SubtypeVisitor object at 0x000001D16BD61A90>

To Reproduce

This problem arose in a relatively large codebase; I have attempt to minimize the reproducer as much as I can.

Create three files (aliases.py, defs.py, someclass.py) in a directory with an empty __init__.py.

The contents are as follows:

aliases.py

from typing import TypeAlias

from .defs import C, Alias1

Alias2: TypeAlias = Alias1[C]

defs.py

from typing import TypeAlias, TypeVar, TYPE_CHECKING

if TYPE_CHECKING:
    from .someclass import SomeClass

C = TypeVar("C", bound="SomeClass")

Alias1: TypeAlias = C

someclass.py

from . import aliases

class SomeClass:
    pass

Your Environment

  • Mypy version used: mypy 1.20.0+dev.ece4d41e2c1b8e67fd099291c54562020d24ae7e (compiled: no)
  • Mypy command-line flags: mypy --show-traceback
  • Python version used: Python 3.13.3 [MSC v.1943 64 bit (AMD64)] on win32
  • Operating system and version: Windows 11

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions