Skip to content

Commit 1ef94dc

Browse files
authored
Merge branch 'master' into fix_abs_path
2 parents 6f5c97b + 96fac3a commit 1ef94dc

21 files changed

+762
-60
lines changed

mypy-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ typing_extensions>=4.6.0
44
mypy_extensions>=1.0.0
55
pathspec>=0.9.0
66
tomli>=1.1.0; python_version<'3.11'
7-
librt>=0.6.0
7+
librt>=0.6.2

mypy/checker.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3424,7 +3424,11 @@ def check_assignment(
34243424
and lvalue_type is not None
34253425
):
34263426
lvalue.node.type = remove_instance_last_known_values(lvalue_type)
3427-
elif self.options.allow_redefinition_new and lvalue_type is not None:
3427+
elif (
3428+
self.options.allow_redefinition_new
3429+
and lvalue_type is not None
3430+
and not isinstance(lvalue_type, PartialType)
3431+
):
34283432
# TODO: Can we use put() here?
34293433
self.binder.assign_type(lvalue, lvalue_type, lvalue_type)
34303434

mypy/semanal.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,7 +2455,7 @@ def tvar_defs_from_tvars(
24552455
self.fail(
24562456
message_registry.TYPE_VAR_REDECLARED_IN_NESTED_CLASS.format(name), context
24572457
)
2458-
tvar_def = self.tvar_scope.bind_new(name, tvar_expr)
2458+
tvar_def = self.tvar_scope.bind_new(name, tvar_expr, self.fail, context)
24592459
if last_tvar_name_with_default is not None and not tvar_def.has_default():
24602460
self.msg.tvar_without_default_type(
24612461
tvar_def.name, last_tvar_name_with_default, context
@@ -2473,19 +2473,18 @@ def get_and_bind_all_tvars(self, type_exprs: list[Expression]) -> list[TypeVarLi
24732473
a simplified version of the logic we use for ClassDef bases. We duplicate
24742474
some amount of code, because it is hard to refactor common pieces.
24752475
"""
2476-
tvars = []
2476+
tvars: dict[str, tuple[TypeVarLikeExpr, Expression]] = {}
24772477
for base_expr in type_exprs:
24782478
try:
24792479
base = self.expr_to_unanalyzed_type(base_expr)
24802480
except TypeTranslationError:
24812481
# This error will be caught later.
24822482
continue
2483-
base_tvars = self.find_type_var_likes(base)
2484-
tvars.extend(base_tvars)
2485-
tvars = remove_dups(tvars) # Variables are defined in order of textual appearance.
2483+
for name, expr in self.find_type_var_likes(base):
2484+
tvars.setdefault(name, (expr, base_expr))
24862485
tvar_defs = []
2487-
for name, tvar_expr in tvars:
2488-
tvar_def = self.tvar_scope.bind_new(name, tvar_expr)
2486+
for name, (tvar_expr, context) in tvars.items():
2487+
tvar_def = self.tvar_scope.bind_new(name, tvar_expr, self.fail, context)
24892488
tvar_defs.append(tvar_def)
24902489
return tvar_defs
24912490

mypy/server/update.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ def restore(ids: list[str]) -> None:
631631

632632
# Find any other modules brought in by imports.
633633
changed_modules = [(st.id, st.xpath) for st in new_modules]
634+
for m in new_modules:
635+
manager.import_map[m.id] = set(m.dependencies + m.suppressed)
634636

635637
# If there are multiple modules to process, only process one of them and return
636638
# the remaining ones to the caller.

mypy/tvar_scope.py

Lines changed: 70 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,79 @@
11
from __future__ import annotations
22

3+
from collections.abc import Callable
4+
from typing_extensions import TypeAlias as _TypeAlias
5+
36
from mypy.nodes import (
7+
Context,
48
ParamSpecExpr,
59
SymbolTableNode,
610
TypeVarExpr,
711
TypeVarLikeExpr,
812
TypeVarTupleExpr,
913
)
1014
from mypy.types import (
15+
AnyType,
1116
ParamSpecFlavor,
1217
ParamSpecType,
18+
TrivialSyntheticTypeTranslator,
19+
Type,
20+
TypeAliasType,
21+
TypeOfAny,
1322
TypeVarId,
1423
TypeVarLikeType,
1524
TypeVarTupleType,
1625
TypeVarType,
1726
)
18-
from mypy.typetraverser import TypeTraverserVisitor
19-
20-
21-
class TypeVarLikeNamespaceSetter(TypeTraverserVisitor):
22-
"""Set namespace for all TypeVarLikeTypes types."""
2327

24-
def __init__(self, namespace: str) -> None:
25-
self.namespace = namespace
28+
FailFunc: _TypeAlias = Callable[[str, Context], None]
2629

27-
def visit_type_var(self, t: TypeVarType) -> None:
28-
t.id.namespace = self.namespace
29-
super().visit_type_var(t)
3030

31-
def visit_param_spec(self, t: ParamSpecType) -> None:
32-
t.id.namespace = self.namespace
33-
return super().visit_param_spec(t)
31+
class TypeVarLikeDefaultFixer(TrivialSyntheticTypeTranslator):
32+
"""Set namespace for all TypeVarLikeTypes types."""
3433

35-
def visit_type_var_tuple(self, t: TypeVarTupleType) -> None:
36-
t.id.namespace = self.namespace
37-
super().visit_type_var_tuple(t)
34+
def __init__(
35+
self,
36+
scope: TypeVarLikeScope,
37+
fail_func: FailFunc,
38+
source_tv: TypeVarLikeExpr,
39+
context: Context,
40+
) -> None:
41+
self.scope = scope
42+
self.fail_func = fail_func
43+
self.source_tv = source_tv
44+
self.context = context
45+
super().__init__()
46+
47+
def visit_type_var(self, t: TypeVarType) -> Type:
48+
existing = self.scope.get_binding(t.fullname)
49+
if existing is None:
50+
self._report_unbound_tvar(t)
51+
return AnyType(TypeOfAny.from_error)
52+
return existing
53+
54+
def visit_param_spec(self, t: ParamSpecType) -> Type:
55+
existing = self.scope.get_binding(t.fullname)
56+
if existing is None:
57+
self._report_unbound_tvar(t)
58+
return AnyType(TypeOfAny.from_error)
59+
return existing
60+
61+
def visit_type_var_tuple(self, t: TypeVarTupleType) -> Type:
62+
existing = self.scope.get_binding(t.fullname)
63+
if existing is None:
64+
self._report_unbound_tvar(t)
65+
return AnyType(TypeOfAny.from_error)
66+
return existing
67+
68+
def visit_type_alias_type(self, t: TypeAliasType) -> Type:
69+
return t
70+
71+
def _report_unbound_tvar(self, tvar: TypeVarLikeType) -> None:
72+
self.fail_func(
73+
f"Type variable {tvar.name} referenced in the default"
74+
f" of {self.source_tv.name} is unbound",
75+
self.context,
76+
)
3877

3978

4079
class TypeVarLikeScope:
@@ -98,15 +137,25 @@ def new_unique_func_id(self) -> TypeVarId:
98137
self.func_id -= 1
99138
return TypeVarId(self.func_id)
100139

101-
def bind_new(self, name: str, tvar_expr: TypeVarLikeExpr) -> TypeVarLikeType:
140+
def bind_new(
141+
self, name: str, tvar_expr: TypeVarLikeExpr, fail_func: FailFunc, context: Context
142+
) -> TypeVarLikeType:
102143
if self.is_class_scope:
103144
self.class_id += 1
104145
i = self.class_id
105146
else:
106147
self.func_id -= 1
107148
i = self.func_id
108149
namespace = self.namespace
109-
tvar_expr.default.accept(TypeVarLikeNamespaceSetter(namespace))
150+
151+
# Defaults may reference other type variables. That is only valid when the
152+
# referenced variable is already in scope (textually precedes the definition we're
153+
# processing now).
154+
default = tvar_expr.default.accept(
155+
TypeVarLikeDefaultFixer(
156+
self, fail_func=fail_func, source_tv=tvar_expr, context=context
157+
)
158+
)
110159

111160
if isinstance(tvar_expr, TypeVarExpr):
112161
tvar_def: TypeVarLikeType = TypeVarType(
@@ -115,7 +164,7 @@ def bind_new(self, name: str, tvar_expr: TypeVarLikeExpr) -> TypeVarLikeType:
115164
id=TypeVarId(i, namespace=namespace),
116165
values=tvar_expr.values,
117166
upper_bound=tvar_expr.upper_bound,
118-
default=tvar_expr.default,
167+
default=default,
119168
variance=tvar_expr.variance,
120169
line=tvar_expr.line,
121170
column=tvar_expr.column,
@@ -127,7 +176,7 @@ def bind_new(self, name: str, tvar_expr: TypeVarLikeExpr) -> TypeVarLikeType:
127176
id=TypeVarId(i, namespace=namespace),
128177
flavor=ParamSpecFlavor.BARE,
129178
upper_bound=tvar_expr.upper_bound,
130-
default=tvar_expr.default,
179+
default=default,
131180
line=tvar_expr.line,
132181
column=tvar_expr.column,
133182
)
@@ -138,7 +187,7 @@ def bind_new(self, name: str, tvar_expr: TypeVarLikeExpr) -> TypeVarLikeType:
138187
id=TypeVarId(i, namespace=namespace),
139188
upper_bound=tvar_expr.upper_bound,
140189
tuple_fallback=tvar_expr.tuple_fallback,
141-
default=tvar_expr.default,
190+
default=default,
142191
line=tvar_expr.line,
143192
column=tvar_expr.column,
144193
)

mypy/typeanal.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1580,7 +1580,9 @@ def analyze_callable_type(self, t: UnboundType) -> Type:
15801580
# below happens at very early stage.
15811581
variables = []
15821582
for name, tvar_expr in self.find_type_var_likes(callable_args):
1583-
variables.append(self.tvar_scope.bind_new(name, tvar_expr))
1583+
variables.append(
1584+
self.tvar_scope.bind_new(name, tvar_expr, self.fail_func, t)
1585+
)
15841586
maybe_ret = self.analyze_callable_args_for_paramspec(
15851587
callable_args, ret_type, fallback
15861588
) or self.analyze_callable_args_for_concatenate(
@@ -1852,7 +1854,7 @@ def bind_function_type_variables(
18521854
assert var_node, "Binding for function type variable not found within function"
18531855
var_expr = var_node.node
18541856
assert isinstance(var_expr, TypeVarLikeExpr)
1855-
binding = self.tvar_scope.bind_new(var.name, var_expr)
1857+
binding = self.tvar_scope.bind_new(var.name, var_expr, self.fail_func, fun_type)
18561858
defs.append(binding)
18571859
return tuple(defs), has_self_type
18581860
typevars, has_self_type = self.infer_type_variables(fun_type)
@@ -1865,7 +1867,7 @@ def bind_function_type_variables(
18651867
if not self.tvar_scope.allow_binding(tvar.fullname):
18661868
err_msg = message_registry.TYPE_VAR_REDECLARED_IN_NESTED_CLASS.format(name)
18671869
self.fail(err_msg.value, defn, code=err_msg.code)
1868-
binding = self.tvar_scope.bind_new(name, tvar)
1870+
binding = self.tvar_scope.bind_new(name, tvar, self.fail_func, fun_type)
18691871
defs.append(binding)
18701872

18711873
return tuple(defs), has_self_type
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
def b64encode(s: bytes) -> bytes: ...
2+
def b64decode(s: bytes | str) -> bytes: ...
3+
def urlsafe_b64encode(s: bytes) -> bytes: ...
4+
def urlsafe_b64decode(s: bytes | str) -> bytes: ...

mypyc/irbuild/expression.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,12 +504,12 @@ def translate_super_method_call(builder: IRBuilder, expr: CallExpr, callee: Supe
504504
if decl.kind == FUNC_CLASSMETHOD:
505505
vself = builder.primitive_op(type_op, [vself], expr.line)
506506
elif builder.fn_info.is_generator:
507-
# For generator classes, the self target is the 6th value
507+
# For generator classes, the self target is the 7th value
508508
# in the symbol table (which is an ordered dict). This is sort
509509
# of ugly, but we can't search by name since the 'self' parameter
510510
# could be named anything, and it doesn't get added to the
511511
# environment indexes.
512-
self_targ = list(builder.symtables[-1].values())[6]
512+
self_targ = list(builder.symtables[-1].values())[7]
513513
vself = builder.read(self_targ, builder.fn_info.fitem.line)
514514
arg_values.insert(0, vself)
515515
arg_kinds.insert(0, ARG_POS)

mypyc/irbuild/prepare.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,10 @@ def adjust_generator_classes_of_methods(mapper: Mapper) -> None:
842842
if subcls is None:
843843
# Override could be of a different type, so we can't make assumptions.
844844
precise_ret_type = False
845+
elif class_ir.is_trait:
846+
# Give up on traits. We could possibly have an abstract base class
847+
# for generator return types to make this use precise types.
848+
precise_ret_type = False
845849
else:
846850
for s in subcls:
847851
if name in s.method_decls:

mypyc/irbuild/targets.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ def __init__(self, register: Register) -> None:
2020
self.register = register
2121
self.type = register.type
2222

23+
def __repr__(self) -> str:
24+
return f"AssignmentTargetRegister({self.register.name})"
25+
2326

2427
class AssignmentTargetIndex(AssignmentTarget):
2528
"""base[index] as assignment target"""
@@ -31,6 +34,9 @@ def __init__(self, base: Value, index: Value) -> None:
3134
# lvalue type in mypy and use a better type to avoid unneeded boxing.
3235
self.type = object_rprimitive
3336

37+
def __repr__(self) -> str:
38+
return f"AssignmentTargetIndex({self.base!r}, {self.index!r})"
39+
3440

3541
class AssignmentTargetAttr(AssignmentTarget):
3642
"""obj.attr as assignment target"""
@@ -48,10 +54,17 @@ def __init__(self, obj: Value, attr: str, can_borrow: bool = False) -> None:
4854
self.obj_type = object_rprimitive
4955
self.type = object_rprimitive
5056

57+
def __repr__(self) -> str:
58+
can_borrow_str = ", can_borrow=True" if self.can_borrow else ""
59+
return f"AssignmentTargetAttr({self.obj!r}.{self.attr}{can_borrow_str})"
60+
5161

5262
class AssignmentTargetTuple(AssignmentTarget):
5363
"""x, ..., y as assignment target"""
5464

5565
def __init__(self, items: list[AssignmentTarget], star_idx: int | None = None) -> None:
5666
self.items = items
5767
self.star_idx = star_idx
68+
69+
def __repr__(self) -> str:
70+
return f"AssignmentTargetTuple({self.items}, {self.star_idx})"

0 commit comments

Comments
 (0)