Assertion fails in is_overlapping_types() when comparing Unpack TypeVarTuple with default type #18105
Open
Description
Crash Report
mypy reports INTERNAL ERROR (failed assertion) when checking code that calls type(f) is Foo
where Foo is a tuple type with Unpacked TypeVarTuple using a default type.
It seems to be related to using the default type of a TypeVarTuple. When the TypeVarTuple's default is not relied on, the internal error does not occur.
Traceback
$ mypy test/test_mypy_is_overlapping_types.py --show-traceback --pdb --strict
test/test_mypy_is_overlapping_types.py:19: 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.14.0+dev.7788c21269006ac2e3ac3bc69e52d68403741e6e
Dropping into pdb
> /home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py(584)is_overlapping_types()
-> assert type(left) != type(right), f"{type(left)} vs {type(right)}"
(Pdb) left
Unpack[builtins.tuple[Union[builtins.str, builtins.int], ...]]
(Pdb) right
Unpack[Pieces`1 = Unpack[builtins.tuple[Union[builtins.str, builtins.int], ...]]]
(Pdb) exit
Traceback (most recent call last):
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/bin/mypy", line 8, in <module>
sys.exit(console_entry())
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/__main__.py", line 15, in console_entry
main()
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/main.py", line 109, in main
res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/main.py", line 193, in run_build
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/build.py", line 194, in build
result = _build(
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/build.py", line 269, in _build
graph = dispatch(sources, manager, stdout)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/build.py", line 2940, in dispatch
process_graph(graph, manager)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/build.py", line 3338, in process_graph
process_stale_scc(graph, scc, manager)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/build.py", line 3439, in process_stale_scc
graph[id].type_check_first_pass()
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/build.py", line 2309, in type_check_first_pass
self.type_checker().check_first_pass()
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 483, in check_first_pass
self.accept(d)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 592, in accept
stmt.accept(self)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/nodes.py", line 827, in accept
return visitor.visit_func_def(self)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 1046, in visit_func_def
self._visit_func_def(defn)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 1050, in _visit_func_def
self.check_func_item(defn, name=defn.name)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 1084, in check_func_item
self.check_func_def(defn, typ, name, allow_empty)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 1360, in check_func_def
self.accept(item.body)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 592, in accept
stmt.accept(self)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/nodes.py", line 1277, in accept
return visitor.visit_block(self)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 2951, in visit_block
self.accept(s)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 592, in accept
stmt.accept(self)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/nodes.py", line 1490, in accept
return visitor.visit_assert_stmt(self)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checker.py", line 4778, in visit_assert_stmt
self.expr_checker.accept(s.expr)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checkexpr.py", line 5885, in accept
typ = node.accept(self)
^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/nodes.py", line 2156, in accept
return visitor.visit_comparison_expr(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checkexpr.py", line 3645, in visit_comparison_expr
if self.dangerous_comparison(left_type, right_type):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/checkexpr.py", line 3790, in dangerous_comparison
return not is_overlapping_types(left, right, ignore_promotions=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py", line 481, in is_overlapping_types
return _type_object_overlap(left, right) or _type_object_overlap(right, left)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py", line 466, in _type_object_overlap
return _is_overlapping_types(left.item, right.ret_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py", line 306, in _is_overlapping_types
return is_overlapping_types(
^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py", line 570, in is_overlapping_types
if all(
^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py", line 571, in <genexpr>
_is_overlapping_types(left_arg, right_arg)
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py", line 306, in _is_overlapping_types
return is_overlapping_types(
^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.cache/pypoetry/virtualenvs/denokv-G2ZV__I8-py3.12/lib/python3.12/site-packages/mypy/meet.py", line 584, in is_overlapping_types
assert type(left) != type(right), f"{type(left)} vs {type(right)}"
^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: <class 'mypy.types.UnpackType'> vs <class 'mypy.types.UnpackType'>
test/test_mypy_is_overlapping_types.py:19: : note: use --pdb to drop into pdb
To Reproduce
Run mypy on this code to reproduce (this is what I ran on in the traceback above).
- Changing the
Pieces
default value totuple[object ...]
stops the error occurring also
from __future__ import annotations
from typing_extensions import TypeVarTuple
from typing_extensions import Unpack
Pieces = TypeVarTuple("Pieces", default=Unpack[tuple[str | int, ...]])
class Foo(tuple[Unpack[Pieces]]):
pass
def test_mypy_is_overlapping_types_assertion_failure() -> None:
pieces: tuple[str, int] = ("a", 1)
f1: Foo[tuple[str, int]] = Foo(pieces)
assert type(f1) is Foo # ok
f2 = Foo(pieces)
assert type(f2) is Foo # mypy internal error
Your Environment
- Mypy version used: 1.14.0+dev.7788c21269006ac2e3ac3bc69e52d68403741e6e
- Mypy command-line flags:
--strict
- Mypy configuration options from
mypy.ini
(and other config files): None as far as I know, I removed my own config file before running the example above. - Python version used: Python 3.12.7
- Operating system and version: Debian 12, aarch64 (Linux container)