Skip to content

Commit fd79c7a

Browse files
committed
Merge remote-tracking branch 'upstream/master' into bugfix/st-paramspec-with-functools-partial
2 parents acb3548 + 6c1d867 commit fd79c7a

File tree

171 files changed

+5920
-1554
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+5920
-1554
lines changed

docs/source/error_code_list2.rst

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ Error codes for optional checks
55

66
This section documents various errors codes that mypy generates only
77
if you enable certain options. See :ref:`error-codes` for general
8-
documentation about error codes. :ref:`error-code-list` documents
9-
error codes that are enabled by default.
8+
documentation about error codes and their configuration.
9+
:ref:`error-code-list` documents error codes that are enabled by default.
1010

1111
.. note::
1212

@@ -241,7 +241,7 @@ mypy generates an error if it thinks that an expression is redundant.
241241

242242
.. code-block:: python
243243
244-
# Use "mypy --enable-error-code redundant-expr ..."
244+
# mypy: enable-error-code="redundant-expr"
245245
246246
def example(x: int) -> None:
247247
# Error: Left operand of "and" is always true [redundant-expr]
@@ -268,7 +268,7 @@ example:
268268

269269
.. code-block:: python
270270
271-
# Use "mypy --enable-error-code possibly-undefined ..."
271+
# mypy: enable-error-code="possibly-undefined"
272272
273273
from typing import Iterable
274274
@@ -297,7 +297,7 @@ Using an iterable value in a boolean context has a separate error code
297297

298298
.. code-block:: python
299299
300-
# Use "mypy --enable-error-code truthy-bool ..."
300+
# mypy: enable-error-code="truthy-bool"
301301
302302
class Foo:
303303
pass
@@ -347,7 +347,7 @@ Example:
347347

348348
.. code-block:: python
349349
350-
# Use "mypy --enable-error-code ignore-without-code ..."
350+
# mypy: enable-error-code="ignore-without-code"
351351
352352
class Foo:
353353
def __init__(self, name: str) -> None:
@@ -378,7 +378,7 @@ Example:
378378

379379
.. code-block:: python
380380
381-
# Use "mypy --enable-error-code unused-awaitable ..."
381+
# mypy: enable-error-code="unused-awaitable"
382382
383383
import asyncio
384384
@@ -462,7 +462,7 @@ Example:
462462

463463
.. code-block:: python
464464
465-
# Use "mypy --enable-error-code explicit-override ..."
465+
# mypy: enable-error-code="explicit-override"
466466
467467
from typing import override
468468
@@ -536,7 +536,7 @@ Now users can actually import ``reveal_type`` to make the runtime code safe.
536536

537537
.. code-block:: python
538538
539-
# Use "mypy --enable-error-code unimported-reveal"
539+
# mypy: enable-error-code="unimported-reveal"
540540
541541
x = 1
542542
reveal_type(x) # Note: Revealed type is "builtins.int" \
@@ -546,7 +546,7 @@ Correct usage:
546546

547547
.. code-block:: python
548548
549-
# Use "mypy --enable-error-code unimported-reveal"
549+
# mypy: enable-error-code="unimported-reveal"
550550
from typing import reveal_type # or `typing_extensions`
551551
552552
x = 1

docs/source/error_codes.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,13 @@ still keep the other two error codes enabled. The overall logic is following:
8787

8888
* Individual config sections *adjust* them per glob/module
8989

90-
* Inline ``# mypy: disable-error-code="..."`` comments can further
91-
*adjust* them for a specific module.
92-
For example: ``# mypy: disable-error-code="truthy-bool, ignore-without-code"``
90+
* Inline ``# mypy: disable-error-code="..."`` and ``# mypy: enable-error-code="..."``
91+
comments can further *adjust* them for a specific file.
92+
For example:
93+
94+
.. code-block:: python
95+
96+
# mypy: enable-error-code="truthy-bool, ignore-without-code"
9397
9498
So one can e.g. enable some code globally, disable it for all tests in
9599
the corresponding config section, and then re-enable it with an inline

