Skip to content

Commit 555b202

Browse files
committed
Merge remote-tracking branch 'upstream/master' into enum-direct-calls
2 parents 97b6874 + 5a78607 commit 555b202

File tree

16 files changed

+269
-72
lines changed

16 files changed

+269
-72
lines changed

mypy/checkexpr.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,7 @@ def check_overload_call(
27222722
# for example, when we have a fallback alternative that accepts an unrestricted
27232723
# typevar. See https://github.com/python/mypy/issues/4063 for related discussion.
27242724
erased_targets: list[CallableType] | None = None
2725+
inferred_types: list[Type] | None = None
27252726
unioned_result: tuple[Type, Type] | None = None
27262727

27272728
# Determine whether we need to encourage union math. This should be generally safe,
@@ -2749,13 +2750,14 @@ def check_overload_call(
27492750
# Record if we succeeded. Next we need to see if maybe normal procedure
27502751
# gives a narrower type.
27512752
if unioned_return:
2752-
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]
27532755
# Note that we use `combine_function_signatures` instead of just returning
27542756
# a union of inferred callables because for example a call
27552757
# Union[int -> int, str -> str](Union[int, str]) is invalid and
27562758
# we don't want to introduce internal inconsistencies.
27572759
unioned_result = (
2758-
make_simplified_union(list(returns), context.line, context.column),
2760+
make_simplified_union(returns, context.line, context.column),
27592761
self.combine_function_signatures(get_proper_types(inferred_types)),
27602762
)
27612763

@@ -2770,19 +2772,26 @@ def check_overload_call(
27702772
object_type,
27712773
context,
27722774
)
2773-
# If any of checks succeed, stop early.
2775+
# If any of checks succeed, perform deprecation tests and stop early.
27742776
if inferred_result is not None and unioned_result is not None:
27752777
# Both unioned and direct checks succeeded, choose the more precise type.
27762778
if (
27772779
is_subtype(inferred_result[0], unioned_result[0])
27782780
and not isinstance(get_proper_type(inferred_result[0]), AnyType)
27792781
and not none_type_var_overlap
27802782
):
2781-
return inferred_result
2782-
return unioned_result
2783-
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)
27842791
return unioned_result
2785-
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)
27862795
return inferred_result
27872796

27882797
# Step 4: Failure. At this point, we know there is no match. We fall back to trying
@@ -2936,8 +2945,6 @@ def infer_overload_return_type(
29362945
# check for ambiguity due to 'Any' below.
29372946
if not args_contain_any:
29382947
self.chk.store_types(m)
2939-
if isinstance(infer_type, ProperType) and isinstance(infer_type, CallableType):
2940-
self.chk.warn_deprecated(infer_type.definition, context)
29412948
return ret_type, infer_type
29422949
p_infer_type = get_proper_type(infer_type)
29432950
if isinstance(p_infer_type, CallableType):
@@ -2974,11 +2981,6 @@ def infer_overload_return_type(
29742981
else:
29752982
# Success! No ambiguity; return the first match.
29762983
self.chk.store_types(type_maps[0])
2977-
inferred_callable = inferred_types[0]
2978-
if isinstance(inferred_callable, ProperType) and isinstance(
2979-
inferred_callable, CallableType
2980-
):
2981-
self.chk.warn_deprecated(inferred_callable.definition, context)
29822984
return return_types[0], inferred_types[0]
29832985

29842986
def overload_erased_call_targets(

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

mypy/types.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,7 @@
55
import sys
66
from abc import abstractmethod
77
from collections.abc import Iterable, Sequence
8-
from typing import (
9-
TYPE_CHECKING,
10-
Any,
11-
ClassVar,
12-
Final,
13-
NamedTuple,
14-
NewType,
15-
TypeVar,
16-
Union,
17-
cast,
18-
overload,
19-
)
8+
from typing import TYPE_CHECKING, Any, ClassVar, Final, NewType, TypeVar, Union, cast, overload
209
from typing_extensions import Self, TypeAlias as _TypeAlias, TypeGuard
2110

2211
import mypy.nodes
@@ -1607,11 +1596,25 @@ def bound(self) -> bool:
16071596
return bool(self.items) and self.items[0].is_bound
16081597

16091598

1610-
class FormalArgument(NamedTuple):
1611-
name: str | None
1612-
pos: int | None
1613-
typ: Type
1614-
required: bool
1599+
class FormalArgument:
1600+
def __init__(self, name: str | None, pos: int | None, typ: Type, required: bool) -> None:
1601+
self.name = name
1602+
self.pos = pos
1603+
self.typ = typ
1604+
self.required = required
1605+
1606+
def __eq__(self, other: object) -> bool:
1607+
if not isinstance(other, FormalArgument):
1608+
return NotImplemented
1609+
return (
1610+
self.name == other.name
1611+
and self.pos == other.pos
1612+
and self.typ == other.typ
1613+
and self.required == other.required
1614+
)
1615+
1616+
def __hash__(self) -> int:
1617+
return hash((self.name, self.pos, self.typ, self.required))
16151618

16161619

16171620
class Parameters(ProperType):

mypyc/codegen/emitclass.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ def emit_line() -> None:
375375
flags.append("Py_TPFLAGS_MANAGED_DICT")
376376
fields["tp_flags"] = " | ".join(flags)
377377

378-
fields["tp_doc"] = native_class_doc_initializer(cl)
378+
fields["tp_doc"] = f"PyDoc_STR({native_class_doc_initializer(cl)})"
379379

380380
emitter.emit_line(f"static PyTypeObject {emitter.type_struct_name(cl)}_template_ = {{")
381381
emitter.emit_line("PyVarObject_HEAD_INIT(NULL, 0)")
@@ -925,7 +925,7 @@ def generate_methods_table(cl: ClassIR, name: str, emitter: Emitter) -> None:
925925
flags.append("METH_CLASS")
926926

927927
doc = native_function_doc_initializer(fn)
928-
emitter.emit_line(" {}, {}}},".format(" | ".join(flags), doc))
928+
emitter.emit_line(" {}, PyDoc_STR({})}},".format(" | ".join(flags), doc))
929929

930930
# Provide a default __getstate__ and __setstate__
931931
if not cl.has_method("__setstate__") and not cl.has_method("__getstate__"):

mypyc/codegen/emitfunc.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from mypyc.codegen.cstring import c_string_initializer
99
from mypyc.codegen.emit import DEBUG_ERRORS, Emitter, TracebackAndGotoHandler, c_array_initializer
1010
from mypyc.common import (
11+
GENERATOR_ATTRIBUTE_PREFIX,
1112
HAVE_IMMORTAL,
1213
MODULE_PREFIX,
1314
NATIVE_PREFIX,
@@ -436,7 +437,9 @@ def visit_get_attr(self, op: GetAttr) -> None:
436437
exc_class = "PyExc_AttributeError"
437438
self.emitter.emit_line(
438439
'PyErr_SetString({}, "attribute {} of {} undefined");'.format(
439-
exc_class, repr(op.attr), repr(cl.name)
440+
exc_class,
441+
repr(op.attr.removeprefix(GENERATOR_ATTRIBUTE_PREFIX)),
442+
repr(cl.name),
440443
)
441444
)
442445

@@ -938,7 +941,7 @@ def emit_attribute_error(self, op: Branch, class_name: str, attr: str) -> None:
938941
self.source_path.replace("\\", "\\\\"),
939942
op.traceback_entry[0],
940943
class_name,
941-
attr,
944+
attr.removeprefix(GENERATOR_ATTRIBUTE_PREFIX),
942945
op.traceback_entry[1],
943946
globals_static,
944947
)

mypyc/codegen/emitmodule.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -983,7 +983,7 @@ def emit_module_methods(
983983
emitter.emit_line(
984984
(
985985
'{{"{name}", (PyCFunction){prefix}{cname}, {flag} | METH_KEYWORDS, '
986-
"{doc} /* docstring */}},"
986+
"PyDoc_STR({doc}) /* docstring */}},"
987987
).format(
988988
name=name, cname=fn.cname(emitter.names), prefix=PREFIX, flag=flag, doc=doc
989989
)

mypyc/common.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
LAMBDA_NAME: Final = "__mypyc_lambda__"
2424
PROPSET_PREFIX: Final = "__mypyc_setter__"
2525
SELF_NAME: Final = "__mypyc_self__"
26+
GENERATOR_ATTRIBUTE_PREFIX: Final = "__mypyc_generator_attribute__"
2627

2728
# Max short int we accept as a literal is based on 32-bit platforms,
2829
# so that we can just always emit the same code.

mypyc/irbuild/builder.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
)
6060
from mypy.util import module_prefix, split_target
6161
from mypy.visitor import ExpressionVisitor, StatementVisitor
62-
from mypyc.common import BITMAP_BITS, SELF_NAME, TEMP_ATTR_NAME
62+
from mypyc.common import BITMAP_BITS, GENERATOR_ATTRIBUTE_PREFIX, SELF_NAME, TEMP_ATTR_NAME
6363
from mypyc.crash import catch_errors
6464
from mypyc.errors import Errors
6565
from mypyc.ir.class_ir import ClassIR, NonExtClassInfo
@@ -651,7 +651,11 @@ def get_assignment_target(
651651
# current environment.
652652
if self.fn_info.is_generator:
653653
return self.add_var_to_env_class(
654-
symbol, reg_type, self.fn_info.generator_class, reassign=False
654+
symbol,
655+
reg_type,
656+
self.fn_info.generator_class,
657+
reassign=False,
658+
prefix=GENERATOR_ATTRIBUTE_PREFIX,
655659
)
656660

657661
# Otherwise define a new local variable.
@@ -1333,10 +1337,11 @@ def add_var_to_env_class(
13331337
base: FuncInfo | ImplicitClass,
13341338
reassign: bool = False,
13351339
always_defined: bool = False,
1340+
prefix: str = "",
13361341
) -> AssignmentTarget:
13371342
# First, define the variable name as an attribute of the environment class, and then
13381343
# construct a target for that attribute.
1339-
name = remangle_redefinition_name(var.name)
1344+
name = prefix + remangle_redefinition_name(var.name)
13401345
self.fn_info.env_class.attributes[name] = rtype
13411346
if always_defined:
13421347
self.fn_info.env_class.attrs_with_defaults.add(name)

0 commit comments

Comments
 (0)