@@ -5238,17 +5238,10 @@ _PyType_GetModuleByDef2(PyTypeObject *left, PyTypeObject *right,
5238
5238
5239
5239
5240
5240
static PyTypeObject *
5241
- get_base_by_token_recursive (PyTypeObject * type , void * token , int initial )
5241
+ get_base_by_token_recursive (PyTypeObject * type , void * token )
5242
5242
{
5243
- if (initial ) {
5244
- if (!_PyType_HasFeature (type , Py_TPFLAGS_HEAPTYPE )) {
5245
- return NULL ;
5246
- }
5247
- if (((PyHeapTypeObject * )type )-> ht_token == token ) {
5248
- return type ;
5249
- }
5250
- }
5251
5243
PyObject * bases = type -> tp_bases ;
5244
+ assert (bases != NULL );
5252
5245
Py_ssize_t n = PyTuple_GET_SIZE (bases );
5253
5246
for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
5254
5247
PyTypeObject * base = (PyTypeObject * )PyTuple_GET_ITEM (bases , i );
@@ -5258,17 +5251,25 @@ get_base_by_token_recursive(PyTypeObject *type, void *token, int initial)
5258
5251
if (((PyHeapTypeObject * )base )-> ht_token == token ) {
5259
5252
return base ;
5260
5253
}
5261
- base = get_base_by_token_recursive (base , token , 0 );
5254
+ base = get_base_by_token_recursive (base , token );
5262
5255
if (base ) {
5263
5256
return base ;
5264
5257
}
5265
5258
}
5266
5259
return NULL ;
5267
5260
}
5268
5261
5262
+ static inline int
5263
+ _token_found (PyTypeObject * type , PyTypeObject * * result )
5264
+ {
5265
+ if (result != NULL ) {
5266
+ * result = (PyTypeObject * )Py_NewRef (type );
5267
+ }
5268
+ return 1 ;
5269
+ }
5270
+
5269
5271
int
5270
- PyType_GetBaseByToken (PyTypeObject * type , void * token ,
5271
- PyTypeObject * * result )
5272
+ PyType_GetBaseByToken (PyTypeObject * type , void * token , PyTypeObject * * result )
5272
5273
{
5273
5274
if (result != NULL ) {
5274
5275
* result = NULL ;
@@ -5278,35 +5279,33 @@ PyType_GetBaseByToken(PyTypeObject *type, void *token,
5278
5279
return 0 ;
5279
5280
}
5280
5281
assert (PyType_Check (type ));
5282
+ if (!_PyType_HasFeature (type , Py_TPFLAGS_HEAPTYPE )) {
5283
+ // Static type MRO contains no heap type,
5284
+ // which type_ready_mro() ensures.
5285
+ return 0 ;
5286
+ }
5287
+ if (((PyHeapTypeObject * )type )-> ht_token == token ) {
5288
+ return _token_found (type , result );
5289
+ }
5281
5290
PyObject * mro = type -> tp_mro ;
5282
5291
if (mro == NULL ) {
5283
- PyTypeObject * base = get_base_by_token_recursive (type , token , 1 );
5284
- if (base == NULL ) {
5285
- return 0 ;
5286
- }
5287
- if (result != NULL ) {
5288
- * result = (PyTypeObject * )Py_NewRef (base );
5289
- }
5290
- return 1 ;
5292
+ PyTypeObject * base = get_base_by_token_recursive (type , token , result );
5293
+ return base ? _token_found (base , result ) : 0 ;
5291
5294
}
5292
5295
assert (PyTuple_Check (mro ));
5296
+ // mro_invoke() ensures that the type MRO cannot be empty.
5297
+ assert (PyTuple_GET_SIZE (mro ) >= 1 );
5298
+ // Also, the first item in the MRO is the type itself, which
5299
+ // we already checked above. We skip it in the loop.
5300
+ assert (PyTuple_GET_ITEM (mro , 0 ) == (PyObject * )type );
5293
5301
Py_ssize_t n = PyTuple_GET_SIZE (mro );
5294
- for (Py_ssize_t i = 0 ; i < n ; i ++ ) {
5302
+ for (Py_ssize_t i = 1 ; i < n ; i ++ ) {
5295
5303
PyTypeObject * base = _PyType_CAST (PyTuple_GET_ITEM (mro , i ));
5296
5304
if (!_PyType_HasFeature (base , Py_TPFLAGS_HEAPTYPE )) {
5297
- if (i ) {
5298
- continue ;
5299
- }
5300
- // Static type MRO contains no heap type,
5301
- // which type_ready_mro() ensures.
5302
- assert (base == type );
5303
- return 0 ;
5305
+ continue ;
5304
5306
}
5305
5307
if (((PyHeapTypeObject * )base )-> ht_token == token ) {
5306
- if (result != NULL ) {
5307
- * result = (PyTypeObject * )Py_NewRef (base );
5308
- }
5309
- return 1 ;
5308
+ return _token_found (base , result );
5310
5309
}
5311
5310
}
5312
5311
return 0 ;
0 commit comments