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

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 @@
 * 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 @@
 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 @@
         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 @@
     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 @@
     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 */