Skip to content

Commit 396f508

Browse files
committed
[Chore] Update changelog for 2.2 (#21691)
1 parent 9592a9e commit 396f508

1 file changed

Lines changed: 277 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,283 @@
22

33
## Next Release
44

5+
## Mypy 2.2
6+
7+
We've just uploaded mypy 2.2.0 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)).
8+
Mypy is a static type checker for Python. This release includes new features, performance
9+
improvements and bug fixes. You can install it as follows:
10+
11+
python3 -m pip install -U mypy
12+
13+
You can read the full documentation for this release on [Read the Docs](http://mypy.readthedocs.io).
14+
15+
### Support for Closed TypedDicts (PEP 728)
16+
17+
Mypy now supports closed TypedDicts as specified in PEP 728. A closed TypedDict cannot have extra
18+
keys beyond those explicitly defined. This allows the type checker to determine that certain
19+
operations are safe when they otherwise wouldn't be due to the potential presence of unknown keys.
20+
21+
You can use the `closed` keyword argument with `TypedDict`:
22+
23+
```python
24+
HasName = TypedDict("HasName", {"name": str})
25+
HasOnlyName = TypedDict("HasOnlyName", {"name": str}, closed=True)
26+
Movie = TypedDict("Movie", {"name": str, "year": int})
27+
28+
movie: Movie = {"name": "Nimona", "year": 2023}
29+
has_name: HasName = movie # OK: HasName is open (default)
30+
has_only_name: HasOnlyName = movie # Error: HasOnlyName is closed and Movie has extra "year" key
31+
```
32+
33+
Closed TypedDicts enable more precise type checking because the type checker knows exactly which
34+
keys are present. This is particularly useful when working with TypedDict unions or when you want
35+
to ensure that a TypedDict conforms to an exact shape.
36+
37+
The `closed` keyword also enables safe type narrowing with `in` checks:
38+
39+
```python
40+
Book = TypedDict('Book', {'book': str}, closed=True)
41+
DVD = TypedDict('DVD', {'dvd': str}, closed=True)
42+
type Inventory = Book | DVD
43+
44+
def print_type(inventory: Inventory) -> None:
45+
if "book" in inventory:
46+
# Type is narrowed to Book here - safe because DVD is closed
47+
print(inventory["book"])
48+
else:
49+
# Type is narrowed to DVD here
50+
print(inventory["dvd"])
51+
```
52+
53+
The `closed` keyword is also supported in class-based syntax:
54+
55+
```python
56+
class HasOnlyName(TypedDict, closed=True):
57+
name: str
58+
```
59+
60+
Note that closed TypedDicts are structural types, so a closed TypedDict is assignable to an open
61+
TypedDict with the same keys, but not vice versa.
62+
63+
Contributed by Alice (PR [21382](https://github.com/python/mypy/pull/21382)).
64+
65+
### Complete Support for Type Variable Defaults (PEP 696)
66+
67+
Mypy now has complete support for type variable defaults as specified in PEP 696. This allows you to
68+
specify default values for type parameters in generic classes, functions, and type aliases.
69+
70+
Traditional syntax (Python 3.11 and earlier):
71+
72+
```python
73+
T = TypeVar("T", default=int) # This means that if no type is specified T = int
74+
75+
@dataclass
76+
class Box(Generic[T]):
77+
value: T | None = None
78+
79+
reveal_type(Box()) # type is Box[int]
80+
reveal_type(Box(value="Hello World!")) # type is Box[str]
81+
```
82+
83+
New syntax (Python 3.12+):
84+
85+
```python
86+
class Box[T = int]:
87+
def __init__(self, value: T) -> None:
88+
self.value = value
89+
90+
reveal_type(Box()) # type is Box[int]
91+
reveal_type(Box(value="Hello World!")) # type is Box[str]
92+
```
93+
94+
Type variable defaults work with all forms of generics, including classes, functions, and type aliases.
95+
This release completes the implementation by fixing various edge cases involving recursive defaults,
96+
dependencies between type variables, and interactions with variadic generics.
97+
98+
Contributed by Ivan Levkivskyi (PRs [21491](https://github.com/python/mypy/pull/21491),
99+
[21526](https://github.com/python/mypy/pull/21526), [21544](https://github.com/python/mypy/pull/21544)).
100+
101+
### Respect Explicit Return Type of `__new__()`
102+
103+
Mypy now respects explicitly annotated return types in `__new__()` methods. Previously, mypy would
104+
always assume that `__new__()` returns an instance of the current class, ignoring explicit annotations.
105+
106+
With this change, if you explicitly annotate a return type that differs from the implicit type, mypy
107+
will use the explicit annotation:
108+
109+
```python
110+
class Factory:
111+
def __new__(cls) -> Product:
112+
return Product()
113+
114+
reveal_type(Factory()) # type is Product, not Factory
115+
```
116+
117+
Note that mypy still gives an error at the definition site if the explicit annotation is not a
118+
subtype of the current class, since this is technically not type-safe.
119+
120+
For backwards compatibility, there are two exceptions:
121+
- If the return type is `Any`, mypy will still use the current class as the return type.
122+
- If the explicit return type comes from a superclass and is a supertype of the implicit return type,
123+
mypy will use the implicit (more specific) type:
124+
125+
```python
126+
class A:
127+
def __new__(cls) -> A: ...
128+
129+
reveal_type(A()) # type is A
130+
131+
class B:
132+
def __new__(cls) -> B:
133+
return cls()
134+
135+
class C(B): ...
136+
reveal_type(C()) # type is C
137+
```
138+
139+
This fixes several long-standing issues where explicit `__new__()` return types were ignored.
140+
141+
Contributed by Ivan Levkivskyi (PR [21441](https://github.com/python/mypy/pull/21441)).
142+
143+
### TypeForm Support No Longer Experimental
144+
145+
Support for `TypeForm` is no longer experimental. `TypeForm` (introduced in Python 3.14) allows you
146+
to annotate parameters that accept type expressions, providing better type checking for functions
147+
that work with types as values.
148+
149+
```python
150+
from typing import TypeForm
151+
152+
def make_list(tp: TypeForm[T]) -> list[T]:
153+
...
154+
155+
# Correctly typed as list[int]
156+
int_list = make_list(int)
157+
```
158+
159+
`TypeForm` support was previously reverted from mypy 2.1 due to a performance regression, but this
160+
has now been mitigated.
161+
162+
Contributed by Ivan Levkivskyi and Jelle Zijlstra (PRs [21262](https://github.com/python/mypy/pull/21262), [21591](https://github.com/python/mypy/pull/21591),
163+
[21459](https://github.com/python/mypy/pull/21459)).
164+
165+
### Experimental WASM Wheel for Python 3.14
166+
167+
Mypy now ships an experimental WebAssembly (WASM) wheel for Python 3.14. This allows mypy to run
168+
in WASM environments such as Pyodide and browser-based Python implementations.
169+
170+
The WASM wheel is considered experimental and may have limitations compared to native builds. Please
171+
report any issues you encounter when using mypy in WASM environments.
172+
173+
Contributed by Ivan Levkivskyi (PR [21671](https://github.com/python/mypy/pull/21671)).
174+
175+
### Mypyc Free-threading Improvements
176+
177+
- Make function wrappers thread-safe on free-threaded builds (Jukka Lehtosalo, PR [21620](https://github.com/python/mypy/pull/21620))
178+
- Make list remove and index thread-safe on free-threaded builds (Jukka Lehtosalo, PR [21614](https://github.com/python/mypy/pull/21614))
179+
- Fix dict iteration memory safety on free-threaded builds (Jukka Lehtosalo, PR [21617](https://github.com/python/mypy/pull/21617))
180+
- Make some dict primitives thread-safe on free-threading builds (Jukka Lehtosalo, PR [21616](https://github.com/python/mypy/pull/21616))
181+
- Fix free-threading race condition in argument parsing (Jukka Lehtosalo, PR [21613](https://github.com/python/mypy/pull/21613))
182+
- Document free threading and other doc updates (Jukka Lehtosalo, PR [21494](https://github.com/python/mypy/pull/21494))
183+
184+
### `librt.strings` Updates
185+
186+
- Add `librt.strings.toupper` and `librt.strings.tolower` codepoint primitives (Vaggelis Danias, PR [21553](https://github.com/python/mypy/pull/21553))
187+
- Add `librt.strings.isidentifier` codepoint primitive (Vaggelis Danias, PR [21522](https://github.com/python/mypy/pull/21522))
188+
- Add `librt.strings.isalpha` codepoint primitive (Vaggelis Danias, PR [21521](https://github.com/python/mypy/pull/21521))
189+
- Add `librt.strings.isalnum` codepoint primitive (Vaggelis Danias, PR [21509](https://github.com/python/mypy/pull/21509))
190+
- Add `librt.strings.isdigit` codepoint primitive (Vaggelis Danias, PR [21504](https://github.com/python/mypy/pull/21504))
191+
- Add `librt.strings.isspace` char primitive (Vaggelis Danias, PR [21462](https://github.com/python/mypy/pull/21462))
192+
193+
### Mypyc Improvements
194+
195+
- Fix name lookup when class var and module var have the same name (Jukka Lehtosalo, PR [21594](https://github.com/python/mypy/pull/21594))
196+
- Report file and line number on uncaught exceptions (Jukka Lehtosalo, PR [21584](https://github.com/python/mypy/pull/21584))
197+
- Use `other` arg instead of `self` for RHS type (Ryan Heard, PR [21569](https://github.com/python/mypy/pull/21569))
198+
- Use `method_sig` to get the method signature (Ryan Heard, PR [21567](https://github.com/python/mypy/pull/21567))
199+
- Preserve inherited attribute defaults under `separate=True` (Jo, PR [21547](https://github.com/python/mypy/pull/21547))
200+
- Fix missing cross-group header deps in incremental builds (Jo, PR [21490](https://github.com/python/mypy/pull/21490))
201+
- Fix cross-group call to inherited `__mypyc_defaults_setup` (Jo, PR [21481](https://github.com/python/mypy/pull/21481))
202+
- Fix non-deterministic class struct layout under `separate=True` (Vaggelis Danias, PR [21530](https://github.com/python/mypy/pull/21530))
203+
- Specialize `s[i] == 'x'` to a codepoint int compare (Vaggelis Danias, PR [21579](https://github.com/python/mypy/pull/21579))
204+
- Fix reference leak in mypyc bytes concatenation (Colinxu2020, PR [21469](https://github.com/python/mypy/pull/21469))
205+
206+
### Fixes to Crashes
207+
208+
- Fix crash on invalid recursive variadic alias (Ivan Levkivskyi, PR [21572](https://github.com/python/mypy/pull/21572))
209+
- Fix crashes on variadic unpacking in synthetic types (Ivan Levkivskyi, PR [21555](https://github.com/python/mypy/pull/21555))
210+
- Fix crash on unhandled meet variadic tuple vs instance (Ivan Levkivskyi, PR [21558](https://github.com/python/mypy/pull/21558))
211+
- Fix crash on deferred generic class nested in function (Ivan Levkivskyi, PR [21557](https://github.com/python/mypy/pull/21557))
212+
- Fix crash in new-style type alias with variadic unpack (Ivan Levkivskyi, PR [21551](https://github.com/python/mypy/pull/21551))
213+
- Fix various crashes on recursive type variable defaults (Ivan Levkivskyi, PR [21491](https://github.com/python/mypy/pull/21491))
214+
- Fix crash for empty `Annotated` type application (Rayan Salhab, PR [21503](https://github.com/python/mypy/pull/21503))
215+
- Fix crash on `Unpack` used without arguments in class bases (Sai Asish Y, PR [21470](https://github.com/python/mypy/pull/21470))
216+
217+
### Performance Improvements
218+
219+
- Memoize the options snapshot (Kevin Kannammalil, PR [21354](https://github.com/python/mypy/pull/21354))
220+
- Don't include `not_ready_deps` tracking as relating to mypy internals (Kevin Kannammalil, PR [21389](https://github.com/python/mypy/pull/21389))
221+
- Speed up transitive dependency hash for singleton SCCs (Kevin Kannammalil, PR [21390](https://github.com/python/mypy/pull/21390))
222+
- Optimize typeform checks (Jelle Zijlstra, PR [21459](https://github.com/python/mypy/pull/21459))
223+
224+
### Improvements to the Native Parser
225+
226+
- Support `--shadow-file` with `--native-parser` (Jukka Lehtosalo, PR [21623](https://github.com/python/mypy/pull/21623))
227+
- Add Python version checks to native parser (Kevin Kannammalil, PR [21539](https://github.com/python/mypy/pull/21539))
228+
- Allow nativeparse to parse source code directly (bzoracler, PR [21260](https://github.com/python/mypy/pull/21260))
229+
230+
### Other Notable Fixes and Improvements
231+
232+
- Add function definition notes for `too many positional arguments` errors (Kevin Kannammalil, PR [21410](https://github.com/python/mypy/pull/21410))
233+
- Fix the exportjson tool (.ff cache to .json conversion) (Jukka Lehtosalo, PR [21628](https://github.com/python/mypy/pull/21628))
234+
- Support floats in JSON in fixed-format cache (Ivan Levkivskyi, PR [21603](https://github.com/python/mypy/pull/21603))
235+
- Update `TypedDictType.__init__` signature to preserve backward compat (Jukka Lehtosalo, PR [21590](https://github.com/python/mypy/pull/21590))
236+
- Fix constructor calls for union-bounded `TypeVar`s (Jingchen Ye, PR [21571](https://github.com/python/mypy/pull/21571))
237+
- Fix `TypedDict` indexing with literal keys in comprehensions (Jingchen Ye, PR [21556](https://github.com/python/mypy/pull/21556))
238+
- Correctly handle empty tuple index when unpacked (Ivan Levkivskyi, PR [21545](https://github.com/python/mypy/pull/21545))
239+
- Support protocol checks for self-types in tuple types (Ivan Levkivskyi, PR [21535](https://github.com/python/mypy/pull/21535))
240+
- Fix edge cases in variadic tuple subclasses (Ivan Levkivskyi, PR [21518](https://github.com/python/mypy/pull/21518))
241+
- Special-case constructor for tuple types (Ivan Levkivskyi, PR [21502](https://github.com/python/mypy/pull/21502))
242+
- Fix false positive "Expected TypedDict key to be string literal" for `Union[TypedDict, dict[K, V]]` (Zakir Jiwani, PR [21511](https://github.com/python/mypy/pull/21511))
243+
- Use explicit `Never` for type inference (Ivan Levkivskyi, PR [21497](https://github.com/python/mypy/pull/21497))
244+
- Narrow membership in statically known containers (Shantanu, PR [21461](https://github.com/python/mypy/pull/21461))
245+
- Improve negative narrowing for membership checks on tuples (Shantanu, PR [21456](https://github.com/python/mypy/pull/21456))
246+
- Analyze `TypedDict` decorators (Pranav Manglik, PR [21267](https://github.com/python/mypy/pull/21267))
247+
- Start testing Python 3.15 (Marc Mueller, PR [21439](https://github.com/python/mypy/pull/21439))
248+
- Improved handling of `NamedTuple`, `TypedDict`, `Enum`, and regular classes nested in functions (Ivan Levkivskyi, PR [21478](https://github.com/python/mypy/pull/21478))
249+
250+
### Typeshed Updates
251+
252+
Please see [git log](https://github.com/python/typeshed/commits/main?after=616424285beccaa76f90e87e1e922b1dc68710ca+0&branch=main&path=stdlib) for full list of standard library typeshed stub changes.
253+
254+
### Acknowledgements
255+
256+
Thanks to all mypy contributors who contributed to this release:
257+
258+
- Adam Turner
259+
- alicederyn
260+
- bzoracler
261+
- Colinxu2020
262+
- georgesittas
263+
- Ivan Levkivskyi
264+
- Jelle Zijlstra
265+
- Jingchen Ye
266+
- Jukka Lehtosalo
267+
- Kevin Kannammalil
268+
- lphuc2250gma
269+
- Marc Mueller
270+
- Pranav Manglik
271+
- Rayan Salhab
272+
- Ryan Heard
273+
- Sai Asish Y
274+
- Shantanu
275+
- sobolevn
276+
- Vaggelis Danias
277+
- Victor Letichevsky
278+
- Zakir Jiwani
279+
280+
I'd also like to thank my employer, Dropbox, for supporting mypy development.
281+
5282
## Mypy 2.1
6283

7284
We’ve just uploaded mypy 2.1.0 to the Python Package Index ([PyPI](https://pypi.org/project/mypy/)).

0 commit comments

Comments
 (0)