https://github.com/python/cpython/commit/795dd3bd3500c49c6a08281a15a9472a28f416d3
commit: 795dd3bd3500c49c6a08281a15a9472a28f416d3
branch: 3.15
author: Victor Stinner <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-05-23T12:27:27+05:30
summary:
[3.15] Revert "[3.15] gh-146452: Improve locking granularity in pickle's
batch_dict_exact and fix race condition (GH-150025) (#150039)" (#150262)
Revert "[3.15] gh-146452: Improve locking granularity in pickle's
batch_dict_exact and fix race condition (GH-150025) (#150039)"
This reverts commit 66ade2861fec1d6c18998710938a1c71fde5f76b.
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 15d95c658d6f906..9874f9475ac0296 100644
--- a/Modules/_pickle.c
+++ b/Modules/_pickle.c
@@ -3450,9 +3450,6 @@ 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)
@@ -3469,24 +3466,15 @@ batch_dict_exact(PickleState *state, PicklerObject
*self, PyObject *obj)
assert(self->proto > 0);
dict_size = PyDict_GET_SIZE(obj);
+ assert(dict_size);
/* Write in batches of BATCHSIZE. */
Py_ssize_t total = 0;
do {
if (dict_size - total == 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;
}
@@ -3504,18 +3492,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;
}
_______________________________________________
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]