@@ -174,15 +174,16 @@ static final Object doBuiltinModule(VirtualFrame frame, Object object, String na
174
174
}
175
175
}
176
176
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.
180
181
@ SuppressWarnings ("unused" )
181
182
@ Specialization (guards = {"isTypeGetAttribute(type)" , "isBuiltinTypeType(type)" , "!isTypeSlot(name)" }, limit = "1" )
182
183
static final Object doBuiltinTypeType (VirtualFrame frame , Object object , String name ,
183
184
@ Cached GetClassNode getClass ,
184
185
@ Bind ("getClass.execute(object)" ) Object type ,
185
- @ Cached ReadAttributeFromObjectNode readNode ,
186
+ @ Cached LookupAttributeInMRONode . Dynamic readNode ,
186
187
@ Cached ConditionProfile valueFound ,
187
188
@ Cached ("create(Get)" ) LookupInheritedSlotNode lookupValueGet ,
188
189
@ Cached ConditionProfile noGetMethod ,
@@ -205,24 +206,24 @@ static final Object doBuiltinTypeType(VirtualFrame frame, Object object, String
205
206
return PNone .NO_VALUE ;
206
207
}
207
208
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.
211
212
@ 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 " )
213
214
static final Object doBuiltinType (VirtualFrame frame , Object object , String name ,
214
215
@ Cached ("name" ) String cachedName ,
215
216
@ Cached GetClassNode getClass ,
216
217
@ 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 ,
220
221
@ Cached ConditionProfile valueFound ,
221
222
@ Cached ("create(Get)" ) LookupInheritedSlotNode lookupValueGet ,
222
223
@ Cached ConditionProfile noGetMethod ,
223
224
@ Cached CallTernaryMethodNode invokeValueGet ,
224
225
@ Shared ("errorProfile" ) @ Cached IsBuiltinClassProfile errorProfile ) {
225
- Object value = readNode .execute (object , cachedName );
226
+ Object value = readNode .execute (object );
226
227
if (valueFound .profile (value != PNone .NO_VALUE )) {
227
228
Object valueGet = lookupValueGet .execute (value );
228
229
if (noGetMethod .profile (valueGet == PNone .NO_VALUE )) {
0 commit comments