From 9d05c8c0e0b0f3ebd19d7add842d2db8269f7d75 Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Sat, 16 Feb 2013 18:20:32 -0700 Subject: Issue #15022: Ensure all pickle protocols are supported. --- Lib/test/test_types.py | 13 +++++++++---- Objects/namespaceobject.c | 25 ++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index de0aac2..ec10752 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -1159,10 +1159,15 @@ class SimpleNamespaceTests(unittest.TestCase): def test_pickle(self): ns = types.SimpleNamespace(breakfast="spam", lunch="spam") - ns_pickled = pickle.dumps(ns) - ns_roundtrip = pickle.loads(ns_pickled) - - self.assertEqual(ns, ns_roundtrip) + for protocol in range(pickle.HIGHEST_PROTOCOL + 1): + pname = "protocol {}".format(protocol) + try: + ns_pickled = pickle.dumps(ns, protocol) + except TypeError as e: + raise TypeError(pname) from e + ns_roundtrip = pickle.loads(ns_pickled) + + self.assertEqual(ns, ns_roundtrip, pname) def test_main(): diff --git a/Objects/namespaceobject.c b/Objects/namespaceobject.c index f9a6f65..7e9107a 100644 --- a/Objects/namespaceobject.c +++ b/Objects/namespaceobject.c @@ -173,6 +173,29 @@ namespace_richcompare(PyObject *self, PyObject *other, int op) } +PyDoc_STRVAR(namespace_reduce__doc__, "Return state information for pickling"); + +static PyObject * +namespace_reduce(register _PyNamespaceObject *ns) +{ + PyObject *result, *args = PyTuple_New(0); + + if (!args) + return NULL; + + result = PyTuple_Pack(3, (PyObject *)Py_TYPE(ns), args, ns->ns_dict); + Py_DECREF(args); + return result; +} + + +static PyMethodDef namespace_methods[] = { + {"__reduce__", (PyCFunction)namespace_reduce, METH_NOARGS, + namespace_reduce__doc__}, + {NULL, NULL} /* sentinel */ +}; + + PyDoc_STRVAR(namespace_doc, "A simple attribute-based namespace.\n\ \n\ @@ -207,7 +230,7 @@ PyTypeObject _PyNamespace_Type = { 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ - 0, /* tp_methods */ + namespace_methods, /* tp_methods */ namespace_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ -- cgit v0.12