misc/typeshed_patches/0001-Remove-use-of-LiteralString-in-builtins-13743.patch

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
From 5c00e362d40aa26e0a22a740f05a52d05edf0f91 Mon Sep 17 00:00:00 2001
1+
From 3ec9b878d6bbe3fae64a508a62372f10a886406f Mon Sep 17 00:00:00 2001
22
From: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
33
Date: Mon, 26 Sep 2022 12:55:07 -0700
44
Subject: [PATCH] Remove use of LiteralString in builtins (#13743)
55

66
---
7-
mypy/typeshed/stdlib/builtins.pyi | 88 -------------------------------
8-
1 file changed, 88 deletions(-)
7+
mypy/typeshed/stdlib/builtins.pyi | 95 -------------------------------
8+
1 file changed, 95 deletions(-)
99

1010
diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi
11-
index b4765b26c..99919c64c 100644
11+
index 53e00ec6a..bad3250ef 100644
1212
--- a/mypy/typeshed/stdlib/builtins.pyi
1313
+++ b/mypy/typeshed/stdlib/builtins.pyi
1414
@@ -61,7 +61,6 @@ from typing import ( # noqa: Y022
@@ -19,7 +19,7 @@ index b4765b26c..99919c64c 100644
1919
ParamSpec,
2020
Self,
2121
TypeAlias,
22-
@@ -434,31 +433,16 @@ class str(Sequence[str]):
22+
@@ -435,31 +434,16 @@ class str(Sequence[str]):
2323
def __new__(cls, object: object = ...) -> Self: ...
2424
@overload
2525
def __new__(cls, object: ReadableBuffer, encoding: str = ..., errors: str = ...) -> Self: ...
@@ -49,9 +49,9 @@ index b4765b26c..99919c64c 100644
4949
- def format(self: LiteralString, *args: LiteralString, **kwargs: LiteralString) -> LiteralString: ...
5050
- @overload
5151
def format(self, *args: object, **kwargs: object) -> str: ...
52-
def format_map(self, map: _FormatMapMapping) -> str: ...
52+
def format_map(self, mapping: _FormatMapMapping, /) -> str: ...
5353
def index(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ...
54-
@@ -474,89 +458,32 @@ class str(Sequence[str]):
54+
@@ -475,99 +459,35 @@ class str(Sequence[str]):
5555
def isspace(self) -> bool: ...
5656
def istitle(self) -> bool: ...
5757
def isupper(self) -> bool: ...
@@ -75,10 +75,20 @@ index b4765b26c..99919c64c 100644
7575
- def partition(self: LiteralString, sep: LiteralString, /) -> tuple[LiteralString, LiteralString, LiteralString]: ...
7676
- @overload
7777
def partition(self, sep: str, /) -> tuple[str, str, str]: ... # type: ignore[misc]
78-
- @overload
79-
- def replace(self: LiteralString, old: LiteralString, new: LiteralString, count: SupportsIndex = -1, /) -> LiteralString: ...
80-
- @overload
81-
def replace(self, old: str, new: str, count: SupportsIndex = -1, /) -> str: ... # type: ignore[misc]
78+
if sys.version_info >= (3, 13):
79+
- @overload
80+
- def replace(
81+
- self: LiteralString, old: LiteralString, new: LiteralString, /, count: SupportsIndex = -1
82+
- ) -> LiteralString: ...
83+
- @overload
84+
def replace(self, old: str, new: str, /, count: SupportsIndex = -1) -> str: ... # type: ignore[misc]
85+
else:
86+
- @overload
87+
- def replace(
88+
- self: LiteralString, old: LiteralString, new: LiteralString, count: SupportsIndex = -1, /
89+
- ) -> LiteralString: ...
90+
- @overload
91+
def replace(self, old: str, new: str, count: SupportsIndex = -1, /) -> str: ... # type: ignore[misc]
8292
if sys.version_info >= (3, 9):
8393
- @overload
8494
- def removeprefix(self: LiteralString, prefix: LiteralString, /) -> LiteralString: ...
@@ -141,7 +151,7 @@ index b4765b26c..99919c64c 100644
141151
def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc]
142152
@staticmethod
143153
@overload
144-
@@ -567,9 +494,6 @@ class str(Sequence[str]):
154+
@@ -578,9 +498,6 @@ class str(Sequence[str]):
145155
@staticmethod
146156
@overload
147157
def maketrans(x: str, y: str, z: str, /) -> dict[int, int | None]: ...
@@ -151,7 +161,7 @@ index b4765b26c..99919c64c 100644
151161
def __add__(self, value: str, /) -> str: ... # type: ignore[misc]
152162
# Incompatible with Sequence.__contains__
153163
def __contains__(self, key: str, /) -> bool: ... # type: ignore[override]
154-
@@ -578,25 +502,13 @@ class str(Sequence[str]):
164+
@@ -589,25 +506,13 @@ class str(Sequence[str]):
155165
def __getitem__(self, key: SupportsIndex | slice, /) -> str: ...
156166
def __gt__(self, value: str, /) -> bool: ...
157167
def __hash__(self) -> int: ...
@@ -178,5 +188,5 @@ index b4765b26c..99919c64c 100644
178188
def __getnewargs__(self) -> tuple[str]: ...
179189

180190
--
181-
2.39.3 (Apple Git-146)
191+
2.45.2
182192

mypy/applytype.py

Lines changed: 135 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,32 @@
11
from __future__ import annotations
22

3-
from typing import Callable, Sequence
3+
from typing import Callable, Iterable, Sequence
44

55
import mypy.subtypes
66
from mypy.erasetype import erase_typevars
77
from mypy.expandtype import expand_type
8-
from mypy.nodes import Context
8+
from mypy.nodes import Context, TypeInfo
9+
from mypy.type_visitor import TypeTranslator
10+
from mypy.typeops import get_all_type_vars
911
from mypy.types import (
1012
AnyType,
1113
CallableType,
14+
Instance,
15+
Parameters,
16+
ParamSpecFlavor,
1217
ParamSpecType,
1318
PartialType,
19+
ProperType,
1420
Type,
21+
TypeAliasType,
1522
TypeVarId,
1623
TypeVarLikeType,
1724
TypeVarTupleType,
1825
TypeVarType,
1926
UninhabitedType,
2027
UnpackType,
2128
get_proper_type,
29+
remove_dups,
2230
)
2331

2432

@@ -93,8 +101,7 @@ def apply_generic_arguments(
93101
bound or constraints, instead of giving an error.
94102
"""
95103
tvars = callable.variables
96-
min_arg_count = sum(not tv.has_default() for tv in tvars)
97-
assert min_arg_count <= len(orig_types) <= len(tvars)
104+
assert len(orig_types) <= len(tvars)
98105
# Check that inferred type variable values are compatible with allowed
99106
# values and bounds. Also, promote subtype values to allowed values.
100107
# Create a map from type variable id to target type.
@@ -148,7 +155,7 @@ def apply_generic_arguments(
148155
type_is = None
149156

150157
# The callable may retain some type vars if only some were applied.
151-
# TODO: move apply_poly() logic from checkexpr.py here when new inference
158+
# TODO: move apply_poly() logic here when new inference
152159
# becomes universally used (i.e. in all passes + in unification).
153160
# With this new logic we can actually *add* some new free variables.
154161
remaining_tvars: list[TypeVarLikeType] = []
@@ -170,3 +177,126 @@ def apply_generic_arguments(
170177
type_guard=type_guard,
171178
type_is=type_is,
172179
)
180+
181+
182+
def apply_poly(tp: CallableType, poly_tvars: Sequence[TypeVarLikeType]) -> CallableType | None:
183+
"""Make free type variables generic in the type if possible.
184+
185+
This will translate the type `tp` while trying to create valid bindings for
186+
type variables `poly_tvars` while traversing the type. This follows the same rules
187+
as we do during semantic analysis phase, examples:
188+
* Callable[Callable[[T], T], T] -> def [T] (def (T) -> T) -> T
189+
* Callable[[], Callable[[T], T]] -> def () -> def [T] (T -> T)
190+
* List[T] -> None (not possible)
191+
"""
192+
try:
193+
return tp.copy_modified(
194+
arg_types=[t.accept(PolyTranslator(poly_tvars)) for t in tp.arg_types],
195+
ret_type=tp.ret_type.accept(PolyTranslator(poly_tvars)),
196+
variables=[],
197+
)
198+
except PolyTranslationError:
199+
return None
200+
201+
202+
class PolyTranslationError(Exception):
203+
pass
204+
205+
206+
class PolyTranslator(TypeTranslator):
207+
"""Make free type variables generic in the type if possible.
208+
209+
See docstring for apply_poly() for details.
210+
"""
211+
212+
def __init__(
213+
self,
214+
poly_tvars: Iterable[TypeVarLikeType],
215+
bound_tvars: frozenset[TypeVarLikeType] = frozenset(),
216+
seen_aliases: frozenset[TypeInfo] = frozenset(),
217+
) -> None:
218+
self.poly_tvars = set(poly_tvars)
219+
# This is a simplified version of TypeVarScope used during semantic analysis.
220+
self.bound_tvars = bound_tvars
221+
self.seen_aliases = seen_aliases
222+
223+
def collect_vars(self, t: CallableType | Parameters) -> list[TypeVarLikeType]:
224+
found_vars = []
225+
for arg in t.arg_types:
226+
for tv in get_all_type_vars(arg):
227+
if isinstance(tv, ParamSpecType):
228+
normalized: TypeVarLikeType = tv.copy_modified(
229+
flavor=ParamSpecFlavor.BARE, prefix=Parameters([], [], [])
230+
)
231+
else:
232+
normalized = tv
233+
if normalized in self.poly_tvars and normalized not in self.bound_tvars:
234+
found_vars.append(normalized)
235+
return remove_dups(found_vars)
236+
237+
def visit_callable_type(self, t: CallableType) -> Type:
238+
found_vars = self.collect_vars(t)
239+
self.bound_tvars |= set(found_vars)
240+
result = super().visit_callable_type(t)
241+
self.bound_tvars -= set(found_vars)
242+
243+
assert isinstance(result, ProperType) and isinstance(result, CallableType)
244+
result.variables = list(result.variables) + found_vars
245+
return result
246+
247+
def visit_type_var(self, t: TypeVarType) -> Type:
248+
if t in self.poly_tvars and t not in self.bound_tvars:
249+
raise PolyTranslationError()
250+
return super().visit_type_var(t)
251+
252+
def visit_param_spec(self, t: ParamSpecType) -> Type:
253+
if t in self.poly_tvars and t not in self.bound_tvars:
254+
raise PolyTranslationError()
255+
return super().visit_param_spec(t)
256+
257+
def visit_type_var_tuple(self, t: TypeVarTupleType) -> Type:
258+
if t in self.poly_tvars and t not in self.bound_tvars:
259+
raise PolyTranslationError()
260+
return super().visit_type_var_tuple(t)
261+
262+
def visit_type_alias_type(self, t: TypeAliasType) -> Type:
263+
if not t.args:
264+
return t.copy_modified()
265+
if not t.is_recursive:
266+
return get_proper_type(t).accept(self)
267+
# We can't handle polymorphic application for recursive generic aliases
268+
# without risking an infinite recursion, just give up for now.
269+
raise PolyTranslationError()
270+
271+
def visit_instance(self, t: Instance) -> Type:
272+
if t.type.has_param_spec_type:
273+
# We need this special-casing to preserve the possibility to store a
274+
# generic function in an instance type. Things like
275+
# forall T . Foo[[x: T], T]
276+
# are not really expressible in current type system, but this looks like
277+
# a useful feature, so let's keep it.
278+
param_spec_index = next(
279+
i for (i, tv) in enumerate(t.type.defn.type_vars) if isinstance(tv, ParamSpecType)
280+
)
281+
p = get_proper_type(t.args[param_spec_index])
282+
if isinstance(p, Parameters):
283+
found_vars = self.collect_vars(p)
284+
self.bound_tvars |= set(found_vars)
285+
new_args = [a.accept(self) for a in t.args]
286+
self.bound_tvars -= set(found_vars)
287+
288+
repl = new_args[param_spec_index]
289+
assert isinstance(repl, ProperType) and isinstance(repl, Parameters)
290+
repl.variables = list(repl.variables) + list(found_vars)
291+
return t.copy_modified(args=new_args)
292+
# There is the same problem with callback protocols as with aliases
293+
# (callback protocols are essentially more flexible aliases to callables).
294+
if t.args and t.type.is_protocol and t.type.protocol_members == ["__call__"]:
295+
if t.type in self.seen_aliases:
296+
raise PolyTranslationError()
297+
call = mypy.subtypes.find_member("__call__", t, t, is_operator=True)
298+
assert call is not None
299+
return call.accept(
300+
PolyTranslator(self.poly_tvars, self.bound_tvars, self.seen_aliases | {t.type})
301+
)
302+
return super().visit_instance(t)

mypy/build.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3467,8 +3467,11 @@ def process_stale_scc(graph: Graph, scc: list[str], manager: BuildManager) -> No
34673467
for id in stale:
34683468
graph[id].transitive_error = True
34693469
for id in stale:
3470-
errors = manager.errors.file_messages(graph[id].xpath, formatter=manager.error_formatter)
3471-
manager.flush_errors(manager.errors.simplify_path(graph[id].xpath), errors, False)
3470+
if graph[id].xpath not in manager.errors.ignored_files:
3471+
errors = manager.errors.file_messages(
3472+
graph[id].xpath, formatter=manager.error_formatter
3473+
)
3474+
manager.flush_errors(manager.errors.simplify_path(graph[id].xpath), errors, False)
34723475
graph[id].write_cache()
34733476
graph[id].mark_as_rechecked()
34743477

0 commit comments

Comments
 (0)