Skip to content

Commit 2188acb

Browse files
committed
Merge remote-tracking branch 'refs/remotes/origin/master' into color-output-option
2 parents 807f022 + 1f9505c commit 2188acb

File tree

94 files changed

+3151
-1345
lines changed

Some content is hidden

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

94 files changed

+3151
-1345
lines changed

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
From e6995c91231e1915eba43a29a22dd4cbfaf9e08e Mon Sep 17 00:00:00 2001
1+
From 805d7fc06a8bee350959512e0908a18a87b7f8c2 Mon Sep 17 00:00:00 2001
22
From: Shantanu <[email protected]>
33
Date: Mon, 26 Sep 2022 12:55:07 -0700
44
Subject: [PATCH] Remove use of LiteralString in builtins (#13743)
@@ -8,7 +8,7 @@ Subject: [PATCH] Remove use of LiteralString in builtins (#13743)
88
1 file changed, 1 insertion(+), 99 deletions(-)
99

1010
diff --git a/mypy/typeshed/stdlib/builtins.pyi b/mypy/typeshed/stdlib/builtins.pyi
11-
index 00728f42d..ea77a730f 100644
11+
index c7ab95482..3e93da36e 100644
1212
--- a/mypy/typeshed/stdlib/builtins.pyi
1313
+++ b/mypy/typeshed/stdlib/builtins.pyi
1414
@@ -63,7 +63,6 @@ from typing import ( # noqa: Y022,UP035
@@ -19,7 +19,7 @@ index 00728f42d..ea77a730f 100644
1919
ParamSpec,
2020
Self,
2121
TypeAlias,
22-
@@ -453,31 +452,16 @@ class str(Sequence[str]):
22+
@@ -468,31 +467,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: ...
@@ -51,7 +51,7 @@ index 00728f42d..ea77a730f 100644
5151
def format(self, *args: object, **kwargs: object) -> str: ...
5252
def format_map(self, mapping: _FormatMapMapping, /) -> str: ...
5353
def index(self, sub: str, start: SupportsIndex | None = ..., end: SupportsIndex | None = ..., /) -> int: ...
54-
@@ -493,98 +477,34 @@ class str(Sequence[str]):
54+
@@ -508,98 +492,34 @@ class str(Sequence[str]):
5555
def isspace(self) -> bool: ...
5656
def istitle(self) -> bool: ...
5757
def isupper(self) -> bool: ...
@@ -150,7 +150,7 @@ index 00728f42d..ea77a730f 100644
150150
def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc]
151151
@staticmethod
152152
@overload
153-
@@ -595,39 +515,21 @@ class str(Sequence[str]):
153+
@@ -610,39 +530,21 @@ class str(Sequence[str]):
154154
@staticmethod
155155
@overload
156156
def maketrans(x: str, y: str, z: str, /) -> dict[int, int | None]: ...
@@ -190,7 +190,7 @@ index 00728f42d..ea77a730f 100644
190190
- @overload
191191
def __rmul__(self, value: SupportsIndex, /) -> str: ... # type: ignore[misc]
192192
def __getnewargs__(self) -> tuple[str]: ...
193-
193+
def __format__(self, format_spec: str, /) -> str: ...
194194
--
195-
2.49.0
195+
2.50.1
196196

mypy/checker.py

Lines changed: 65 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@
66
from collections import defaultdict
77
from collections.abc import Iterable, Iterator, Mapping, Sequence, Set as AbstractSet
88
from contextlib import ExitStack, contextmanager
9-
from typing import Callable, Final, Generic, NamedTuple, Optional, TypeVar, Union, cast, overload
9+
from typing import (
10+
Callable,
11+
Final,
12+
Generic,
13+
Literal,
14+
NamedTuple,
15+
Optional,
16+
TypeVar,
17+
Union,
18+
cast,
19+
overload,
20+
)
1021
from typing_extensions import TypeAlias as _TypeAlias, TypeGuard
1122

1223
import mypy.checkexpr
@@ -277,6 +288,26 @@ class PartialTypeScope(NamedTuple):
277288
is_local: bool
278289

279290

291+
class LocalTypeMap:
292+
"""Store inferred types into a temporary type map (returned).
293+
294+
This can be used to perform type checking "experiments" without
295+
affecting exported types (which are used by mypyc).
296+
"""
297+
298+
def __init__(self, chk: TypeChecker) -> None:
299+
self.chk = chk
300+
301+
def __enter__(self) -> dict[Expression, Type]:
302+
temp_type_map: dict[Expression, Type] = {}
303+
self.chk._type_maps.append(temp_type_map)
304+
return temp_type_map
305+
306+
def __exit__(self, exc_type: object, exc_val: object, exc_tb: object) -> Literal[False]:
307+
self.chk._type_maps.pop()
308+
return False
309+
310+
280311
class TypeChecker(NodeVisitor[None], TypeCheckerSharedApi):
281312
"""Mypy type checker.
282313
@@ -402,6 +433,7 @@ def __init__(
402433
self.is_typeshed_stub = tree.is_typeshed_file(options)
403434
self.inferred_attribute_types = None
404435
self.allow_constructor_cache = True
436+
self.local_type_map = LocalTypeMap(self)
405437

406438
# If True, process function definitions. If False, don't. This is used
407439
# for processing module top levels in fine-grained incremental mode.
@@ -431,6 +463,13 @@ def __init__(
431463
self._expr_checker = mypy.checkexpr.ExpressionChecker(
432464
self, self.msg, self.plugin, per_line_checking_time_ns
433465
)
466+
467+
self._str_type: Instance | None = None
468+
self._function_type: Instance | None = None
469+
self._int_type: Instance | None = None
470+
self._bool_type: Instance | None = None
471+
self._object_type: Instance | None = None
472+
434473
self.pattern_checker = PatternChecker(self, self.msg, self.plugin, options)
435474
self._unique_id = 0
436475

@@ -4624,7 +4663,7 @@ def check_simple_assignment(
46244663
# may cause some perf impact, plus we want to partially preserve
46254664
# the old behavior. This helps with various practical examples, see
46264665
# e.g. testOptionalTypeNarrowedByGenericCall.
4627-
with self.msg.filter_errors() as local_errors, self.local_type_map() as type_map:
4666+
with self.msg.filter_errors() as local_errors, self.local_type_map as type_map:
46284667
alt_rvalue_type = self.expr_checker.accept(
46294668
rvalue, None, always_allow_any=always_allow_any
46304669
)
@@ -5463,7 +5502,7 @@ def visit_with_stmt(self, s: WithStmt) -> None:
54635502
self.accept(s.body)
54645503

54655504
def check_untyped_after_decorator(self, typ: Type, func: FuncDef) -> None:
5466-
if not self.options.disallow_any_decorated or self.is_stub:
5505+
if not self.options.disallow_any_decorated or self.is_stub or self.current_node_deferred:
54675506
return
54685507

54695508
if mypy.checkexpr.has_any_type(typ):
@@ -7369,6 +7408,29 @@ def named_type(self, name: str) -> Instance:
73697408
73707409
For example, named_type('builtins.object') produces the 'object' type.
73717410
"""
7411+
if name == "builtins.str":
7412+
if self._str_type is None:
7413+
self._str_type = self._named_type(name)
7414+
return self._str_type
7415+
if name == "builtins.function":
7416+
if self._function_type is None:
7417+
self._function_type = self._named_type(name)
7418+
return self._function_type
7419+
if name == "builtins.int":
7420+
if self._int_type is None:
7421+
self._int_type = self._named_type(name)
7422+
return self._int_type
7423+
if name == "builtins.bool":
7424+
if self._bool_type is None:
7425+
self._bool_type = self._named_type(name)
7426+
return self._bool_type
7427+
if name == "builtins.object":
7428+
if self._object_type is None:
7429+
self._object_type = self._named_type(name)
7430+
return self._object_type
7431+
return self._named_type(name)
7432+
7433+
def _named_type(self, name: str) -> Instance:
73727434
# Assume that the name refers to a type.
73737435
sym = self.lookup_qualified(name)
73747436
node = sym.node
@@ -7428,18 +7490,6 @@ def lookup_type(self, node: Expression) -> Type:
74287490
def store_types(self, d: dict[Expression, Type]) -> None:
74297491
self._type_maps[-1].update(d)
74307492

7431-
@contextmanager
7432-
def local_type_map(self) -> Iterator[dict[Expression, Type]]:
7433-
"""Store inferred types into a temporary type map (returned).
7434-
7435-
This can be used to perform type checking "experiments" without
7436-
affecting exported types (which are used by mypyc).
7437-
"""
7438-
temp_type_map: dict[Expression, Type] = {}
7439-
self._type_maps.append(temp_type_map)
7440-
yield temp_type_map
7441-
self._type_maps.pop()
7442-
74437493
def in_checked_function(self) -> bool:
74447494
"""Should we type-check the current function?
74457495

mypy/checkexpr.py

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,9 @@ def __init__(
360360
] = {}
361361
self.in_lambda_expr = False
362362

363+
self._literal_true: Instance | None = None
364+
self._literal_false: Instance | None = None
365+
363366
def reset(self) -> None:
364367
self.resolved_type = {}
365368
self.expr_cache.clear()
@@ -1072,7 +1075,7 @@ def check_typeddict_call_with_kwargs(
10721075

10731076
# We don't show any errors, just infer types in a generic TypedDict type,
10741077
# a custom error message will be given below, if there are errors.
1075-
with self.msg.filter_errors(), self.chk.local_type_map():
1078+
with self.msg.filter_errors(), self.chk.local_type_map:
10761079
orig_ret_type, _ = self.check_callable_call(
10771080
infer_callee,
10781081
# We use first expression for each key to infer type variables of a generic
@@ -1437,7 +1440,7 @@ def is_generic_decorator_overload_call(
14371440
return None
14381441
if not isinstance(get_proper_type(callee_type.ret_type), CallableType):
14391442
return None
1440-
with self.chk.local_type_map():
1443+
with self.chk.local_type_map:
14411444
with self.msg.filter_errors():
14421445
arg_type = get_proper_type(self.accept(args[0], type_context=None))
14431446
if isinstance(arg_type, Overloaded):
@@ -2719,6 +2722,7 @@ def check_overload_call(
27192722
# for example, when we have a fallback alternative that accepts an unrestricted
27202723
# typevar. See https://github.com/python/mypy/issues/4063 for related discussion.
27212724
erased_targets: list[CallableType] | None = None
2725+
inferred_types: list[Type] | None = None
27222726
unioned_result: tuple[Type, Type] | None = None
27232727

27242728
# Determine whether we need to encourage union math. This should be generally safe,
@@ -2746,13 +2750,14 @@ def check_overload_call(
27462750
# Record if we succeeded. Next we need to see if maybe normal procedure
27472751
# gives a narrower type.
27482752
if unioned_return:
2749-
returns, inferred_types = zip(*unioned_return)
2753+
returns = [u[0] for u in unioned_return]
2754+
inferred_types = [u[1] for u in unioned_return]
27502755
# Note that we use `combine_function_signatures` instead of just returning
27512756
# a union of inferred callables because for example a call
27522757
# Union[int -> int, str -> str](Union[int, str]) is invalid and
27532758
# we don't want to introduce internal inconsistencies.
27542759
unioned_result = (
2755-
make_simplified_union(list(returns), context.line, context.column),
2760+
make_simplified_union(returns, context.line, context.column),
27562761
self.combine_function_signatures(get_proper_types(inferred_types)),
27572762
)
27582763

@@ -2767,19 +2772,26 @@ def check_overload_call(
27672772
object_type,
27682773
context,
27692774
)
2770-
# If any of checks succeed, stop early.
2775+
# If any of checks succeed, perform deprecation tests and stop early.
27712776
if inferred_result is not None and unioned_result is not None:
27722777
# Both unioned and direct checks succeeded, choose the more precise type.
27732778
if (
27742779
is_subtype(inferred_result[0], unioned_result[0])
27752780
and not isinstance(get_proper_type(inferred_result[0]), AnyType)
27762781
and not none_type_var_overlap
27772782
):
2778-
return inferred_result
2779-
return unioned_result
2780-
elif unioned_result is not None:
2783+
unioned_result = None
2784+
else:
2785+
inferred_result = None
2786+
if unioned_result is not None:
2787+
if inferred_types is not None:
2788+
for inferred_type in inferred_types:
2789+
if isinstance(c := get_proper_type(inferred_type), CallableType):
2790+
self.chk.warn_deprecated(c.definition, context)
27812791
return unioned_result
2782-
elif inferred_result is not None:
2792+
if inferred_result is not None:
2793+
if isinstance(c := get_proper_type(inferred_result[1]), CallableType):
2794+
self.chk.warn_deprecated(c.definition, context)
27832795
return inferred_result
27842796

27852797
# Step 4: Failure. At this point, we know there is no match. We fall back to trying
@@ -2917,7 +2929,7 @@ def infer_overload_return_type(
29172929
for typ in plausible_targets:
29182930
assert self.msg is self.chk.msg
29192931
with self.msg.filter_errors() as w:
2920-
with self.chk.local_type_map() as m:
2932+
with self.chk.local_type_map as m:
29212933
ret_type, infer_type = self.check_call(
29222934
callee=typ,
29232935
args=args,
@@ -2933,8 +2945,6 @@ def infer_overload_return_type(
29332945
# check for ambiguity due to 'Any' below.
29342946
if not args_contain_any:
29352947
self.chk.store_types(m)
2936-
if isinstance(infer_type, ProperType) and isinstance(infer_type, CallableType):
2937-
self.chk.warn_deprecated(infer_type.definition, context)
29382948
return ret_type, infer_type
29392949
p_infer_type = get_proper_type(infer_type)
29402950
if isinstance(p_infer_type, CallableType):
@@ -2971,11 +2981,6 @@ def infer_overload_return_type(
29712981
else:
29722982
# Success! No ambiguity; return the first match.
29732983
self.chk.store_types(type_maps[0])
2974-
inferred_callable = inferred_types[0]
2975-
if isinstance(inferred_callable, ProperType) and isinstance(
2976-
inferred_callable, CallableType
2977-
):
2978-
self.chk.warn_deprecated(inferred_callable.definition, context)
29792984
return return_types[0], inferred_types[0]
29802985

29812986
def overload_erased_call_targets(
@@ -3428,11 +3433,19 @@ def infer_literal_expr_type(self, value: LiteralValue, fallback_name: str) -> Ty
34283433
if self.is_literal_context():
34293434
return LiteralType(value=value, fallback=typ)
34303435
else:
3431-
return typ.copy_modified(
3432-
last_known_value=LiteralType(
3433-
value=value, fallback=typ, line=typ.line, column=typ.column
3434-
)
3435-
)
3436+
if value is True:
3437+
if self._literal_true is None:
3438+
self._literal_true = typ.copy_modified(
3439+
last_known_value=LiteralType(value=value, fallback=typ)
3440+
)
3441+
return self._literal_true
3442+
if value is False:
3443+
if self._literal_false is None:
3444+
self._literal_false = typ.copy_modified(
3445+
last_known_value=LiteralType(value=value, fallback=typ)
3446+
)
3447+
return self._literal_false
3448+
return typ.copy_modified(last_known_value=LiteralType(value=value, fallback=typ))
34363449

34373450
def concat_tuples(self, left: TupleType, right: TupleType) -> TupleType:
34383451
"""Concatenate two fixed length tuples."""
@@ -5356,7 +5369,7 @@ def visit_dict_expr(self, e: DictExpr) -> Type:
53565369
return self.check_typeddict_literal_in_context(e, typeddict_contexts[0])
53575370
# Multiple items union, check if at least one of them matches cleanly.
53585371
for typeddict_context in typeddict_contexts:
5359-
with self.msg.filter_errors() as err, self.chk.local_type_map() as tmap:
5372+
with self.msg.filter_errors() as err, self.chk.local_type_map as tmap:
53605373
ret_type = self.check_typeddict_literal_in_context(e, typeddict_context)
53615374
if err.has_new_errors():
53625375
continue
@@ -6084,15 +6097,12 @@ def accept(
60846097

60856098
def accept_maybe_cache(self, node: Expression, type_context: Type | None = None) -> Type:
60866099
binder_version = self.chk.binder.version
6087-
# Micro-optimization: inline local_type_map() as it is somewhat slow in mypyc.
6088-
type_map: dict[Expression, Type] = {}
6089-
self.chk._type_maps.append(type_map)
60906100
with self.msg.filter_errors(filter_errors=True, save_filtered_errors=True) as msg:
6091-
typ = node.accept(self)
6101+
with self.chk.local_type_map as type_map:
6102+
typ = node.accept(self)
60926103
messages = msg.filtered_errors()
60936104
if binder_version == self.chk.binder.version and not self.chk.current_node_deferred:
60946105
self.expr_cache[(node, type_context)] = (binder_version, typ, messages, type_map)
6095-
self.chk._type_maps.pop()
60966106
self.chk.store_types(type_map)
60976107
self.msg.add_errors(messages)
60986108
return typ

mypy/messages.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2432,13 +2432,13 @@ def format_long_tuple_type(self, typ: TupleType) -> str:
24322432
"""Format very long tuple type using an ellipsis notation"""
24332433
item_cnt = len(typ.items)
24342434
if item_cnt > MAX_TUPLE_ITEMS:
2435-
return "tuple[{}, {}, ... <{} more items>]".format(
2435+
return '"tuple[{}, {}, ... <{} more items>]"'.format(
24362436
format_type_bare(typ.items[0], self.options),
24372437
format_type_bare(typ.items[1], self.options),
24382438
str(item_cnt - 2),
24392439
)
24402440
else:
2441-
return format_type_bare(typ, self.options)
2441+
return format_type(typ, self.options)
24422442

24432443
def generate_incompatible_tuple_error(
24442444
self,
@@ -2517,15 +2517,12 @@ def iteration_dependent_errors(self, iter_errors: IterationDependentErrors) -> N
25172517

25182518
def quote_type_string(type_string: str) -> str:
25192519
"""Quotes a type representation for use in messages."""
2520-
no_quote_regex = r"^<(tuple|union): \d+ items>$"
25212520
if (
25222521
type_string in ["Module", "overloaded function", "<deleted>"]
25232522
or type_string.startswith("Module ")
2524-
or re.match(no_quote_regex, type_string) is not None
25252523
or type_string.endswith("?")
25262524
):
2527-
# Messages are easier to read if these aren't quoted. We use a
2528-
# regex to match strings with variable contents.
2525+
# These messages are easier to read if these aren't quoted.
25292526
return type_string
25302527
return f'"{type_string}"'
25312528

0 commit comments

Comments
 (0)