@@ -6604,34 +6604,11 @@ compatible_for_assignment(PyTypeObject* oldto, PyTypeObject* newto, const char*
66046604 return 0 ;
66056605}
66066606
6607- static int
6608- object_set_class (PyObject * self , PyObject * value , void * closure )
6609- {
6610-
6611- if (value == NULL ) {
6612- PyErr_SetString (PyExc_TypeError ,
6613- "can't delete __class__ attribute" );
6614- return -1 ;
6615- }
6616- if (!PyType_Check (value )) {
6617- PyErr_Format (PyExc_TypeError ,
6618- "__class__ must be set to a class, not '%s' object" ,
6619- Py_TYPE (value )-> tp_name );
6620- return -1 ;
6621- }
6622- PyTypeObject * newto = (PyTypeObject * )value ;
66236607
6624- if (PySys_Audit ("object.__setattr__" , "OsO" ,
6625- self , "__class__" , value ) < 0 ) {
6626- return -1 ;
6627- }
66286608
6629- #ifdef Py_GIL_DISABLED
6630- PyInterpreterState * interp = _PyInterpreterState_GET ();
6631- // The real Py_TYPE(self) (`oldto`) may have changed from
6632- // underneath us in another thread, so we stop the world.
6633- _PyEval_StopTheWorld (interp );
6634- #endif
6609+ static int
6610+ object_set_class_no_world_stopped (PyObject * self , PyTypeObject * newto , PyTypeObject * * oldto_p )
6611+ {
66356612 PyTypeObject * oldto = Py_TYPE (self );
66366613
66376614 /* In versions of CPython prior to 3.5, the code in
@@ -6690,7 +6667,7 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
66906667 PyErr_Format (PyExc_TypeError ,
66916668 "__class__ assignment only supported for mutable types "
66926669 "or ModuleType subclasses" );
6693- goto err ;
6670+ return -1 ;
66946671 }
66956672
66966673 if (compatible_for_assignment (oldto , newto , "__class__" )) {
@@ -6699,9 +6676,9 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
66996676 if (oldto -> tp_flags & Py_TPFLAGS_INLINE_VALUES ) {
67006677 PyDictObject * dict = _PyObject_GetManagedDict (self );
67016678 if (dict == NULL ) {
6702- dict = _PyObject_materialize_managed_dict_lock_held (self );
6679+ dict = _PyObject_MaterializeManagedDict_LockHeld (self );
67036680 if (dict == NULL ) {
6704- goto err ;
6681+ return -1 ;
67056682 }
67066683 }
67076684
@@ -6714,35 +6691,67 @@ object_set_class(PyObject *self, PyObject *value, void *closure)
67146691 dict -> ma_values != _PyObject_InlineValues (self ));
67156692
67166693 if (_PyDict_DetachFromObject (dict , self ) < 0 ) {
6717- goto err ;
6694+ return -1 ;
67186695 }
67196696
67206697 }
67216698 if (newto -> tp_flags & Py_TPFLAGS_HEAPTYPE ) {
67226699 Py_INCREF (newto );
67236700 }
67246701
6725- #ifdef Py_GIL_DISABLED
6726- _PyEval_StartTheWorld (interp );
6727- #endif
67286702 Py_SET_TYPE (self , newto );
67296703
6730- if (oldto -> tp_flags & Py_TPFLAGS_HEAPTYPE ) {
6731- Py_DECREF (oldto );
6732- }
6733-
6734- RARE_EVENT_INC (set_class );
6704+ * oldto_p = oldto ;
67356705
67366706 return 0 ;
67376707 }
67386708 else {
6739- goto err ;
6709+ return -1 ;
67406710 }
6741- err :
6711+ }
6712+
6713+ static int
6714+ object_set_class (PyObject * self , PyObject * value , void * closure )
6715+ {
6716+
6717+ if (value == NULL ) {
6718+ PyErr_SetString (PyExc_TypeError ,
6719+ "can't delete __class__ attribute" );
6720+ return -1 ;
6721+ }
6722+ if (!PyType_Check (value )) {
6723+ PyErr_Format (PyExc_TypeError ,
6724+ "__class__ must be set to a class, not '%s' object" ,
6725+ Py_TYPE (value )-> tp_name );
6726+ return -1 ;
6727+ }
6728+ PyTypeObject * newto = (PyTypeObject * )value ;
6729+
6730+ if (PySys_Audit ("object.__setattr__" , "OsO" ,
6731+ self , "__class__" , value ) < 0 ) {
6732+ return -1 ;
6733+ }
6734+
6735+ #ifdef Py_GIL_DISABLED
6736+ PyInterpreterState * interp = _PyInterpreterState_GET ();
6737+ // The real Py_TYPE(self) (`oldto`) may have changed from
6738+ // underneath us in another thread, so we stop the world.
6739+ _PyEval_StopTheWorld (interp );
6740+ #endif
6741+ PyTypeObject * oldto ;
6742+ int res = object_set_class_no_world_stopped (self , newto , & oldto );
67426743#ifdef Py_GIL_DISABLED
67436744 _PyEval_StartTheWorld (interp );
67446745#endif
6745- return -1 ;
6746+ if (res == 0 ) {
6747+ if (oldto -> tp_flags & Py_TPFLAGS_HEAPTYPE ) {
6748+ Py_DECREF (oldto );
6749+ }
6750+
6751+ RARE_EVENT_INC (set_class );
6752+ return 0 ;
6753+ }
6754+ return res ;
67466755}
67476756
67486757static PyGetSetDef object_getsets [] = {
0 commit comments