mypy
mypy copied to clipboard
Crash for TypedDict with non-literal keys
Crash Report
Creating a TypedDict with non-literal keys gives TypedDict() expects a dictionary literal as the second argument. Attempting to ignore this with # type: ignore causes an AssertionError if (and only if):
- any error (unrelated to TypedDict) happens later in a different module that imports the one with the
TypedDictdefinition - and
.mypy_cacheexists
Traceback
✗ mypy --show-traceback main.py
main.py:3: error: Unsupported operand types for + ("int" and "str") [operator]
Found 1 error in 1 file (checked 1 source file)
✗ mypy --show-traceback main.py
Traceback (most recent call last):
(...)
File "mypy/main.py", line 95, in main
File "mypy/main.py", line 174, in run_build
File "mypy/build.py", line 197, in build
File "mypy/build.py", line 270, in _build
File "mypy/build.py", line 2927, in dispatch
File "mypy/build.py", line 3318, in process_graph
File "mypy/build.py", line 3399, in process_fresh_modules
File "mypy/build.py", line 2114, in fix_cross_refs
File "mypy/fixup.py", line 53, in fixup_module
File "mypy/fixup.py", line 126, in visit_symbol_table
AssertionError: ('counts.Counts', 'counts.TypedDict')
To Reproduce
# counts.py
from typing import TypedDict
Counts = TypedDict("Counts", {k: int for k in "abc"}) # type: ignore
# main.py
from counts import Counts
print(1 + "a")
Your Environment
- Mypy version used: 1.4.1
- Python version used: 3.10
I can reproduce this, but importantly, this doesn't crash the first time you run mypy -- only the second time you run mypy. (This indicates that it's probably something to do with mypy's cache.)
Just noticed that in my original code I get different traceback from the MCVE above:
File "mypy/main.py", line 95, in main
File "mypy/main.py", line 174, in run_build
File "mypy/build.py", line 197, in build
File "mypy/build.py", line 270, in _build
File "mypy/build.py", line 2927, in dispatch
File "mypy/build.py", line 3318, in process_graph
File "mypy/build.py", line 3399, in process_fresh_modules
File "mypy/build.py", line 2114, in fix_cross_refs
File "mypy/fixup.py", line 53, in fixup_module
File "mypy/fixup.py", line 136, in visit_symbol_table
File "mypy/fixup.py", line 86, in visit_type_info
File "mypy/types.py", line 2382, in accept
File "mypy/fixup.py", line 287, in visit_typeddict_type
File "mypy/types.py", line 391, in accept
File "mypy/fixup.py", line 231, in visit_type_alias_type
File "mypy/fixup.py", line 386, in lookup_fully_qualified_alias
AssertionError: Should never get here in normal mode, got NoneType: instead of TypeAlias
I can reproduce this, but importantly, this doesn't crash the first time you run mypy -- only the second time you run mypy. (This indicates that it's probably something to do with mypy's cache.)
Here's the traceback I get using mypy master on Python 3.11 with the original repro:
>mypy main.py --show-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\coding\mypy\venv\Scripts\mypy.exe\__main__.py", line 7, in <module>
File "C:\Users\alexw\coding\mypy\mypy\__main__.py", line 15, in console_entry
main()
File "C:\Users\alexw\coding\mypy\mypy\main.py", line 95, in main
res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\coding\mypy\mypy\main.py", line 174, in run_build
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\coding\mypy\mypy\build.py", line 194, in build
result = _build(
^^^^^^^
File "C:\Users\alexw\coding\mypy\mypy\build.py", line 267, in _build
graph = dispatch(sources, manager, stdout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\coding\mypy\mypy\build.py", line 2926, in dispatch
process_graph(graph, manager)
File "C:\Users\alexw\coding\mypy\mypy\build.py", line 3317, in process_graph
process_fresh_modules(graph, prev_scc, manager)
File "C:\Users\alexw\coding\mypy\mypy\build.py", line 3398, in process_fresh_modules
graph[id].fix_cross_refs()
File "C:\Users\alexw\coding\mypy\mypy\build.py", line 2113, in fix_cross_refs
fixup_module(self.tree, self.manager.modules, self.options.use_fine_grained_cache)
File "C:\Users\alexw\coding\mypy\mypy\fixup.py", line 53, in fixup_module
node_fixer.visit_symbol_table(tree.names, tree.fullname)
File "C:\Users\alexw\coding\mypy\mypy\fixup.py", line 126, in visit_symbol_table
assert stnode.node is not None, (table_fullname + "." + key, cross_ref)
^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: ('counts.Counts', 'counts.TypedDict')