Kaydet (Commit) 1aa78938 authored tarafından Victor Stinner's avatar Victor Stinner

Issue #26146: marshal.loads() now uses the empty frozenset singleton

üst 5ebe2c89
...@@ -135,6 +135,13 @@ class ContainerTestCase(unittest.TestCase, HelperMixin): ...@@ -135,6 +135,13 @@ class ContainerTestCase(unittest.TestCase, HelperMixin):
for constructor in (set, frozenset): for constructor in (set, frozenset):
self.helper(constructor(self.d.keys())) self.helper(constructor(self.d.keys()))
@support.cpython_only
def test_empty_frozenset_singleton(self):
# marshal.loads() must reuse the empty frozenset singleton
obj = frozenset()
obj2 = marshal.loads(marshal.dumps(obj))
self.assertIs(obj2, obj)
class BufferTestCase(unittest.TestCase, HelperMixin): class BufferTestCase(unittest.TestCase, HelperMixin):
......
...@@ -1266,41 +1266,52 @@ r_object(RFILE *p) ...@@ -1266,41 +1266,52 @@ r_object(RFILE *p)
PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)"); PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
break; break;
} }
v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
if (type == TYPE_SET) {
R_REF(v);
} else {
/* must use delayed registration of frozensets because they must
* be init with a refcount of 1
*/
idx = r_ref_reserve(flag, p);
if (idx < 0)
Py_CLEAR(v); /* signal error */
}
if (v == NULL)
break;
for (i = 0; i < n; i++) { if (n == 0 && type == TYPE_FROZENSET) {
v2 = r_object(p); /* call frozenset() to get the empty frozenset singleton */
if ( v2 == NULL ) { v = PyObject_CallFunction((PyObject*)&PyFrozenSet_Type, NULL);
if (!PyErr_Occurred()) if (v == NULL)
PyErr_SetString(PyExc_TypeError,
"NULL object in marshal data for set");
Py_DECREF(v);
v = NULL;
break; break;
R_REF(v);
retval = v;
}
else {
v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
if (type == TYPE_SET) {
R_REF(v);
} else {
/* must use delayed registration of frozensets because they must
* be init with a refcount of 1
*/
idx = r_ref_reserve(flag, p);
if (idx < 0)
Py_CLEAR(v); /* signal error */
} }
if (PySet_Add(v, v2) == -1) { if (v == NULL)
Py_DECREF(v);
Py_DECREF(v2);
v = NULL;
break; break;
for (i = 0; i < n; i++) {
v2 = r_object(p);
if ( v2 == NULL ) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_TypeError,
"NULL object in marshal data for set");
Py_DECREF(v);
v = NULL;
break;
}
if (PySet_Add(v, v2) == -1) {
Py_DECREF(v);
Py_DECREF(v2);
v = NULL;
break;
}
Py_DECREF(v2);
} }
Py_DECREF(v2); if (type != TYPE_SET)
v = r_ref_insert(v, idx, flag, p);
retval = v;
} }
if (type != TYPE_SET)
v = r_ref_insert(v, idx, flag, p);
retval = v;
break; break;
case TYPE_CODE: case TYPE_CODE:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment