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

This commit is contained in:
Victor Stinner 2016-01-23 14:15:48 +01:00
parent 5ebe2c89fe
commit 1aa78938b0
2 changed files with 50 additions and 32 deletions

View File

@ -135,6 +135,13 @@ class ContainerTestCase(unittest.TestCase, HelperMixin):
for constructor in (set, frozenset):
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):

View File

@ -1266,6 +1266,16 @@ r_object(RFILE *p)
PyErr_SetString(PyExc_ValueError, "bad marshal data (set size out of range)");
break;
}
if (n == 0 && type == TYPE_FROZENSET) {
/* call frozenset() to get the empty frozenset singleton */
v = PyObject_CallFunction((PyObject*)&PyFrozenSet_Type, NULL);
if (v == NULL)
break;
R_REF(v);
retval = v;
}
else {
v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
if (type == TYPE_SET) {
R_REF(v);
@ -1301,6 +1311,7 @@ r_object(RFILE *p)
if (type != TYPE_SET)
v = r_ref_insert(v, idx, flag, p);
retval = v;
}
break;
case TYPE_CODE: