Skip to content

Commit dc865f9

Browse files
committed
[GR-29185] Use LookupAttributeInMRO in LookupAndCallTernaryNode.
PullRequest: graalpython/1588
2 parents 4ad1843 + 549f12b commit dc865f9

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_setattr.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,18 @@ def m(self):
5555
assert_raises(TypeError, object.__setattr__, M('m'), type, 42)
5656
assert_raises(TypeError, types.ModuleType.__setattr__, M('m'), type, 42)
5757
assert_raises(TypeError, types.MethodType.__setattr__, M('m').m, type, 42)
58+
59+
60+
def test_overriding_via_getattribute_should_not_work():
61+
class MyMeta(type):
62+
def __getattribute__(self, item):
63+
if item == '__setattr__':
64+
return lambda self, key, value: None
65+
return super(MyMeta, self).__getattribute__(item)
66+
67+
class Cls(metaclass=MyMeta):
68+
pass
69+
70+
x = Cls()
71+
x.bar = 42 # should not call __getattribute__ to get __setattr__
72+
assert x.bar == 42

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/special/LookupAndCallTernaryNode.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,26 @@
4242

4343
import com.oracle.graal.python.builtins.objects.PNone;
4444
import com.oracle.graal.python.builtins.objects.PNotImplemented;
45+
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
4546
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
4647
import com.oracle.graal.python.nodes.PNodeWithContext;
4748
import com.oracle.graal.python.nodes.SpecialMethodNames;
4849
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
4950
import com.oracle.graal.python.nodes.object.GetClassNode;
51+
import com.oracle.graal.python.runtime.PythonOptions;
5052
import com.oracle.graal.python.util.Supplier;
5153
import com.oracle.truffle.api.CompilerDirectives;
5254
import com.oracle.truffle.api.dsl.Cached;
5355
import com.oracle.truffle.api.dsl.ImportStatic;
5456
import com.oracle.truffle.api.dsl.Specialization;
5557
import com.oracle.truffle.api.frame.VirtualFrame;
58+
import com.oracle.truffle.api.library.CachedLibrary;
5659
import com.oracle.truffle.api.nodes.Node;
5760
import com.oracle.truffle.api.profiles.BranchProfile;
5861

5962
// cpython://Objects/abstract.c#ternary_op
6063
// Order operations are tried until either a valid result or error: v.op(v,w,z), w.op(v,w,z), z.op(v,w,z)
61-
@ImportStatic({SpecialMethodNames.class})
64+
@ImportStatic({SpecialMethodNames.class, PythonOptions.class})
6265
public abstract class LookupAndCallTernaryNode extends Node {
6366
public abstract static class NotImplementedHandler extends PNodeWithContext {
6467
public abstract Object execute(Object arg, Object arg2, Object arg3);
@@ -100,26 +103,30 @@ protected boolean isReversible() {
100103
return isReversible;
101104
}
102105

103-
@Specialization(guards = "!isReversible()")
106+
@Specialization(guards = "!isReversible()", limit = "getCallSiteInlineCacheMaxDepth()")
104107
Object callObject(
105108
VirtualFrame frame,
106109
Object arg1,
107110
int arg2,
108111
Object arg3,
109-
@Cached("create()") GetClassNode getclass,
110-
@Cached("create(__GETATTRIBUTE__)") LookupAndCallBinaryNode getattr) {
111-
return dispatchNode.execute(frame, getattr.executeObject(frame, getclass.execute(arg1), name), arg1, arg2, arg3);
112+
@CachedLibrary("arg1") PythonObjectLibrary libArg1,
113+
@Cached("create(name, ignoreDescriptorException)") LookupSpecialMethodNode getattr) {
114+
Object klass = libArg1.getLazyPythonClass(arg1);
115+
Object value = libArg1.getDelegatedValue(arg1);
116+
return dispatchNode.execute(frame, getattr.execute(frame, klass, value), value, arg2, arg3);
112117
}
113118

114-
@Specialization(guards = "!isReversible()")
119+
@Specialization(guards = "!isReversible()", limit = "getCallSiteInlineCacheMaxDepth()")
115120
Object callObject(
116121
VirtualFrame frame,
117122
Object arg1,
118123
Object arg2,
119124
Object arg3,
120-
@Cached("create()") GetClassNode getclass,
121-
@Cached("create(__GETATTRIBUTE__)") LookupAndCallBinaryNode getattr) {
122-
return dispatchNode.execute(frame, getattr.executeObject(frame, getclass.execute(arg1), name), arg1, arg2, arg3);
125+
@CachedLibrary("arg1") PythonObjectLibrary libArg1,
126+
@Cached("create(name, ignoreDescriptorException)") LookupSpecialMethodNode getattr) {
127+
Object klass = libArg1.getLazyPythonClass(arg1);
128+
Object value = libArg1.getDelegatedValue(arg1);
129+
return dispatchNode.execute(frame, getattr.execute(frame, klass, value), value, arg2, arg3);
123130
}
124131

125132
private CallTernaryMethodNode ensureReverseDispatch() {

0 commit comments

Comments
 (0)