Pablo Galindo Salgado <pablog...@gmail.com> added the comment:
I think I found it. After doing the bisect manually (as redirecting stdout/stderr) seems to affect somehow the test) I found commit b0a7a037b8fde56b62f886d5188bced7776777b4 as the culprit. Reverting this commit on the current master seem to solve the problem. This is the diff of the revert: diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 40d7d8af6e..f7d792232e 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -613,52 +613,6 @@ new_dict_with_shared_keys(PyDictKeysObject *keys) return new_dict(keys, values); } - -static PyObject * -clone_combined_dict(PyDictObject *orig) -{ - assert(PyDict_CheckExact(orig)); - assert(orig->ma_values == NULL); - assert(orig->ma_keys->dk_refcnt == 1); - - Py_ssize_t keys_size = _PyDict_KeysSize(orig->ma_keys); - PyDictKeysObject *keys = PyObject_Malloc(keys_size); - if (keys == NULL) { - PyErr_NoMemory(); - return NULL; - } - - memcpy(keys, orig->ma_keys, keys_size); - - /* After copying key/value pairs, we need to incref all - keys and values and they are about to be co-owned by a - new dict object. */ - PyDictKeyEntry *ep0 = DK_ENTRIES(keys); - Py_ssize_t n = keys->dk_nentries; - for (Py_ssize_t i = 0; i < n; i++) { - PyDictKeyEntry *entry = &ep0[i]; - PyObject *value = entry->me_value; - if (value != NULL) { - Py_INCREF(value); - Py_INCREF(entry->me_key); - } - } - - PyDictObject *new = (PyDictObject *)new_dict(keys, NULL); - if (new == NULL) { - /* In case of an error, `new_dict()` takes care of - cleaning up `keys`. */ - return NULL; - } - new->ma_used = orig->ma_used; - assert(_PyDict_CheckConsistency(new)); - if (_PyObject_GC_IS_TRACKED(orig)) { - /* Maintain tracking. */ - _PyObject_GC_TRACK(new); - } - return (PyObject *)new; -} - PyObject * PyDict_New(void) { @@ -2527,13 +2481,7 @@ PyDict_Copy(PyObject *o) PyErr_BadInternalCall(); return NULL; } - mp = (PyDictObject *)o; - if (mp->ma_used == 0) { - /* The dict is empty; just return a new dict. */ - return PyDict_New(); - } - if (_PyDict_HasSplitTable(mp)) { PyDictObject *split_copy; Py_ssize_t size = USABLE_FRACTION(DK_SIZE(mp->ma_keys)); @@ -2560,27 +2508,6 @@ PyDict_Copy(PyObject *o) _PyObject_GC_TRACK(split_copy); return (PyObject *)split_copy; } - - if (PyDict_CheckExact(mp) && mp->ma_values == NULL && - (mp->ma_used >= (mp->ma_keys->dk_nentries * 2) / 3)) - { - /* Use fast-copy if: - - (1) 'mp' is an instance of a subclassed dict; and - - (2) 'mp' is not a split-dict; and - - (3) if 'mp' is non-compact ('del' operation does not resize dicts), - do fast-copy only if it has at most 1/3 non-used keys. - - The last condition (3) is important to guard against a pathological - case when a large dict is almost emptied with multiple del/pop - operations and copied after that. In cases like this, we defer to - PyDict_Merge, which produces a compacted copy. - */ - return clone_combined_dict(mp); - } - copy = PyDict_New(); if (copy == NULL) return NULL; ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue34042> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com