From: Sam Gross Date: Fri, 6 Mar 2026 17:01:06 +0000 (-0500) Subject: gh-145566: Skip stop-the-world when reassigning `__class__` on newly created objects... X-Git-Tag: v3.15.0a7~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d091a336e60b703a7d7ae4124f652eabe144f4e;p=thirdparty%2FPython%2Fcpython.git gh-145566: Skip stop-the-world when reassigning `__class__` on newly created objects (gh-145567) --- 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 1fdd3cbdaaa6..27ec8bb40a92 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -7568,7 +7568,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; } @@ -7608,10 +7612,15 @@ object_set_class(PyObject *self, PyObject *value, void *closure) return -1; } - types_stop_world(); + int unique = _PyObject_IsUniquelyReferenced(self); + if (!unique) { + types_stop_world(); + } PyTypeObject *oldto = Py_TYPE(self); int res = object_set_class_world_stopped(self, newto); - types_start_world(); + if (!unique) { + types_start_world(); + } if (res == 0) { if (oldto->tp_flags & Py_TPFLAGS_HEAPTYPE) { Py_DECREF(oldto);