diff --git a/Doc/c-api/type.rst b/Doc/c-api/type.rst index 5d832541f20..9e2b9399a56 100644 --- a/Doc/c-api/type.rst +++ b/Doc/c-api/type.rst @@ -97,3 +97,13 @@ Type Objects 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 05bffc9804c..68ca7b446aa 100644 --- a/Include/object.h +++ b/Include/object.h @@ -439,6 +439,9 @@ PyAPI_FUNC(PyObject*) PyType_FromSpec(PyType_Spec*); #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 ff73d0ba40c..99383675670 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,8 @@ Release date: 2014-02-09 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 661b6e294af..eecdab96975 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -44,7 +44,7 @@ static void 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 cbbb58a949a..349a6fd0a44 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2641,6 +2641,19 @@ PyType_FromSpec(PyType_Spec *spec) 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 448d605faff..8269e1caba4 100644 --- a/setup.py +++ b/setup.py @@ -1539,7 +1539,7 @@ class PyBuildExt(build_ext): 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