6363import com .oracle .graal .python .builtins .objects .type .slots .TpSlot .TpSlotPython ;
6464import com .oracle .graal .python .nodes .PGuards ;
6565import com .oracle .graal .python .nodes .attributes .LookupAttributeInMRONode .Dynamic ;
66+ import com .oracle .graal .python .nodes .call .special .CallBinaryMethodNode ;
67+ import com .oracle .graal .python .nodes .call .special .MaybeBindDescriptorNode ;
6668import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
6769import com .oracle .graal .python .nodes .object .BuiltinClassProfiles .IsBuiltinObjectProfile ;
6870import com .oracle .graal .python .runtime .ExecutionContext .CallContext ;
@@ -297,6 +299,8 @@ static Object callPythonSimple(VirtualFrame frame, Node inliningTarget, TpSlotGe
297299
298300 @ Specialization (guards = "slot.hasGetattr()" )
299301 static Object callPythonSimple (VirtualFrame frame , Node inliningTarget , TpSlotGetAttrPython slot , Object self , Object name ,
302+ @ Cached MaybeBindDescriptorNode bindDescriptorNode ,
303+ @ Cached CallBinaryMethodNode callGetAttributeNode ,
300304 @ Exclusive @ Cached BinaryPythonSlotDispatcherNode callPythonFun ,
301305 @ Cached IsBuiltinObjectProfile errorProfile ) {
302306 // equivalent of slot_tp_getattr_hook
@@ -309,7 +313,13 @@ static Object callPythonSimple(VirtualFrame frame, Node inliningTarget, TpSlotGe
309313 // TODO: CPython calls PyObject_GenericGetAttr if there is no __getattribute__. Can
310314 // we create a type that does not inherit tp_getattro and so no __getattribute__ is
311315 // created for it in add_operators?
312- return callPythonFun .execute (frame , inliningTarget , slot .getGetattribute (), type , self , name );
316+
317+ // NOTE: we use CallBinaryMethodNode, because it is common that the __getattribute__
318+ // callable is PBuiltinFunction wrapper is wrapping raw tp_getattro slot. This
319+ // happens if a Python class declares __getattr__ and inherits __getattribute__
320+ // wrapping some builtin slot.
321+ Object bound = bindDescriptorNode .execute (frame , inliningTarget , slot .getGetattribute (), self , type );
322+ return callGetAttributeNode .executeObject (frame , bound , self , name );
313323 } catch (PException pe ) {
314324 pe .expect (inliningTarget , AttributeError , errorProfile );
315325 if (getattr == null ) {
0 commit comments