Skip to content

Commit 3eb714a

Browse files
committed
gh-141510, PEP 814: Add frozendict support to pickle
Add frozendict.__getnewargs__() method.
1 parent 16ccdbc commit 3eb714a

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

Lib/test/picklecommon.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ class MyList(list):
252252
class MyDict(dict):
253253
sample = {"a": 1, "b": 2}
254254

255+
class MyFrozenDict(dict):
256+
sample = frozendict({"a": 1, "b": 2})
257+
255258
class MySet(set):
256259
sample = {"a", "b"}
257260

@@ -261,7 +264,7 @@ class MyFrozenSet(frozenset):
261264
myclasses = [MyInt, MyLong, MyFloat,
262265
MyComplex,
263266
MyStr, MyUnicode,
264-
MyTuple, MyList, MyDict, MySet, MyFrozenSet]
267+
MyTuple, MyList, MyDict, MyFrozenDict, MySet, MyFrozenSet]
265268

266269
# For test_newobj_overridden_new
267270
class MyIntWithNew(int):

Lib/test/pickletester.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2839,11 +2839,13 @@ def test_recursive_multi(self):
28392839
self.assertEqual(list(x[0].attr.keys()), [1])
28402840
self.assertIs(x[0].attr[1], x)
28412841

2842-
def _test_recursive_collection_and_inst(self, factory, oldminproto=None):
2842+
def _test_recursive_collection_and_inst(self, factory, oldminproto=None,
2843+
minprotocol=0):
28432844
if self.py_version < (3, 0):
28442845
self.skipTest('"classic" classes are not interoperable with Python 2')
28452846
# Mutable object containing a collection containing the original
28462847
# object.
2848+
protocols = range(minprotocol, pickle.HIGHEST_PROTOCOL + 1)
28472849
o = Object()
28482850
o.attr = factory([o])
28492851
t = type(o.attr)
@@ -2883,6 +2885,9 @@ def test_recursive_tuple_and_inst(self):
28832885
def test_recursive_dict_and_inst(self):
28842886
self._test_recursive_collection_and_inst(dict.fromkeys, oldminproto=0)
28852887

2888+
def test_recursive_frozendict_and_inst(self):
2889+
self._test_recursive_collection_and_inst(frozendict.fromkeys, minprotocol=2)
2890+
28862891
def test_recursive_set_and_inst(self):
28872892
self._test_recursive_collection_and_inst(set)
28882893

Objects/dictobject.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7930,6 +7930,18 @@ _PyObject_InlineValuesConsistencyCheck(PyObject *obj)
79307930

79317931
// --- frozendict implementation ---------------------------------------------
79327932

7933+
static PyObject *
7934+
frozendict_getnewargs(PyObject *op, PyObject *Py_UNUSED(dummy))
7935+
{
7936+
// Call dict(op): convert 'op' frozendict to a dict
7937+
PyObject *arg = PyObject_CallOneArg((PyObject*)&PyDict_Type, op);
7938+
if (arg == NULL) {
7939+
return NULL;
7940+
}
7941+
return Py_BuildValue("(N)", arg);
7942+
}
7943+
7944+
79337945
static PyNumberMethods frozendict_as_number = {
79347946
.nb_or = frozendict_or,
79357947
};
@@ -7951,6 +7963,7 @@ static PyMethodDef frozendict_methods[] = {
79517963
DICT_COPY_METHODDEF
79527964
DICT___REVERSED___METHODDEF
79537965
{"__class_getitem__", Py_GenericAlias, METH_O|METH_CLASS, PyDoc_STR("See PEP 585")},
7966+
{"__getnewargs__", frozendict_getnewargs, METH_NOARGS},
79547967
{NULL, NULL} /* sentinel */
79557968
};
79567969

0 commit comments

Comments
 (0)