@@ -314,15 +314,6 @@ managed_static_type_state_clear(PyInterpreterState *interp, PyTypeObject *self,
314
314
}
315
315
}
316
316
317
- static PyTypeObject *
318
- managed_static_type_get_def (PyTypeObject * self , int isbuiltin )
319
- {
320
- size_t index = managed_static_type_index_get (self );
321
- size_t full_index = isbuiltin
322
- ? index
323
- : index + _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES ;
324
- return & _PyRuntime .types .managed_static .types [full_index ].def ;
325
- }
326
317
327
318
328
319
PyObject *
@@ -5927,6 +5918,7 @@ fini_static_type(PyInterpreterState *interp, PyTypeObject *type,
5927
5918
5928
5919
_PyStaticType_ClearWeakRefs (interp , type );
5929
5920
managed_static_type_state_clear (interp , type , isbuiltin , final );
5921
+ /* We leave _Py_TPFLAGS_STATIC_BUILTIN set on tp_flags. */
5930
5922
}
5931
5923
5932
5924
void
@@ -7939,7 +7931,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
7939
7931
return 0 ;
7940
7932
}
7941
7933
7942
- static int add_operators (PyTypeObject * , PyTypeObject * );
7934
+ static int add_operators (PyTypeObject * type );
7943
7935
static int add_tp_new_wrapper (PyTypeObject * type );
7944
7936
7945
7937
#define COLLECTION_FLAGS (Py_TPFLAGS_SEQUENCE | Py_TPFLAGS_MAPPING)
@@ -8104,10 +8096,10 @@ type_dict_set_doc(PyTypeObject *type)
8104
8096
8105
8097
8106
8098
static int
8107
- type_ready_fill_dict (PyTypeObject * type , PyTypeObject * def )
8099
+ type_ready_fill_dict (PyTypeObject * type )
8108
8100
{
8109
8101
/* Add type-specific descriptors to tp_dict */
8110
- if (add_operators (type , def ) < 0 ) {
8102
+ if (add_operators (type ) < 0 ) {
8111
8103
return -1 ;
8112
8104
}
8113
8105
if (type_add_methods (type ) < 0 ) {
@@ -8426,7 +8418,7 @@ type_ready_post_checks(PyTypeObject *type)
8426
8418
8427
8419
8428
8420
static int
8429
- type_ready (PyTypeObject * type , PyTypeObject * def , int initial )
8421
+ type_ready (PyTypeObject * type , int initial )
8430
8422
{
8431
8423
ASSERT_TYPE_LOCK_HELD ();
8432
8424
@@ -8465,7 +8457,7 @@ type_ready(PyTypeObject *type, PyTypeObject *def, int initial)
8465
8457
if (type_ready_set_new (type , initial ) < 0 ) {
8466
8458
goto error ;
8467
8459
}
8468
- if (type_ready_fill_dict (type , def ) < 0 ) {
8460
+ if (type_ready_fill_dict (type ) < 0 ) {
8469
8461
goto error ;
8470
8462
}
8471
8463
if (initial ) {
@@ -8522,7 +8514,7 @@ PyType_Ready(PyTypeObject *type)
8522
8514
int res ;
8523
8515
BEGIN_TYPE_LOCK ();
8524
8516
if (!(type -> tp_flags & Py_TPFLAGS_READY )) {
8525
- res = type_ready (type , NULL , 1 );
8517
+ res = type_ready (type , 1 );
8526
8518
} else {
8527
8519
res = 0 ;
8528
8520
assert (_PyType_CheckConsistency (type ));
@@ -8558,20 +8550,14 @@ init_static_type(PyInterpreterState *interp, PyTypeObject *self,
8558
8550
8559
8551
managed_static_type_state_init (interp , self , isbuiltin , initial );
8560
8552
8561
- PyTypeObject * def = managed_static_type_get_def (self , isbuiltin );
8562
- if (initial ) {
8563
- memcpy (def , self , sizeof (PyTypeObject ));
8564
- }
8565
-
8566
8553
int res ;
8567
8554
BEGIN_TYPE_LOCK ();
8568
- res = type_ready (self , def , initial );
8555
+ res = type_ready (self , initial );
8569
8556
END_TYPE_LOCK ();
8570
8557
if (res < 0 ) {
8571
8558
_PyStaticType_ClearWeakRefs (interp , self );
8572
8559
managed_static_type_state_clear (interp , self , isbuiltin , initial );
8573
8560
}
8574
-
8575
8561
return res ;
8576
8562
}
8577
8563
@@ -11182,6 +11168,26 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name,
11182
11168
return 0 ;
11183
11169
}
11184
11170
11171
+ static int
11172
+ slot_inherited (PyTypeObject * type , pytype_slotdef * slotdef , void * * slot )
11173
+ {
11174
+ void * * slot_base = slotptr (type -> tp_base , slotdef -> offset );
11175
+ if (slot_base == NULL || * slot != * slot_base ) {
11176
+ return 0 ;
11177
+ }
11178
+
11179
+ /* Some slots are inherited in pairs. */
11180
+ if (slot == (void * )& type -> tp_hash ) {
11181
+ return (type -> tp_richcompare == type -> tp_base -> tp_richcompare );
11182
+ }
11183
+ else if (slot == (void * )& type -> tp_richcompare ) {
11184
+ return (type -> tp_hash == type -> tp_base -> tp_hash );
11185
+ }
11186
+
11187
+ /* It must be inherited (see type_ready_inherit()). */
11188
+ return 1 ;
11189
+ }
11190
+
11185
11191
/* This function is called by PyType_Ready() to populate the type's
11186
11192
dictionary with method descriptors for function slots. For each
11187
11193
function slot (like tp_repr) that's defined in the type, one or more
@@ -11213,24 +11219,26 @@ recurse_down_subclasses(PyTypeObject *type, PyObject *attr_name,
11213
11219
infinite recursion here.) */
11214
11220
11215
11221
static int
11216
- add_operators (PyTypeObject * type , PyTypeObject * def )
11222
+ add_operators (PyTypeObject * type )
11217
11223
{
11218
11224
PyObject * dict = lookup_tp_dict (type );
11219
11225
pytype_slotdef * p ;
11220
11226
PyObject * descr ;
11221
11227
void * * ptr ;
11222
11228
11223
- assert (def == NULL || (type -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ));
11224
- if (def == NULL ) {
11225
- def = type ;
11226
- }
11227
-
11228
11229
for (p = slotdefs ; p -> name ; p ++ ) {
11229
11230
if (p -> wrapper == NULL )
11230
11231
continue ;
11231
- ptr = slotptr (def , p -> offset );
11232
+ ptr = slotptr (type , p -> offset );
11232
11233
if (!ptr || !* ptr )
11233
11234
continue ;
11235
+ /* Also ignore when the type slot has been inherited. */
11236
+ if (type -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN
11237
+ && type -> tp_base != NULL
11238
+ && slot_inherited (type , p , ptr ))
11239
+ {
11240
+ continue ;
11241
+ }
11234
11242
int r = PyDict_Contains (dict , p -> name_strobj );
11235
11243
if (r > 0 )
11236
11244
continue ;
0 commit comments