Skip to content

Mypy crash when unpacking typevar tuples (not TypeVarTuple) #17755

Closed

Description

@kdkavanagh

Crash Report

Unpacked *args tuple type with TypeVar crashes mypy. Offending source below, crash occurred after introducing *tuple[_S1] as the *args type. This overload is necessary instead of a TypeVarTuple due to the challenge described here

_S1 = TypeVar("_S1", bound=_ScopeType)

@overload
def create_scoped(
    arg1: Arg1,
    arg2: Union[type[TraitsLikeT], TraitsLikeT],
    *scopes: * tuple[_S1 | type[_S1] ],
) -> ScopeContainer[TraitsLikeT, _S1]: ...

Traceback

src/mylib/api/scope.py:238: 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.11.2
Traceback (most recent call last):
  File "mypy/checker.py", line 591, in accept
  File "mypy/nodes.py", line 589, in accept
  File "mypy/checker.py", line 628, in visit_overloaded_func_def
  File "mypy/checker.py", line 658, in _visit_overloaded_func_def
  File "mypy/checker.py", line 825, in check_overlapping_overloads
  File "mypy/subtypes.py", line 1855, in unify_generic_callable
  File "mypy/constraints.py", line 317, in infer_constraints
  File "mypy/constraints.py", line 410, in _infer_constraints
  File "mypy/types.py", line 2004, in accept
  File "mypy/constraints.py", line 1085, in visit_callable_type
  File "mypy/constraints.py", line 1440, in repack_callable_args
AssertionError:

Your Environment

  • Mypy version used: mypy 1.11.2 (compiled: yes)
  • Mypy command-line flags:
  • Mypy configuration options from mypy.ini (and other config files): Only set python_version = 3.11
  • Python version used: Python 3.11.9
  • Operating system and version: rhel8

Activity

  1. kdkavanagh commented on Sep 10, 2024

    @kdkavanagh
    Author

    Latest commit on master yields a slightly different backtrace:

    version: 1.12.0+dev.0c1036717578b00e35625cc353a538e4eb63bc37
      File ".venv/bin/mypy", line 8, in <module>
        sys.exit(console_entry())
      File ".venv/lib/python3.11/site-packages/mypy/__main__.py", line 15, in console_entry
        main()
      File ".venv/lib/python3.11/site-packages/mypy/main.py", line 102, in main
        res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
      File ".venv/lib/python3.11/site-packages/mypy/main.py", line 186, in run_build
        res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
      File ".venv/lib/python3.11/site-packages/mypy/build.py", line 193, in build
        result = _build(
      File ".venv/lib/python3.11/site-packages/mypy/build.py", line 268, in _build
        graph = dispatch(sources, manager, stdout)
      File ".venv/lib/python3.11/site-packages/mypy/build.py", line 2950, in dispatch
        process_graph(graph, manager)
      File ".venv/lib/python3.11/site-packages/mypy/build.py", line 3348, in process_graph
        process_stale_scc(graph, scc, manager)
      File ".venv/lib/python3.11/site-packages/mypy/build.py", line 3449, in process_stale_scc
        graph[id].type_check_first_pass()
      File ".venv/lib/python3.11/site-packages/mypy/build.py", line 2314, in type_check_first_pass
        self.type_checker().check_first_pass()
      File ".venv/lib/python3.11/site-packages/mypy/checker.py", line 483, in check_first_pass
        self.accept(d)
      File ".venv/lib/python3.11/site-packages/mypy/checker.py", line 592, in accept
        stmt.accept(self)
      File ".venv/lib/python3.11/site-packages/mypy/nodes.py", line 589, in accept
        return visitor.visit_overloaded_func_def(self)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File ".venv/lib/python3.11/site-packages/mypy/checker.py", line 629, in visit_overloaded_func_def
        self._visit_overloaded_func_def(defn)
      File ".venv/lib/python3.11/site-packages/mypy/checker.py", line 659, in _visit_overloaded_func_def
        self.check_overlapping_overloads(defn)
      File ".venv/lib/python3.11/site-packages/mypy/checker.py", line 828, in check_overlapping_overloads
        impl: CallableType | None = unify_generic_callable(
                                    ^^^^^^^^^^^^^^^^^^^^^^^
      File ".venv/lib/python3.11/site-packages/mypy/subtypes.py", line 1855, in unify_generic_callable
        cs = mypy.constraints.infer_constraints(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File ".venv/lib/python3.11/site-packages/mypy/constraints.py", line 317, in infer_constraints
        return _infer_constraints(template, actual, direction, skip_neg_op)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File ".venv/lib/python3.11/site-packages/mypy/constraints.py", line 410, in _infer_constraints
        return template.accept(ConstraintBuilderVisitor(actual, direction, skip_neg_op))
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File ".venv/lib/python3.11/site-packages/mypy/types.py", line 2004, in accept
        return visitor.visit_callable_type(self)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File ".venv/lib/python3.11/site-packages/mypy/constraints.py", line 1085, in visit_callable_type
        actual_types = repack_callable_args(cactual, tuple_type)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File ".venv/lib/python3.11/site-packages/mypy/constraints.py", line 1440, in repack_callable_args
        assert isinstance(tp.items[0], UnpackType)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    pdb shows:

    -> assert isinstance(tp.items[0], UnpackType)
    (Pdb) p tp.items[0]
    Union[_S1`-2, type[_S1`-2]]
    
  2. ilevkivskyi commented on Feb 10, 2025

    @ilevkivskyi
    Member

    Could you please post a more complete (ideally self-contained) example? I am having trouble reproducing this.

  3. sterliakov commented on Mar 30, 2025

    @sterliakov
    Collaborator

    Reproduces on the following (playground):

    from typing import TypeVar, overload
    
    _T = TypeVar("_T")
    
    @overload
    def fn() -> tuple[()]: ...
    @overload
    def fn(*scopes: *tuple[_T]) -> tuple[_T]: ...
    def fn(*scopes: *tuple[_T]) -> tuple[_T]: ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions