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

This commit is contained in:
Joe Jevnik 2019-02-21 16:00:40 -05:00 committed by Raymond Hettinger
parent 407c734326
commit f36f89257b
3 changed files with 23 additions and 3 deletions

View File

@ -368,7 +368,7 @@ Optimizations
* Sped-up field lookups in :func:`collections.namedtuple`. They are now more * Sped-up field lookups in :func:`collections.namedtuple`. They are now more
than two times faster, making them the fastest form of instance variable than two times faster, making them the fastest form of instance variable
lookup in Python. (Contributed by Raymond Hettinger, Pablo Galindo, and 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 * The :class:`list` constructor does not overallocate the internal item buffer
if the input iterable has a known length (the input implements ``__len__``). if the input iterable has a known length (the input implements ``__len__``).

View File

@ -13,7 +13,7 @@ from test import support
import types import types
import unittest 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 UserDict, UserString, UserList
from collections import ChainMap from collections import ChainMap
from collections import deque 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.__set__, p, 33)
self.assertRaises(AttributeError, Point.x.__delete__, p) 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 ### Abstract Base Classes

View File

@ -2440,12 +2440,23 @@ tuplegetter_dealloc(_tuplegetterobject *self)
Py_TYPE(self)->tp_free((PyObject*)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[] = { static PyMemberDef tuplegetter_members[] = {
{"__doc__", T_OBJECT, offsetof(_tuplegetterobject, doc), 0}, {"__doc__", T_OBJECT, offsetof(_tuplegetterobject, doc), 0},
{0} {0}
}; };
static PyMethodDef tuplegetter_methods[] = {
{"__reduce__", (PyCFunction) tuplegetter_reduce, METH_NOARGS, NULL},
{NULL},
};
static PyTypeObject tuplegetter_type = { static PyTypeObject tuplegetter_type = {
PyVarObject_HEAD_INIT(NULL, 0) PyVarObject_HEAD_INIT(NULL, 0)
"_collections._tuplegetter", /* tp_name */ "_collections._tuplegetter", /* tp_name */
@ -2475,7 +2486,7 @@ static PyTypeObject tuplegetter_type = {
0, /* tp_weaklistoffset */ 0, /* tp_weaklistoffset */
0, /* tp_iter */ 0, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
0, /* tp_methods */ tuplegetter_methods, /* tp_methods */
tuplegetter_members, /* tp_members */ tuplegetter_members, /* tp_members */
0, /* tp_getset */ 0, /* tp_getset */
0, /* tp_base */ 0, /* tp_base */