@@ -174,15 +174,16 @@ static final Object doBuiltinModule(VirtualFrame frame, Object object, String na
174174 }
175175 }
176176
177- // simple version that needs no calls and only reads from the object directly. the only
178- // difference for type.__getattribute__ over object.__getattribute__ is that it looks for a
179- // __get__ method on the value and invokes it if it is callable.
177+ // If the class of an object is "type", the object must be a class and as "type" is the base
178+ // metaclass, which defines only certain type slots, it can not have inherited other
179+ // attributes via metaclass inheritance. For all non-type-slot attributes it therefore
180+ // suffices to only check for inheritance via super classes.
180181 @ SuppressWarnings ("unused" )
181182 @ Specialization (guards = {"isTypeGetAttribute(type)" , "isBuiltinTypeType(type)" , "!isTypeSlot(name)" }, limit = "1" )
182183 static final Object doBuiltinTypeType (VirtualFrame frame , Object object , String name ,
183184 @ Cached GetClassNode getClass ,
184185 @ Bind ("getClass.execute(object)" ) Object type ,
185- @ Cached ReadAttributeFromObjectNode readNode ,
186+ @ Cached LookupAttributeInMRONode . Dynamic readNode ,
186187 @ Cached ConditionProfile valueFound ,
187188 @ Cached ("create(Get)" ) LookupInheritedSlotNode lookupValueGet ,
188189 @ Cached ConditionProfile noGetMethod ,
@@ -205,24 +206,24 @@ static final Object doBuiltinTypeType(VirtualFrame frame, Object object, String
205206 return PNone .NO_VALUE ;
206207 }
207208
208- // simple version that needs no calls and only reads from the object directly. the only
209- // difference for type.__getattribute__ over object.__getattribute__ is that it looks for a
210- // __get__ method on the value and invokes it if it is callable.
209+ // simple version that only reads attributes from (super) class inheritance and the object
210+ // itself. the only difference for type.__getattribute__ over object.__getattribute__
211+ // is that it looks for a __get__ method on the value and invokes it if it is callable.
211212 @ SuppressWarnings ("unused" )
212- @ Specialization (guards = {"isTypeGetAttribute(type)" , "hasNoGetAttr(type)" , "name == cachedName" , "isNoValue(descr )" }, limit = "1 " , replaces = "doBuiltinTypeType " )
213+ @ Specialization (guards = {"isTypeGetAttribute(type)" , "hasNoGetAttr(type)" , "name == cachedName" , "isNoValue(metaClassDescr )" }, replaces = "doBuiltinTypeType " , limit = "1 " )
213214 static final Object doBuiltinType (VirtualFrame frame , Object object , String name ,
214215 @ Cached ("name" ) String cachedName ,
215216 @ Cached GetClassNode getClass ,
216217 @ Bind ("getClass.execute(object)" ) Object type ,
217- @ Cached ("create(name)" ) LookupAttributeInMRONode lookupName ,
218- @ Bind ("lookupName .execute(type)" ) Object descr ,
219- @ Cached ReadAttributeFromObjectNode readNode ,
218+ @ Cached ("create(name)" ) LookupAttributeInMRONode lookupInMetaclassHierachy ,
219+ @ Bind ("lookupInMetaclassHierachy .execute(type)" ) Object metaClassDescr ,
220+ @ Cached ( "create(name)" ) LookupAttributeInMRONode readNode ,
220221 @ Cached ConditionProfile valueFound ,
221222 @ Cached ("create(Get)" ) LookupInheritedSlotNode lookupValueGet ,
222223 @ Cached ConditionProfile noGetMethod ,
223224 @ Cached CallTernaryMethodNode invokeValueGet ,
224225 @ Shared ("errorProfile" ) @ Cached IsBuiltinClassProfile errorProfile ) {
225- Object value = readNode .execute (object , cachedName );
226+ Object value = readNode .execute (object );
226227 if (valueFound .profile (value != PNone .NO_VALUE )) {
227228 Object valueGet = lookupValueGet .execute (value );
228229 if (noGetMethod .profile (valueGet == PNone .NO_VALUE )) {
0 commit comments