Skip to content

Commit 590af47

Browse files
committed
Fix __getattr__ handling in uncached path
1 parent ff37ad0 commit 590af47

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetAttr.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,12 @@ static Object getDynamicAttr(Frame frame, Object receiver, Object name,
8989
Object result = PyObjectLookupAttr.readAttributeQuickly(type, getattribute, receiver, name);
9090
if (result != null) {
9191
if (result == PNone.NO_VALUE) {
92-
throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name);
92+
Object getattr = lookupGetattr.execute(frame, type, receiver);
93+
if (getattr != PNone.NO_VALUE) {
94+
return callGetattr.executeObject(frame, getattr, receiver, name);
95+
} else {
96+
throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.AttributeError, ErrorMessages.OBJ_P_HAS_NO_ATTR_S, receiver, name);
97+
}
9398
}
9499
return result;
95100
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectLookupAttr.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,14 @@ static Object getDynamicAttr(Frame frame, Object receiver, Object name,
254254
// It pays to try this in the uncached case, avoiding a full call to __getattribute__
255255
Object result = readAttributeQuickly(type, getattribute, receiver, name);
256256
if (result != null) {
257-
return result;
257+
if (result == PNone.NO_VALUE) {
258+
Object getattr = lookupGetattr.execute(frame, type, receiver);
259+
if (getattr != PNone.NO_VALUE) {
260+
return callGetattr.executeObject(frame, getattr, receiver, name);
261+
} else {
262+
return null;
263+
}
264+
}
258265
}
259266
}
260267
try {
@@ -296,7 +303,8 @@ public static PyObjectLookupAttr getUncached() {
296303
* ModuleBuiltins.GetAttributeNode}. This method returns {@code PNone.NO_VALUE} when the
297304
* attribute is not found and the original would've raised an AttributeError. It returns {@code
298305
* null} when no shortcut was applicable. If {@code PNone.NO_VALUE} was returned, name is
299-
* guaranteed to be a {@code java.lang.String}.
306+
* guaranteed to be a {@code java.lang.String}. Note it is often necessary to call
307+
* {@code __getattr__} if this returns {@code PNone.NO_VALUE}.
300308
*/
301309
static final Object readAttributeQuickly(Object type, Object getattribute, Object receiver, Object name) {
302310
if (name instanceof String) {

0 commit comments

Comments
 (0)