Issue #17162: Add PyType_GetSlot.
diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst
index 5d83254..9e2b939 100644
--- a/Doc/c-api/type.rst
+++ b/Doc/c-api/type.rst
@@ -97,3 +97,13 @@
    types. This allows the caller to reference other heap types as base types.
 
    .. versionadded:: 3.3
+
+.. c:function:: void* PyType_GetSlot(PyTypeObject *type, int slot)
+
+   Return the function pointer stored int the given slot. If the
+   result is *NULL*, this indicates that either the slot is *NULL*,
+   or that the function was called with invalid parameters.
+   Callers will typically cast the result pointer into the appropriate
+   function type.
+
+   .. versionadded:: 3.4
diff --git a/Include/object.h b/Include/object.h
index 05bffc9..68ca7b4 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -439,6 +439,9 @@
 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
 PyAPI_FUNC(PyObject*) PyType_FromSpecWithBases(PyType_Spec*, PyObject*);
 #endif
+#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03040000
+PyAPI_FUNC(void*) PyType_GetSlot(PyTypeObject*, int);
+#endif
 
 #ifndef Py_LIMITED_API
 /* The *real* layout of a type object when allocated on the heap */
diff --git a/Misc/NEWS b/Misc/NEWS
index ff73d0b..9938367 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
 Core and Builtins
 -----------------
 
+- Issue #17162: Add PyType_GetSlot.
+
 - Issue #20162: Fix an alignment issue in the siphash24() hash function which
   caused a crash on PowerPC 64-bit (ppc64).
 
diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c
index 661b6e2..eecdab9 100644
--- a/Modules/xxlimited.c
+++ b/Modules/xxlimited.c
@@ -44,7 +44,7 @@
 Xxo_dealloc(XxoObject *self)
 {
     Py_XDECREF(self->x_attr);
-    PyObject_Del(self);
+    ((freefunc)PyType_GetSlot(Py_TYPE(self), Py_tp_free))(self);
 }
 
 static PyObject *
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index cbbb58a..349a6fd 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -2641,6 +2641,19 @@
     return PyType_FromSpecWithBases(spec, NULL);
 }
 
+void *
+PyType_GetSlot(PyTypeObject *type, int slot)
+{
+    if (!PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) {
+        PyErr_BadInternalCall();
+        return NULL;
+    }
+    if (slot >= Py_ARRAY_LENGTH(slotoffsets)) {
+        /* Extension module requesting slot from a future version */
+        return NULL;
+    }
+    return  *(void**)(((char*)type) + slotoffsets[slot]);
+}
 
 /* Internal API to look for a name through the MRO.
    This returns a borrowed reference, and doesn't set an exception! */
diff --git a/setup.py b/setup.py
index 448d605..8269e1c 100644
--- a/setup.py
+++ b/setup.py
@@ -1539,7 +1539,7 @@
 
         if 'd' not in sys.abiflags:
             ext = Extension('xxlimited', ['xxlimited.c'],
-                            define_macros=[('Py_LIMITED_API', 1)])
+                            define_macros=[('Py_LIMITED_API', '0x03040000')])
             self.extensions.append(ext)
 
         return missing