mirror of
https://github.com/python/cpython.git
synced 2025-07-24 19:54:21 +00:00
Issue #26146: marshal.loads() now uses the empty frozenset singleton
This commit is contained in:
parent
5ebe2c89fe
commit
1aa78938b0
2 changed files with 50 additions and 32 deletions
|
@ -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)
|
||||||
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);
|
||||||
if (PySet_Add(v, v2) == -1) {
|
retval = v;
|
||||||
Py_DECREF(v);
|
}
|
||||||
Py_DECREF(v2);
|
else {
|
||||||
v = NULL;
|
v = (type == TYPE_SET) ? PySet_New(NULL) : PyFrozenSet_New(NULL);
|
||||||
break;
|
if (type == TYPE_SET) {
|
||||||
}
|
R_REF(v);
|
||||||
Py_DECREF(v2);
|
} 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++) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue