@@ -597,15 +597,15 @@ set_tp_bases(PyTypeObject *self, PyObject *bases)
597597// and 0 otherwise.
598598static int
599599try_set_tp_bases (PyTypeObject * self , PyObject * expected ,
600- PyObject * bases , PyTypeObject * base , uint64_t * gen )
600+ PyObject * bases , PyTypeObject * base , uint64_t gen , bool check_gen )
601601{
602602 ASSERT_TYPE_LOCK_HELD ();
603603 assert (PyTuple_Check (bases ));
604604 assert (!(self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ));
605605 int stored = 0 ;
606606 types_stop_world ();
607607 if ((expected == NULL || self -> tp_bases == expected )
608- && (gen == NULL || !types_publish_is_stale (* gen )))
608+ && (! check_gen || !types_publish_is_stale (gen )))
609609 {
610610 self -> tp_bases = bases ;
611611 self -> tp_base = base ;
@@ -668,7 +668,7 @@ set_tp_mro(PyTypeObject *self, PyObject *mro)
668668// cases the caller still owns 'mro'.
669669static int
670670try_set_tp_mro (PyTypeObject * self , PyObject * expected , PyObject * mro ,
671- uint64_t * gen )
671+ uint64_t gen , bool check_gen )
672672{
673673 ASSERT_TYPE_LOCK_HELD ();
674674 assert (!(self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ));
@@ -681,7 +681,7 @@ try_set_tp_mro(PyTypeObject *self, PyObject *expected, PyObject *mro,
681681 if (self -> tp_mro != expected ) {
682682 res = 0 ;
683683 }
684- else if (gen != NULL && types_publish_is_stale (* gen )) {
684+ else if (check_gen && types_publish_is_stale (gen )) {
685685 res = -1 ;
686686 }
687687 else {
@@ -1811,7 +1811,7 @@ mro_hierarchy_for_complete_type(PyTypeObject *type, PyObject *temp)
18111811
18121812 if (res < 0 ) {
18131813 // Roll back, unless tp_mro has already been replaced again.
1814- if (try_set_tp_mro (type , new_mro , old_mro , NULL ) == 1 ) {
1814+ if (try_set_tp_mro (type , new_mro , old_mro , 0 , false ) == 1 ) {
18151815 Py_DECREF (new_mro );
18161816 }
18171817 else {
@@ -1946,7 +1946,7 @@ type_set_bases_unlocked(PyTypeObject *type, PyObject *new_bases,
19461946 PyTypeObject * old_base = type -> tp_base ;
19471947
19481948 if (!try_set_tp_bases (type , NULL , Py_NewRef (new_bases ),
1949- (PyTypeObject * )Py_NewRef (best_base ), & gen ))
1949+ (PyTypeObject * )Py_NewRef (best_base ), gen , true ))
19501950 {
19511951 Py_DECREF (new_bases );
19521952 Py_DECREF (best_base );
@@ -2022,7 +2022,7 @@ type_set_bases_unlocked(PyTypeObject *type, PyObject *new_bases,
20222022 "" , 2 , 3 , & cls , & new_mro , & old_mro );
20232023 /* Do not rollback if cls has a newer version of MRO. */
20242024 old_mro = Py_XNewRef (old_mro );
2025- if (try_set_tp_mro (cls , new_mro , old_mro , NULL ) == 1 ) {
2025+ if (try_set_tp_mro (cls , new_mro , old_mro , 0 , false ) == 1 ) {
20262026 Py_DECREF (new_mro );
20272027 }
20282028 else {
@@ -2033,7 +2033,7 @@ type_set_bases_unlocked(PyTypeObject *type, PyObject *new_bases,
20332033
20342034 bail :
20352035 /* Restore the old bases, unless tp_bases has been replaced again. */
2036- if (try_set_tp_bases (type , new_bases , old_bases , old_base , NULL )) {
2036+ if (try_set_tp_bases (type , new_bases , old_bases , old_base , 0 , false )) {
20372037 Py_DECREF (new_bases );
20382038 Py_DECREF (best_base );
20392039 }
@@ -3723,7 +3723,7 @@ mro_internal(PyTypeObject *type, int initial, PyObject **p_old_mro)
37233723 // released while mro_invoke() ran or while waiting to stop the
37243724 // world, so check for reentrance and for concurrent mutation of
37253725 // the hierarchy inside the stop-the-world.
3726- res = try_set_tp_mro (type , old_mro , new_mro , & gen );
3726+ res = try_set_tp_mro (type , old_mro , new_mro , gen , true );
37273727 }
37283728 if (res == 1 ) {
37293729 break ;
0 commit comments