https://github.com/python/cpython/commit/0bd80a1d486592ae4af51e010616c8227d6b589d
commit: 0bd80a1d486592ae4af51e010616c8227d6b589d
branch: 3.14
author: Victor Stinner <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-05-23T12:28:19+05:30
summary:

[3.14] Revert "[3.14] gh-146452: Improve locking granularity in pickle's 
batch_dict_… (#150062)" (#150263)

Revert "[3.14] gh-146452: Improve locking granularity in pickle's batch_dict_… 
(#150062)"

This reverts commit 1243cd677d7f62b90c50546c5ff27e26ef24ca4f.

files:
D Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst
M Modules/_pickle.c

diff --git 
a/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst 
b/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst
deleted file mode 100644
index 66f9acf6c710a79..000000000000000
--- a/Misc/NEWS.d/next/Library/2026-05-18-15-30-34.gh-issue-146452.RM0EVJ.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Fix race condition when pickling dictionaries in free threaded builds. Also
-reduce critical section cover.
diff --git a/Modules/_pickle.c b/Modules/_pickle.c
index 201ea9af8b2a8bb..75e1c4dea85e004 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3351,12 +3351,9 @@ batch_dict(PickleState *state, PicklerObject *self, 
PyObject *iter, PyObject *or
  * Returns 0 on success, -1 on error.
  *
  * Note that this currently doesn't work for protocol 0.
-
- * gh-146452: Wrap the dict iteration in a critical sections to prevent
- * concurrent mutation from invalidating PyDict_Next() iteration state.
  */
 static int
-batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
+batch_dict_exact_impl(PickleState *state, PicklerObject *self, PyObject *obj)
 {
     PyObject *key = NULL, *value = NULL;
     int i;
@@ -3373,19 +3370,9 @@ batch_dict_exact(PickleState *state, PicklerObject 
*self, PyObject *obj)
 
     /* Special-case len(d) == 1 to save space. */
     if (dict_size == 1) {
-        int next;
-        Py_BEGIN_CRITICAL_SECTION(obj);
-        next = PyDict_Next(obj, &ppos, &key, &value);
-        if (next) {
-            Py_INCREF(key);
-            Py_INCREF(value);
-        }
-        Py_END_CRITICAL_SECTION();
-        if (!next) {
-            PyErr_SetString(PyExc_RuntimeError,
-                            "dictionary changed size during iteration");
-            goto error;
-        }
+        PyDict_Next(obj, &ppos, &key, &value);
+        Py_INCREF(key);
+        Py_INCREF(value);
         if (save(state, self, key, 0) < 0) {
             goto error;
         }
@@ -3405,18 +3392,9 @@ batch_dict_exact(PickleState *state, PicklerObject 
*self, PyObject *obj)
         i = 0;
         if (_Pickler_Write(self, &mark_op, 1) < 0)
             return -1;
-        int next;
-        while (1) {
-            Py_BEGIN_CRITICAL_SECTION(obj);
-            next = PyDict_Next(obj, &ppos, &key, &value);
-            if (next) {
-                Py_INCREF(key);
-                Py_INCREF(value);
-            }
-            Py_END_CRITICAL_SECTION();
-            if (!next) {
-                break;
-            }
+        while (PyDict_Next(obj, &ppos, &key, &value)) {
+            Py_INCREF(key);
+            Py_INCREF(value);
             if (save(state, self, key, 0) < 0) {
                 goto error;
             }
@@ -3446,6 +3424,18 @@ batch_dict_exact(PickleState *state, PicklerObject 
*self, PyObject *obj)
     return -1;
 }
 
+/* gh-146452: Wrap the dict iteration in a critical section to prevent
+   concurrent mutation from invalidating PyDict_Next() iteration state. */
+static int
+batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj)
+{
+    int ret;
+    Py_BEGIN_CRITICAL_SECTION(obj);
+    ret = batch_dict_exact_impl(state, self, obj);
+    Py_END_CRITICAL_SECTION();
+    return ret;
+}
+
 static int
 save_dict(PickleState *state, PicklerObject *self, PyObject *obj)
 {

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to