]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-145566: Skip stop-the-world when reassigning `__class__` on newly created...
authorSam Gross <colesbury@gmail.com>
Fri, 6 Mar 2026 19:35:00 +0000 (14:35 -0500)
committerGitHub <noreply@github.com>
Fri, 6 Mar 2026 19:35:00 +0000 (14:35 -0500)
Co-authored-by: Sam Gross <colesbury@gmail.com>
Misc/NEWS.d/next/Core_and_Builtins/2026-03-05-19-10-56.gh-issue-145566.H4RupyYN.rst [new file with mode: 0644]
Objects/typeobject.c

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 (file)
index 0000000..723b81d
--- /dev/null
@@ -0,0 +1,2 @@
+In the free threading build, skip the stop-the-world pause when reassigning
+``__class__`` on a newly created object.
index 03d5cfa4ca524955a3d3e69608a99a2c744d43e1..76886a180368542e59e9c5f9e41b88332cd15556 100644 (file)
@@ -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) {