Skip to content

Commit 048a50e

Browse files
Merge branch 'master' into patch-9
2 parents f6f98e4 + 44bbb18 commit 048a50e

23 files changed

+1280
-27
lines changed

docs/source/command_line.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ definitions or calls.
372372

373373
.. option:: --untyped-calls-exclude
374374

375-
This flag allows to selectively disable :option:`--disallow-untyped-calls`
375+
This flag allows one to selectively disable :option:`--disallow-untyped-calls`
376376
for functions and methods defined in specific packages, modules, or classes.
377377
Note that each exclude entry acts as a prefix. For example (assuming there
378378
are no type annotations for ``third_party_lib`` available):
@@ -562,7 +562,7 @@ potentially problematic or redundant in some way.
562562

563563
.. option:: --deprecated-calls-exclude
564564

565-
This flag allows to selectively disable :ref:`deprecated<code-deprecated>` warnings
565+
This flag allows one to selectively disable :ref:`deprecated<code-deprecated>` warnings
566566
for functions and methods defined in specific packages, modules, or classes.
567567
Note that each exclude entry acts as a prefix. For example (assuming ``foo.A.func`` is deprecated):
568568

docs/source/error_code_list.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,8 +1032,8 @@ Warn about top level await expressions [top-level-await]
10321032
This error code is separate from the general ``[syntax]`` errors, because in
10331033
some environments (e.g. IPython) a top level ``await`` is allowed. In such
10341034
environments a user may want to use ``--disable-error-code=top-level-await``,
1035-
that allows to still have errors for other improper uses of ``await``, for
1036-
example:
1035+
which allows one to still have errors for other improper uses of ``await``,
1036+
for example:
10371037

10381038
.. code-block:: python
10391039

docs/source/mypy_daemon.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,16 @@ command.
252252
Statically inspect expressions
253253
******************************
254254

255-
The daemon allows to get declared or inferred type of an expression (or other
255+
The daemon allows one to get the declared or inferred type of an expression (or other
256256
information about an expression, such as known attributes or definition location)
257-
using ``dmypy inspect LOCATION`` command. The location of the expression should be
257+
using the ``dmypy inspect LOCATION`` command. The location of the expression should be
258258
specified in the format ``path/to/file.py:line:column[:end_line:end_column]``.
259259
Both line and column are 1-based. Both start and end position are inclusive.
260260
These rules match how mypy prints the error location in error messages.
261261

262262
If a span is given (i.e. all 4 numbers), then only an exactly matching expression
263263
is inspected. If only a position is given (i.e. 2 numbers, line and column), mypy
264-
will inspect all *expressions*, that include this position, starting from the
264+
will inspect all expressions that include this position, starting from the
265265
innermost one.
266266

267267
Consider this Python code snippet:

mypy/traverser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ class ExtendedTraverserVisitor(TraverserVisitor):
504504
In addition to the base traverser it:
505505
* has visit_ methods for leaf nodes
506506
* has common method that is called for all nodes
507-
* allows to skip recursing into a node
507+
* allows skipping recursing into a node
508508
509509
Note that this traverser still doesn't visit some internal
510510
mypy constructs like _promote expression and Var.

mypy/type_visitor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
get_proper_type,
5252
)
5353

54-
T = TypeVar("T")
54+
T = TypeVar("T", covariant=True)
5555

5656

5757
@trait

mypy/types.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3938,8 +3938,12 @@ def visit_type_alias_type(self, t: TypeAliasType, /) -> list[mypy.nodes.TypeAlia
39383938
assert t.alias is not None
39393939
if t.alias not in self.seen_alias_nodes:
39403940
self.seen_alias_nodes.add(t.alias)
3941-
return [t.alias] + t.alias.target.accept(self)
3942-
return []
3941+
res = [t.alias] + t.alias.target.accept(self)
3942+
else:
3943+
res = []
3944+
for arg in t.args:
3945+
res.extend(arg.accept(self))
3946+
return res
39433947

39443948

39453949
def is_named_instance(t: Type, fullnames: str | tuple[str, ...]) -> TypeGuard[Instance]:

mypyc/codegen/emitclass.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ def dunder_attr_slot(cl: ClassIR, fn: FuncIR, emitter: Emitter) -> str:
6262
"__hash__": ("tp_hash", generate_hash_wrapper),
6363
"__get__": ("tp_descr_get", generate_get_wrapper),
6464
"__getattr__": ("tp_getattro", dunder_attr_slot),
65+
"__setattr__": ("tp_setattro", dunder_attr_slot),
6566
}
6667

6768
AS_MAPPING_SLOT_DEFS: SlotTable = {

mypyc/irbuild/builder.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
Integer,
7777
IntOp,
7878
LoadStatic,
79+
MethodCall,
7980
Op,
8081
PrimitiveDescription,
8182
RaiseStandardError,
@@ -700,7 +701,12 @@ def get_assignment_target(
700701
assert False, "Unsupported lvalue: %r" % lvalue
701702

702703
def read(
703-
self, target: Value | AssignmentTarget, line: int = -1, can_borrow: bool = False
704+
self,
705+
target: Value | AssignmentTarget,
706+
line: int = -1,
707+
*,
708+
can_borrow: bool = False,
709+
allow_error_value: bool = False,
704710
) -> Value:
705711
if isinstance(target, Value):
706712
return target
@@ -716,7 +722,15 @@ def read(
716722
if isinstance(target, AssignmentTargetAttr):
717723
if isinstance(target.obj.type, RInstance) and target.obj.type.class_ir.is_ext_class:
718724
borrow = can_borrow and target.can_borrow
719-
return self.add(GetAttr(target.obj, target.attr, line, borrow=borrow))
725+
return self.add(
726+
GetAttr(
727+
target.obj,
728+
target.attr,
729+
line,
730+
borrow=borrow,
731+
allow_error_value=allow_error_value,
732+
)
733+
)
720734
else:
721735
return self.py_get_attr(target.obj, target.attr, line)
722736

@@ -735,8 +749,15 @@ def assign(self, target: Register | AssignmentTarget, rvalue_reg: Value, line: i
735749
self.add(Assign(target.register, rvalue_reg))
736750
elif isinstance(target, AssignmentTargetAttr):
737751
if isinstance(target.obj_type, RInstance):
738-
rvalue_reg = self.coerce_rvalue(rvalue_reg, target.type, line)
739-
self.add(SetAttr(target.obj, target.attr, rvalue_reg, line))
752+
setattr = target.obj_type.class_ir.get_method("__setattr__")
753+
if setattr:
754+
key = self.load_str(target.attr)
755+
boxed_reg = self.builder.box(rvalue_reg)
756+
call = MethodCall(target.obj, setattr.name, [key, boxed_reg], line)
757+
self.add(call)
758+
else:
759+
rvalue_reg = self.coerce_rvalue(rvalue_reg, target.type, line)
760+
self.add(SetAttr(target.obj, target.attr, rvalue_reg, line))
740761
else:
741762
key = self.load_str(target.attr)
742763
boxed_reg = self.builder.box(rvalue_reg)

mypyc/irbuild/expression.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
apply_function_specialization,
102102
apply_method_specialization,
103103
translate_object_new,
104+
translate_object_setattr,
104105
)
105106
from mypyc.primitives.bytes_ops import bytes_slice_op
106107
from mypyc.primitives.dict_ops import dict_get_item_op, dict_new_op, exact_dict_set_item_op
@@ -480,6 +481,12 @@ def translate_super_method_call(builder: IRBuilder, expr: CallExpr, callee: Supe
480481
result = translate_object_new(builder, expr, MemberExpr(callee.call, "__new__"))
481482
if result:
482483
return result
484+
elif callee.name == "__setattr__":
485+
result = translate_object_setattr(
486+
builder, expr, MemberExpr(callee.call, "__setattr__")
487+
)
488+
if result:
489+
return result
483490
if ir.is_ext_class and ir.builtin_base is None and not ir.inherits_python:
484491
if callee.name == "__init__" and len(expr.args) == 0:
485492
# Call translates to object.__init__(self), which is a

mypyc/irbuild/for_helpers.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,12 @@ def for_loop_helper_with_index(
184184

185185
builder.push_loop_stack(step_block, exit_block)
186186

187-
builder.goto_and_activate(condition_block)
187+
if isinstance(length, Integer) and length.value > 0:
188+
builder.goto(body_block)
189+
builder.activate_block(condition_block)
190+
else:
191+
builder.goto_and_activate(condition_block)
192+
188193
for_gen.gen_condition()
189194

190195
builder.activate_block(body_block)

0 commit comments

Comments
 (0)