summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Jevnik <JoeJev@gmail.com>2019-02-21 21:00:40 (GMT)
committerRaymond Hettinger <rhettinger@users.noreply.github.com>2019-02-21 21:00:40 (GMT)
commitf36f89257b30e0bf88e8aaff6da14a9a96f57b9e (patch)
treec8e0d07472981a5cb4fcf4d597178c9a30c06819
parent407c7343266eb3e5a2f5c1f4913082c84f8dd8a0 (diff)
downloadcpython-f36f89257b30e0bf88e8aaff6da14a9a96f57b9e.zip
cpython-f36f89257b30e0bf88e8aaff6da14a9a96f57b9e.tar.gz
cpython-f36f89257b30e0bf88e8aaff6da14a9a96f57b9e.tar.bz2
bpo-36068: Make _tuplegetter objects serializable (GH-11981)
-rw-r--r--Doc/whatsnew/3.8.rst2
-rw-r--r--Lib/test/test_collections.py11
-rw-r--r--Modules/_collectionsmodule.c13
3 files changed, 23 insertions, 3 deletions
diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 66e1c13..2f759f3 100644
--- a/Doc/whatsnew/3.8.rst
+++ b/Doc/whatsnew/3.8.rst
@@ -368,7 +368,7 @@ Optimizations
* Sped-up field lookups in :func:`collections.namedtuple`. They are now more
than two times faster, making them the fastest form of instance variable
lookup in Python. (Contributed by Raymond Hettinger, Pablo Galindo, and
- Serhiy Storchaka in :issue:`32492`.)
+ Joe Jevnik, Serhiy Storchaka in :issue:`32492`.)
* The :class:`list` constructor does not overallocate the internal item buffer
if the input iterable has a known length (the input implements ``__len__``).
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 4f8a841..dad1b6c 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -13,7 +13,7 @@ from test import support
import types
import unittest
-from collections import namedtuple, Counter, OrderedDict, _count_elements
+from collections import namedtuple, Counter, OrderedDict, _count_elements, _tuplegetter
from collections import UserDict, UserString, UserList
from collections import ChainMap
from collections import deque
@@ -573,6 +573,15 @@ class TestNamedTuple(unittest.TestCase):
self.assertRaises(AttributeError, Point.x.__set__, p, 33)
self.assertRaises(AttributeError, Point.x.__delete__, p)
+ class NewPoint(tuple):
+ x = pickle.loads(pickle.dumps(Point.x))
+ y = pickle.loads(pickle.dumps(Point.y))
+
+ np = NewPoint([1, 2])
+
+ self.assertEqual(np.x, 1)
+ self.assertEqual(np.y, 2)
+
################################################################################
### Abstract Base Classes
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index 280b15d..1c9e866 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -2440,12 +2440,23 @@ tuplegetter_dealloc(_tuplegetterobject *self)
Py_TYPE(self)->tp_free((PyObject*)self);
}
+static PyObject*
+tuplegetter_reduce(_tuplegetterobject *self)
+{
+ return Py_BuildValue("(O(nO))", (PyObject*) Py_TYPE(self), self->index, self->doc);
+}
+
static PyMemberDef tuplegetter_members[] = {
{"__doc__", T_OBJECT, offsetof(_tuplegetterobject, doc), 0},
{0}
};
+static PyMethodDef tuplegetter_methods[] = {
+ {"__reduce__", (PyCFunction) tuplegetter_reduce, METH_NOARGS, NULL},
+ {NULL},
+};
+
static PyTypeObject tuplegetter_type = {
PyVarObject_HEAD_INIT(NULL, 0)
"_collections._tuplegetter", /* tp_name */
@@ -2475,7 +2486,7 @@ static PyTypeObject tuplegetter_type = {
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- 0, /* tp_methods */
+ tuplegetter_methods, /* tp_methods */
tuplegetter_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */