2.2 Regression with placeholder types in a TypeVar
crashtopic-plugins
**Crash Report**
I was testing the [mypy 2.2 branch](https://github.com/python/mypy/issues/21618#issuecomment-4784328932) and I came across some errors around placeholder types.
**Traceback**
There's kinda two errors and I think they're related
<details>
<summary>AssertionError: Must not defer during final iteration</summary>
```
Please report a bug at https://github.com/python/mypy/issues
version: 2.2.0+dev.5ef090270579013c337a9bcc79e2c58417f09538
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/semanal.py", line 7732, in accept
File "mypy/nodes.py", line 1165, in accept
File "mypy/semanal.py", line 991, in visit_func_def
File "mypy/semanal.py", line 1036, in analyze_func_def
File "mypy/semanal.py", line 7333, in defer
AssertionError: Must not defer during final iteration
```
</details>
If I use the source directly so I get more of a traceback
<details>
<summary>More details</summary>
```
version: 2.2.0+dev.5ef090270579013c337a9bcc79e2c58417f09538
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/Users/stephen.moore/Projects/external/mypy/mypy/__main__.py", line 52, in <module>
console_entry()
File "/Users/stephen.moore/Projects/external/mypy/mypy/__main__.py", line 16, in console_entry
main()
File "/Users/stephen.moore/Projects/external/mypy/mypy/main.py", line 154, in main
res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
File "/Users/stephen.moore/Projects/external/mypy/mypy/main.py", line 244, in run_build
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
File "/Users/stephen.moore/Projects/external/mypy/mypy/build.py", line 422, in build
result = build_inner(
File "/Users/stephen.moore/Projects/external/mypy/mypy/build.py", line 537, in build_inner
graph = dispatch(sources, manager, stdout, connect_threads)
File "/Users/stephen.moore/Projects/external/mypy/mypy/build.py", line 4146, in dispatch
process_graph(graph, manager)
File "/Users/stephen.moore/Projects/external/mypy/mypy/build.py", line 4614, in process_graph
done, still_working, results = manager.wait_for_done(graph)
File "/Users/stephen.moore/Projects/external/mypy/mypy/build.py", line 1484, in wait_for_done
process_stale_scc(graph, next_scc, self)
File "/Users/stephen.moore/Projects/external/mypy/mypy/build.py", line 4782, in process_stale_scc
mypy.semanal_main.semantic_analysis_for_scc(graph, scc, manager.errors)
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal_main.py", line 92, in semantic_analysis_for_scc
process_functions(graph, scc, patches)
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal_main.py", line 275, in process_functions
process_top_level_function(
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal_main.py", line 314, in process_top_level_function
deferred, incomplete, progress = semantic_analyze_target(
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal_main.py", line 380, in semantic_analyze_target
analyzer.refresh_partial(
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal.py", line 709, in refresh_partial
self.accept(node)
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal.py", line 7732, in accept
node.accept(self)
~~~~~~~~~~~^^^^^^
File "/Users/stephen.moore/Projects/external/mypy/mypy/nodes.py", line 1165, in accept
return visitor.visit_func_def(self)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal.py", line 991, in visit_func_def
self.analyze_func_def(defn)
~~~~~~~~~~~~~~~~~~~~~^^^^^^
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal.py", line 1036, in analyze_func_def
self.defer(defn)
~~~~~~~~~~^^^^^^
File "/Users/stephen.moore/Projects/external/mypy/mypy/semanal.py", line 7333, in defer
assert not self.final_iteration, "Must not defer during final iteration"
^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Must not defer during final iteration
```
</details>
And if I start trying to fill in default values I start to get this happening:
<details>
<summary>NotImplementedError: Cannot serialize PlaceholderType instance</summary>
```
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/__main__.py", line 52, in <module>
console_entry()
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/__main__.py", line 16, in console_entry
main()
~~~~^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/main.py", line 154, in main
res, messages, blockers = run_build(sources, options, fscache, t0, stdout, stderr)
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/main.py", line 244, in run_build
res = build.build(sources, options, None, flush_errors, fscache, stdout, stderr)
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 422, in build
result = build_inner(
sources,
...<9 lines>...
metastore,
)
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 537, in build_inner
graph = dispatch(sources, manager, stdout, connect_threads)
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 4146, in dispatch
process_graph(graph, manager)
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 4614, in process_graph
done, still_working, results = manager.wait_for_done(graph)
~~~~~~~~~~~~~~~~~~~~~^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 1484, in wait_for_done
process_stale_scc(graph, next_scc, self)
~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 4821, in process_stale_scc
meta_tuple = graph[id].write_cache()
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 3604, in write_cache
new_interface_hash, meta_tuple = write_cache(
~~~~~~~~~~~^
self.id,
^^^^^^^^
...<13 lines>...
self.manager,
^^^^^^^^^^^^^
)
^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/build.py", line 2325, in write_cache
tree.write(data_io)
~~~~~~~~~~^^^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/nodes.py", line 599, in write
self.names.write(data, self._fullname)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/nodes.py", line 5169, in write
value.write(data, fullname, key)
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/nodes.py", line 5074, in write
self.node.write(data)
~~~~~~~~~~~~~~~^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/nodes.py", line 4721, in write
self.target.write(data)
~~~~~~~~~~~~~~~~~^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/types.py", line 1756, in write
write_type_list(data, self.args)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/types.py", line 4553, in write_type_list
item.write(data)
~~~~~~~~~~^^^^^^
File "/Users/stephen.moore/.virtualenvs/project/lib/python3.13/site-packages/mypy/types.py", line 318, in write
raise NotImplementedError(f"Cannot serialize {self.__class__.__name__} instance")
NotImplementedError: Cannot serialize PlaceholderType instance
```
</details>
**To Reproduce**
It appears that ultimately this is an interaction with how my [mypy plugin](https://github.com/delfick/extended-mypy-django-plugin) works, which complicates it a little.
Essentially I add dependencies with the `get_additional_deps` hook that contain aliases (I call these virtual dependencies), and then with a `get_type_analyze_hook` hook I look for a special class that I replace with the target of an appropriate alias from those "virtual dependencies".
I have created an example with a readme that replicates the problem. Seems I can't upload a git bundle to a github issue, so
here is a repo: https://github.com/delfick/mypy-release-2.2-bug-demonstration
It seems there is one change required to fix it
```patch
From 84140edcb76aaf4b6bf3a2fd1f6a5ffc80277810 Mon Sep 17 00:00:00 2001
From: Stephen Moore <stephen.moore@kraken.tech>
Date: Wed, 24 Jun 2026 10:13:32 +1000
Subject: [PATCH] WIP: this makes a difference
---
mypy/semanal.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mypy/semanal.py b/mypy/semanal.py
index e010273b0..324910809 100644
--- a/mypy/semanal.py
+++ b/mypy/semanal.py
@@ -2009,7 +2009,7 @@ class SemanticAnalyzer(
# re-analyze this class. Note we force progress to handle cases like
# class C[T = C], this matches logic in process_typevar_parameters()
# for "old style" type variables.
- self.defer(force_progress=tvar_defs != defn.type_vars)
+ self.mark_incomplete(defn.name, defn)
self.analyze_class_keywords(defn)
bases_result = self.analyze_base_classes(defn.name, bases)
--
2.50.1 (Apple Git-155)
```
(undoing a change in https://github.com/python/mypy/pull/21491)
However when I do this mypy unit tests start to fail. I can't figure out how to fix that, or even how to replicate the errors in a mypy unit test.
**Your Environment**
<!-- Include as many relevant details about the environment you experienced the bug in -->
- Mypy version used: release-2.2 branch (5ef090270579013c337a9bcc79e2c58417f09538)
- Python version used: 3.13.2
- Operating system and version: MacOS Tahoe 26.5.1
AI Disclosure: None: I actively avoid LLMs
关闭于 2026-07-14 7 条评论