Commit ada319bb authored by Antoine Pitrou's avatar Antoine Pitrou Committed by GitHub

bpo-32388: Remove cross-version binary compatibility requirement in tp_flags (GH-4944)

It is now allowed to add new fields at the end of the PyTypeObject struct without having to allocate a dedicated compatibility flag in tp_flags.

This will reduce the risk of running out of bits in the 32-bit tp_flags value.
parent 43fdbd27
...@@ -1099,6 +1099,11 @@ and :c:type:`PyType_Type` effectively act as defaults.) ...@@ -1099,6 +1099,11 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. versionadded:: 3.4 .. versionadded:: 3.4
.. deprecated:: 3.8
This flag isn't necessary anymore, as the interpreter assumes the
:c:member:`~PyTypeObject.tp_finalize` slot is always present in the
type structure.
.. c:member:: const char* PyTypeObject.tp_doc .. c:member:: const char* PyTypeObject.tp_doc
......
...@@ -1265,6 +1265,15 @@ Changes in the C API ...@@ -1265,6 +1265,15 @@ Changes in the C API
(Contributed by Zackery Spytz in :issue:`33407`.) (Contributed by Zackery Spytz in :issue:`33407`.)
* The interpreter does not pretend to support binary compatibility of
extension types accross feature releases, anymore. A :c:type:`PyTypeObject`
exported by a third-party extension module is supposed to have all the
slots expected in the current Python version, including
:c:member:`~PyTypeObject.tp_finalize` (:const:`Py_TPFLAGS_HAVE_FINALIZE`
is not checked anymore before reading :c:member:`~PyTypeObject.tp_finalize`).
(Contributed by Antoine Pitrou in :issue:`32388`.)
CPython bytecode changes CPython bytecode changes
------------------------ ------------------------
......
...@@ -263,17 +263,14 @@ PyAPI_FUNC(void) Py_ReprLeave(PyObject *); ...@@ -263,17 +263,14 @@ PyAPI_FUNC(void) Py_ReprLeave(PyObject *);
#define Py_PRINT_RAW 1 /* No string quotes etc. */ #define Py_PRINT_RAW 1 /* No string quotes etc. */
/* /*
`Type flags (tp_flags) Type flags (tp_flags)
These flags are used to extend the type structure in a backwards-compatible These flags are used to change expected features and behavior for a
fashion. Extensions can use the flags to indicate (and test) when a given particular type.
type structure contains a new feature. The Python core will use these when
introducing new functionality between major revisions (to avoid mid-version
changes in the PYTHON_API_VERSION).
Arbitration of the flag bit positions will need to be coordinated among Arbitration of the flag bit positions will need to be coordinated among
all extension writers who publicly release their extensions (this will all extension writers who publicly release their extensions (this will
be fewer than you might expect!).. be fewer than you might expect!).
Most flags were removed as of Python 3.0 to make room for new flags. (Some Most flags were removed as of Python 3.0 to make room for new flags. (Some
flags are not for backwards compatibility but to indicate the presence of an flags are not for backwards compatibility but to indicate the presence of an
...@@ -302,7 +299,7 @@ given type object has a specified feature. ...@@ -302,7 +299,7 @@ given type object has a specified feature.
/* Set while the type is being 'readied', to prevent recursive ready calls */ /* Set while the type is being 'readied', to prevent recursive ready calls */
#define Py_TPFLAGS_READYING (1UL << 13) #define Py_TPFLAGS_READYING (1UL << 13)
/* Objects support garbage collection (see objimp.h) */ /* Objects support garbage collection (see objimpl.h) */
#define Py_TPFLAGS_HAVE_GC (1UL << 14) #define Py_TPFLAGS_HAVE_GC (1UL << 14)
/* These two bits are preserved for Stackless Python, next after this is 17 */ /* These two bits are preserved for Stackless Python, next after this is 17 */
...@@ -340,6 +337,11 @@ given type object has a specified feature. ...@@ -340,6 +337,11 @@ given type object has a specified feature.
/* NOTE: The following flags reuse lower bits (removed as part of the /* NOTE: The following flags reuse lower bits (removed as part of the
* Python 3.0 transition). */ * Python 3.0 transition). */
/* The following flag is kept for compatibility. Starting with 3.8,
* binary compatibility of C extensions accross feature releases of
* Python is not supported anymore, except when using the stable ABI.
*/
/* Type structure has tp_finalize member (3.4) */ /* Type structure has tp_finalize member (3.4) */
#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) #define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0)
......
Remove cross-version binary compatibility requirement in tp_flags.
...@@ -1430,8 +1430,7 @@ static PyTypeObject FutureType = { ...@@ -1430,8 +1430,7 @@ static PyTypeObject FutureType = {
.tp_dealloc = FutureObj_dealloc, .tp_dealloc = FutureObj_dealloc,
.tp_as_async = &FutureType_as_async, .tp_as_async = &FutureType_as_async,
.tp_repr = (reprfunc)FutureObj_repr, .tp_repr = (reprfunc)FutureObj_repr,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
| Py_TPFLAGS_HAVE_FINALIZE,
.tp_doc = _asyncio_Future___init____doc__, .tp_doc = _asyncio_Future___init____doc__,
.tp_traverse = (traverseproc)FutureObj_traverse, .tp_traverse = (traverseproc)FutureObj_traverse,
.tp_clear = (inquiry)FutureObj_clear, .tp_clear = (inquiry)FutureObj_clear,
...@@ -2461,8 +2460,7 @@ static PyTypeObject TaskType = { ...@@ -2461,8 +2460,7 @@ static PyTypeObject TaskType = {
.tp_dealloc = TaskObj_dealloc, .tp_dealloc = TaskObj_dealloc,
.tp_as_async = &FutureType_as_async, .tp_as_async = &FutureType_as_async,
.tp_repr = (reprfunc)FutureObj_repr, .tp_repr = (reprfunc)FutureObj_repr,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE,
| Py_TPFLAGS_HAVE_FINALIZE,
.tp_doc = _asyncio_Task___init____doc__, .tp_doc = _asyncio_Task___init____doc__,
.tp_traverse = (traverseproc)TaskObj_traverse, .tp_traverse = (traverseproc)TaskObj_traverse,
.tp_clear = (inquiry)TaskObj_clear, .tp_clear = (inquiry)TaskObj_clear,
......
...@@ -2342,8 +2342,7 @@ PyTypeObject PyBufferedIOBase_Type = { ...@@ -2342,8 +2342,7 @@ PyTypeObject PyBufferedIOBase_Type = {
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
| Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
bufferediobase_doc, /* tp_doc */ bufferediobase_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
...@@ -2434,7 +2433,7 @@ PyTypeObject PyBufferedReader_Type = { ...@@ -2434,7 +2433,7 @@ PyTypeObject PyBufferedReader_Type = {
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
_io_BufferedReader___init____doc__, /* tp_doc */ _io_BufferedReader___init____doc__, /* tp_doc */
(traverseproc)buffered_traverse, /* tp_traverse */ (traverseproc)buffered_traverse, /* tp_traverse */
(inquiry)buffered_clear, /* tp_clear */ (inquiry)buffered_clear, /* tp_clear */
...@@ -2520,7 +2519,7 @@ PyTypeObject PyBufferedWriter_Type = { ...@@ -2520,7 +2519,7 @@ PyTypeObject PyBufferedWriter_Type = {
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
_io_BufferedWriter___init____doc__, /* tp_doc */ _io_BufferedWriter___init____doc__, /* tp_doc */
(traverseproc)buffered_traverse, /* tp_traverse */ (traverseproc)buffered_traverse, /* tp_traverse */
(inquiry)buffered_clear, /* tp_clear */ (inquiry)buffered_clear, /* tp_clear */
...@@ -2597,7 +2596,7 @@ PyTypeObject PyBufferedRWPair_Type = { ...@@ -2597,7 +2596,7 @@ PyTypeObject PyBufferedRWPair_Type = {
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ | Py_TPFLAGS_HAVE_GC, /* tp_flags */
_io_BufferedRWPair___init____doc__, /* tp_doc */ _io_BufferedRWPair___init____doc__, /* tp_doc */
(traverseproc)bufferedrwpair_traverse, /* tp_traverse */ (traverseproc)bufferedrwpair_traverse, /* tp_traverse */
(inquiry)bufferedrwpair_clear, /* tp_clear */ (inquiry)bufferedrwpair_clear, /* tp_clear */
...@@ -2691,7 +2690,7 @@ PyTypeObject PyBufferedRandom_Type = { ...@@ -2691,7 +2690,7 @@ PyTypeObject PyBufferedRandom_Type = {
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
_io_BufferedRandom___init____doc__, /* tp_doc */ _io_BufferedRandom___init____doc__, /* tp_doc */
(traverseproc)buffered_traverse, /* tp_traverse */ (traverseproc)buffered_traverse, /* tp_traverse */
(inquiry)buffered_clear, /* tp_clear */ (inquiry)buffered_clear, /* tp_clear */
......
...@@ -1200,12 +1200,12 @@ PyTypeObject PyFileIO_Type = { ...@@ -1200,12 +1200,12 @@ PyTypeObject PyFileIO_Type = {
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ | Py_TPFLAGS_HAVE_GC, /* tp_flags */
_io_FileIO___init____doc__, /* tp_doc */ _io_FileIO___init____doc__, /* tp_doc */
(traverseproc)fileio_traverse, /* tp_traverse */ (traverseproc)fileio_traverse, /* tp_traverse */
(inquiry)fileio_clear, /* tp_clear */ (inquiry)fileio_clear, /* tp_clear */
0, /* tp_richcompare */ 0, /* tp_richcompare */
offsetof(fileio, weakreflist), /* tp_weaklistoffset */ offsetof(fileio, weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */ 0, /* tp_iter */
0, /* tp_iternext */ 0, /* tp_iternext */
fileio_methods, /* tp_methods */ fileio_methods, /* tp_methods */
...@@ -1215,7 +1215,7 @@ PyTypeObject PyFileIO_Type = { ...@@ -1215,7 +1215,7 @@ PyTypeObject PyFileIO_Type = {
0, /* tp_dict */ 0, /* tp_dict */
0, /* tp_descr_get */ 0, /* tp_descr_get */
0, /* tp_descr_set */ 0, /* tp_descr_set */
offsetof(fileio, dict), /* tp_dictoffset */ offsetof(fileio, dict), /* tp_dictoffset */
_io_FileIO___init__, /* tp_init */ _io_FileIO___init__, /* tp_init */
PyType_GenericAlloc, /* tp_alloc */ PyType_GenericAlloc, /* tp_alloc */
fileio_new, /* tp_new */ fileio_new, /* tp_new */
......
...@@ -856,7 +856,7 @@ PyTypeObject PyIOBase_Type = { ...@@ -856,7 +856,7 @@ PyTypeObject PyIOBase_Type = {
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
iobase_doc, /* tp_doc */ iobase_doc, /* tp_doc */
(traverseproc)iobase_traverse, /* tp_traverse */ (traverseproc)iobase_traverse, /* tp_traverse */
(inquiry)iobase_clear, /* tp_clear */ (inquiry)iobase_clear, /* tp_clear */
...@@ -1051,7 +1051,7 @@ PyTypeObject PyRawIOBase_Type = { ...@@ -1051,7 +1051,7 @@ PyTypeObject PyRawIOBase_Type = {
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
rawiobase_doc, /* tp_doc */ rawiobase_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
......
...@@ -183,8 +183,7 @@ PyTypeObject PyTextIOBase_Type = { ...@@ -183,8 +183,7 @@ PyTypeObject PyTextIOBase_Type = {
0, /*tp_getattro*/ 0, /*tp_getattro*/
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
| Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/
textiobase_doc, /* tp_doc */ textiobase_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
...@@ -3258,7 +3257,7 @@ PyTypeObject PyTextIOWrapper_Type = { ...@@ -3258,7 +3257,7 @@ PyTypeObject PyTextIOWrapper_Type = {
0, /*tp_setattro*/ 0, /*tp_setattro*/
0, /*tp_as_buffer*/ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ | Py_TPFLAGS_HAVE_GC, /*tp_flags*/
_io_TextIOWrapper___init____doc__, /* tp_doc */ _io_TextIOWrapper___init____doc__, /* tp_doc */
(traverseproc)textiowrapper_traverse, /* tp_traverse */ (traverseproc)textiowrapper_traverse, /* tp_traverse */
(inquiry)textiowrapper_clear, /* tp_clear */ (inquiry)textiowrapper_clear, /* tp_clear */
......
...@@ -1133,7 +1133,7 @@ PyTypeObject PyWindowsConsoleIO_Type = { ...@@ -1133,7 +1133,7 @@ PyTypeObject PyWindowsConsoleIO_Type = {
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ | Py_TPFLAGS_HAVE_GC, /* tp_flags */
_io__WindowsConsoleIO___init____doc__, /* tp_doc */ _io__WindowsConsoleIO___init____doc__, /* tp_doc */
(traverseproc)winconsoleio_traverse, /* tp_traverse */ (traverseproc)winconsoleio_traverse, /* tp_traverse */
(inquiry)winconsoleio_clear, /* tp_clear */ (inquiry)winconsoleio_clear, /* tp_clear */
......
...@@ -98,7 +98,7 @@ static PyType_Spec Example_Type_spec = { ...@@ -98,7 +98,7 @@ static PyType_Spec Example_Type_spec = {
"_testimportexec.Example", "_testimportexec.Example",
sizeof(ExampleObject), sizeof(ExampleObject),
0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Example_Type_slots Example_Type_slots
}; };
......
...@@ -858,7 +858,6 @@ finalize_garbage(PyGC_Head *collectable) ...@@ -858,7 +858,6 @@ finalize_garbage(PyGC_Head *collectable)
PyObject *op = FROM_GC(gc); PyObject *op = FROM_GC(gc);
gc_list_move(gc, &seen); gc_list_move(gc, &seen);
if (!_PyGCHead_FINALIZED(gc) && if (!_PyGCHead_FINALIZED(gc) &&
PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) &&
(finalize = Py_TYPE(op)->tp_finalize) != NULL) { (finalize = Py_TYPE(op)->tp_finalize) != NULL) {
_PyGCHead_SET_FINALIZED(gc); _PyGCHead_SET_FINALIZED(gc);
Py_INCREF(op); Py_INCREF(op);
......
...@@ -13032,8 +13032,7 @@ static PyTypeObject ScandirIteratorType = { ...@@ -13032,8 +13032,7 @@ static PyTypeObject ScandirIteratorType = {
0, /* tp_getattro */ 0, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT, /* tp_flags */
| Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
0, /* tp_doc */ 0, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
......
...@@ -5286,8 +5286,7 @@ static PyTypeObject sock_type = { ...@@ -5286,8 +5286,7 @@ static PyTypeObject sock_type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
| Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
sock_doc, /* tp_doc */ sock_doc, /* tp_doc */
0, /* tp_traverse */ 0, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
......
...@@ -123,7 +123,7 @@ static PyType_Spec Xxo_Type_spec = { ...@@ -123,7 +123,7 @@ static PyType_Spec Xxo_Type_spec = {
"xxlimited.Xxo", "xxlimited.Xxo",
sizeof(XxoObject), sizeof(XxoObject),
0, 0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Xxo_Type_slots Xxo_Type_slots
}; };
......
...@@ -742,8 +742,7 @@ PyTypeObject PyGen_Type = { ...@@ -742,8 +742,7 @@ PyTypeObject PyGen_Type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)gen_traverse, /* tp_traverse */ (traverseproc)gen_traverse, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
...@@ -997,8 +996,7 @@ PyTypeObject PyCoro_Type = { ...@@ -997,8 +996,7 @@ PyTypeObject PyCoro_Type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)gen_traverse, /* tp_traverse */ (traverseproc)gen_traverse, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
...@@ -1394,8 +1392,7 @@ PyTypeObject PyAsyncGen_Type = { ...@@ -1394,8 +1392,7 @@ PyTypeObject PyAsyncGen_Type = {
PyObject_GenericGetAttr, /* tp_getattro */ PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */ 0, /* tp_setattro */
0, /* tp_as_buffer */ 0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
0, /* tp_doc */ 0, /* tp_doc */
(traverseproc)async_gen_traverse, /* tp_traverse */ (traverseproc)async_gen_traverse, /* tp_traverse */
0, /* tp_clear */ 0, /* tp_clear */
......
...@@ -298,10 +298,7 @@ PyObject_CallFinalizer(PyObject *self) ...@@ -298,10 +298,7 @@ PyObject_CallFinalizer(PyObject *self)
{ {
PyTypeObject *tp = Py_TYPE(self); PyTypeObject *tp = Py_TYPE(self);
/* The former could happen on heaptypes created from the C API, e.g. if (tp->tp_finalize == NULL)
PyType_FromSpec(). */
if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_FINALIZE) ||
tp->tp_finalize == NULL)
return; return;
/* tp_finalize should only be called once. */ /* tp_finalize should only be called once. */
if (PyType_IS_GC(tp) && _PyGC_FINALIZED(self)) if (PyType_IS_GC(tp) && _PyGC_FINALIZED(self))
......
...@@ -248,8 +248,8 @@ PyType_Modified(PyTypeObject *type) ...@@ -248,8 +248,8 @@ PyType_Modified(PyTypeObject *type)
Invariants: Invariants:
- Py_TPFLAGS_VALID_VERSION_TAG is never set if - Py_TPFLAGS_VALID_VERSION_TAG is never set if
Py_TPFLAGS_HAVE_VERSION_TAG is not set (e.g. on type Py_TPFLAGS_HAVE_VERSION_TAG is not set (in case of a
objects coming from non-recompiled extension modules) bizarre MRO, see type_mro_modified()).
- before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type, - before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type,
it must first be set on all super types. it must first be set on all super types.
...@@ -2571,7 +2571,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) ...@@ -2571,7 +2571,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
/* Initialize tp_flags */ /* Initialize tp_flags */
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE |
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_FINALIZE; Py_TPFLAGS_BASETYPE;
if (base->tp_flags & Py_TPFLAGS_HAVE_GC) if (base->tp_flags & Py_TPFLAGS_HAVE_GC)
type->tp_flags |= Py_TPFLAGS_HAVE_GC; type->tp_flags |= Py_TPFLAGS_HAVE_GC;
...@@ -5179,10 +5179,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) ...@@ -5179,10 +5179,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
COPYSLOT(tp_init); COPYSLOT(tp_init);
COPYSLOT(tp_alloc); COPYSLOT(tp_alloc);
COPYSLOT(tp_is_gc); COPYSLOT(tp_is_gc);
if ((type->tp_flags & Py_TPFLAGS_HAVE_FINALIZE) && COPYSLOT(tp_finalize);
(base->tp_flags & Py_TPFLAGS_HAVE_FINALIZE)) {
COPYSLOT(tp_finalize);
}
if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) == if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) ==
(base->tp_flags & Py_TPFLAGS_HAVE_GC)) { (base->tp_flags & Py_TPFLAGS_HAVE_GC)) {
/* They agree about gc. */ /* They agree about gc. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment