Skip to content

Commit 914a77e

Browse files
committed
Address review comments
1 parent 4ed9c54 commit 914a77e

File tree

4 files changed

+152
-13
lines changed

4 files changed

+152
-13
lines changed

mypyc/irbuild/expression.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -481,17 +481,17 @@ def translate_super_method_call(builder: IRBuilder, expr: CallExpr, callee: Supe
481481
result = translate_object_new(builder, expr, MemberExpr(callee.call, "__new__"))
482482
if result:
483483
return result
484+
elif callee.name == "__setattr__" and ir.builtin_base is None and not ir.inherits_python:
485+
result = translate_object_setattr(
486+
builder, expr, MemberExpr(callee.call, "__setattr__")
487+
)
488+
if result:
489+
return result
484490
if ir.is_ext_class and ir.builtin_base is None and not ir.inherits_python:
485491
if callee.name == "__init__" and len(expr.args) == 0:
486492
# Call translates to object.__init__(self), which is a
487493
# no-op, so omit the call.
488494
return builder.none()
489-
elif callee.name == "__setattr__":
490-
result = translate_object_setattr(
491-
builder, expr, MemberExpr(callee.call, "__setattr__")
492-
)
493-
if result:
494-
return result
495495
return translate_call(builder, expr, callee)
496496

497497
decl = base.method_decl(callee.name)

mypyc/irbuild/specialize.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,9 +1010,7 @@ def translate_ord(builder: IRBuilder, expr: CallExpr, callee: RefExpr) -> Value
10101010

10111011

10121012
def is_object(callee: RefExpr) -> bool:
1013-
"""
1014-
Returns True for object.<name> calls
1015-
"""
1013+
"""Returns True for object.<name> calls."""
10161014
return (
10171015
isinstance(callee, MemberExpr)
10181016
and isinstance(callee.expr, NameExpr)
@@ -1021,9 +1019,7 @@ def is_object(callee: RefExpr) -> bool:
10211019

10221020

10231021
def is_super_or_object(expr: CallExpr, callee: RefExpr) -> bool:
1024-
"""
1025-
Returns True for super().<name> or object.<name> calls.
1026-
"""
1022+
"""Returns True for super().<name> or object.<name> calls."""
10271023
return isinstance(expr.callee, SuperExpr) or is_object(callee)
10281024

10291025

mypyc/test-data/irbuild-classes.test

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2373,6 +2373,8 @@ L0:
23732373
return 1
23742374

23752375
[case testUntransformedSetAttr_64bit]
2376+
from mypy_extensions import mypyc_attr
2377+
23762378
class SetAttr:
23772379
def super_missing_args(self):
23782380
super().__setattr__()
@@ -2383,6 +2385,18 @@ class SetAttr:
23832385
object.__setattr__(self)
23842386
object.__setattr__(self, "attr")
23852387

2388+
@mypyc_attr(native_class=False)
2389+
class NonNative:
2390+
pass
2391+
2392+
class InheritsPython(NonNative):
2393+
def super_setattr(self, key: str, val: object) -> None:
2394+
super().__setattr__(key, val)
2395+
2396+
class BuiltInBase(dict):
2397+
def super_setattr(self, key: str, val: object) -> None:
2398+
super().__setattr__(key, val)
2399+
23862400
[typing fixtures/typing-full.pyi]
23872401
[out]
23882402
def SetAttr.super_missing_args(self):
@@ -2484,3 +2498,63 @@ L0:
24842498
keep_alive r16, self, r17
24852499
r22 = box(None, 1)
24862500
return r22
2501+
def InheritsPython.super_setattr(self, key, val):
2502+
self :: __main__.InheritsPython
2503+
key :: str
2504+
val, r0 :: object
2505+
r1 :: str
2506+
r2, r3 :: object
2507+
r4 :: object[2]
2508+
r5 :: object_ptr
2509+
r6 :: object
2510+
r7 :: str
2511+
r8 :: object
2512+
r9 :: object[2]
2513+
r10 :: object_ptr
2514+
r11 :: object
2515+
L0:
2516+
r0 = builtins :: module
2517+
r1 = 'super'
2518+
r2 = CPyObject_GetAttr(r0, r1)
2519+
r3 = __main__.InheritsPython :: type
2520+
r4 = [r3, self]
2521+
r5 = load_address r4
2522+
r6 = PyObject_Vectorcall(r2, r5, 2, 0)
2523+
keep_alive r3, self
2524+
r7 = '__setattr__'
2525+
r8 = CPyObject_GetAttr(r6, r7)
2526+
r9 = [key, val]
2527+
r10 = load_address r9
2528+
r11 = PyObject_Vectorcall(r8, r10, 2, 0)
2529+
keep_alive key, val
2530+
return 1
2531+
def BuiltInBase.super_setattr(self, key, val):
2532+
self :: dict
2533+
key :: str
2534+
val, r0 :: object
2535+
r1 :: str
2536+
r2, r3 :: object
2537+
r4 :: object[2]
2538+
r5 :: object_ptr
2539+
r6 :: object
2540+
r7 :: str
2541+
r8 :: object
2542+
r9 :: object[2]
2543+
r10 :: object_ptr
2544+
r11 :: object
2545+
L0:
2546+
r0 = builtins :: module
2547+
r1 = 'super'
2548+
r2 = CPyObject_GetAttr(r0, r1)
2549+
r3 = __main__.BuiltInBase :: type
2550+
r4 = [r3, self]
2551+
r5 = load_address r4
2552+
r6 = PyObject_Vectorcall(r2, r5, 2, 0)
2553+
keep_alive r3, self
2554+
r7 = '__setattr__'
2555+
r8 = CPyObject_GetAttr(r6, r7)
2556+
r9 = [key, val]
2557+
r10 = load_address r9
2558+
r11 = PyObject_Vectorcall(r8, r10, 2, 0)
2559+
keep_alive key, val
2560+
return 1

mypyc/test-data/run-classes.test

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4598,6 +4598,20 @@ class NoSetAttr:
45984598
def super_setattr(self, attr: str, val: object) -> None:
45994599
super().__setattr__(attr, val)
46004600

4601+
@mypyc_attr(native_class=False)
4602+
class NoSetAttrNonNative:
4603+
def __init__(self, attr: int) -> None:
4604+
self.attr = attr
4605+
4606+
def object_setattr(self, attr: str, val: object) -> None:
4607+
object.__setattr__(self, attr, val)
4608+
4609+
def super_setattr(self, attr: str, val: object) -> None:
4610+
super().__setattr__(attr, val)
4611+
4612+
def __getattr__(self, attr: str) -> object:
4613+
pass
4614+
46014615
def test_setattr() -> None:
46024616
i = SetAttr(99, {"one": 1})
46034617
assert i.class_var == "x"
@@ -4772,6 +4786,26 @@ def test_no_setattr() -> None:
47724786
with assertRaises(AttributeError):
47734787
object.__setattr__(i, "not_attr", 102)
47744788

4789+
def test_no_setattr_nonnative() -> None:
4790+
i = NoSetAttrNonNative(99)
4791+
i.super_setattr("attr", 100)
4792+
assert i.attr == 100
4793+
4794+
i.object_setattr("attr", 101)
4795+
assert i.attr == 101
4796+
4797+
object.__setattr__(i, "attr", 102)
4798+
assert i.attr == 102
4799+
4800+
i.super_setattr("one", 100)
4801+
assert i.one == 100
4802+
4803+
i.object_setattr("two", 101)
4804+
assert i.two == 101
4805+
4806+
object.__setattr__(i, "three", 102)
4807+
assert i.three == 102
4808+
47754809
[typing fixtures/typing-full.pyi]
47764810

47774811
[case testDunderSetAttrInterpreted]
@@ -4851,8 +4885,22 @@ class NoSetAttr:
48514885
def super_setattr(self, attr: str, val: object) -> None:
48524886
super().__setattr__(attr, val)
48534887

4888+
@mypyc_attr(native_class=False)
4889+
class NoSetAttrNonNative:
4890+
def __init__(self, attr: int) -> None:
4891+
self.attr = attr
4892+
4893+
def object_setattr(self, attr: str, val: object) -> None:
4894+
object.__setattr__(self, attr, val)
4895+
4896+
def super_setattr(self, attr: str, val: object) -> None:
4897+
super().__setattr__(attr, val)
4898+
4899+
def __getattr__(self, attr: str) -> object:
4900+
pass
4901+
48544902
[file driver.py]
4855-
from native import SetAttr, SetAttrInherited, SetAttrOverridden, SetAttrNonNative, NoSetAttr
4903+
from native import SetAttr, SetAttrInherited, SetAttrOverridden, SetAttrNonNative, NoSetAttr, NoSetAttrNonNative
48564904
from testutil import assertRaises
48574905

48584906
def test_setattr() -> None:
@@ -5029,10 +5077,31 @@ def test_no_setattr() -> None:
50295077
with assertRaises(AttributeError):
50305078
object.__setattr__(i, "not_attr", 102)
50315079

5080+
def test_no_setattr_nonnative() -> None:
5081+
i = NoSetAttrNonNative(99)
5082+
i.super_setattr("attr", 100)
5083+
assert i.attr == 100
5084+
5085+
i.object_setattr("attr", 101)
5086+
assert i.attr == 101
5087+
5088+
object.__setattr__(i, "attr", 102)
5089+
assert i.attr == 102
5090+
5091+
i.super_setattr("one", 100)
5092+
assert i.one == 100
5093+
5094+
i.object_setattr("two", 101)
5095+
assert i.two == 101
5096+
5097+
object.__setattr__(i, "three", 102)
5098+
assert i.three == 102
5099+
50325100
test_setattr()
50335101
test_setattr_inherited()
50345102
test_setattr_overridden()
50355103
test_setattr_nonnative()
50365104
test_no_setattr()
5105+
test_no_setattr_nonnative()
50375106

50385107
[typing fixtures/typing-full.pyi]

0 commit comments

Comments
 (0)