From 20438820ffa359d2e7b8fbd5cfd8f30329314bc1 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Fri, 6 Mar 2026 14:35:00 -0500 Subject: [PATCH] [3.14] gh-145566: Skip stop-the-world when reassigning `__class__` on newly created objects (gh-145567) (#145605) Co-authored-by: Sam Gross --- ...26-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst | 2 ++ Objects/typeobject.c | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst new file mode 100644 index 000000000000..723b81ddc5f8 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst @@ -0,0 +1,2 @@ +In the free threading build, skip the stop-the-world pause when reassigning +``__class__`` on a newly created object. diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 03d5cfa4ca52..76886a180368 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7120,7 +7120,11 @@ object_set_class_world_stopped(PyObject *self, PyTypeObject *newto) assert(_PyObject_GetManagedDict(self) == dict); - if (_PyDict_DetachFromObject(dict, self) < 0) { + int err; + Py_BEGIN_CRITICAL_SECTION(dict); + err = _PyDict_DetachFromObject(dict, self); + Py_END_CRITICAL_SECTION(); + if (err < 0) { return -1; } @@ -7162,12 +7166,17 @@ object_set_class(PyObject *self, PyObject *value, void *closure) #ifdef Py_GIL_DISABLED PyInterpreterState *interp = _PyInterpreterState_GET(); - _PyEval_StopTheWorld(interp); + int unique = _PyObject_IsUniquelyReferenced(self); + if (!unique) { + _PyEval_StopTheWorld(interp); + } #endif PyTypeObject *oldto = Py_TYPE(self); int res = object_set_class_world_stopped(self, newto); #ifdef Py_GIL_DISABLED - _PyEval_StartTheWorld(interp); + if (!unique) { + _PyEval_StartTheWorld(interp); + } #endif if (res == 0) { if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) { -- 2.47.3