[Python-checkins] bpo-36068: Make _tuplegetter objects serializable (GH-11981)

Raymond Hettinger webhook-mailer at python.org
Thu Feb 21 16:00:43 EST 2019


https://github.com/python/cpython/commit/f36f89257b30e0bf88e8aaff6da14a9a96f57b9e
commit: f36f89257b30e0bf88e8aaff6da14a9a96f57b9e
branch: master
author: Joe Jevnik <JoeJev at gmail.com>
committer: Raymond Hettinger <rhettinger at users.noreply.github.com>
date: 2019-02-21T13:00:40-08:00
summary:

bpo-36068: Make _tuplegetter objects serializable (GH-11981)

files:
M Doc/whatsnew/3.8.rst
M Lib/test/test_collections.py
M Modules/_collectionsmodule.c

diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst
index 66e1c13cccce..2f759f3454ea 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 4f8a841e7577..dad1b6cd7fb3 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -13,7 +13,7 @@
 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 @@ def test_field_descriptor(self):
         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 280b15d73b1f..1c9e866e62f0 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 */



More information about the Python-checkins mailing list