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.
diff --git a/Objects/genobject.c b/Objects/genobject.c
index e2def38..0d0a02d 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -742,8 +742,7 @@
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)gen_traverse, /* tp_traverse */
0, /* tp_clear */
@@ -997,8 +996,7 @@
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)gen_traverse, /* tp_traverse */
0, /* tp_clear */
@@ -1394,8 +1392,7 @@
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)async_gen_traverse, /* tp_traverse */
0, /* tp_clear */
diff --git a/Objects/object.c b/Objects/object.c
index 87dba98..f9c75b7 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -298,10 +298,7 @@
{
PyTypeObject *tp = Py_TYPE(self);
- /* The former could happen on heaptypes created from the C API, e.g.
- PyType_FromSpec(). */
- if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_FINALIZE) ||
- tp->tp_finalize == NULL)
+ if (tp->tp_finalize == NULL)
return;
/* tp_finalize should only be called once. */
if (PyType_IS_GC(tp) && _PyGC_FINALIZED(self))
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c14cbad..071ff27 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -248,8 +248,8 @@
Invariants:
- Py_TPFLAGS_VALID_VERSION_TAG is never set if
- Py_TPFLAGS_HAVE_VERSION_TAG is not set (e.g. on type
- objects coming from non-recompiled extension modules)
+ Py_TPFLAGS_HAVE_VERSION_TAG is not set (in case of a
+ bizarre MRO, see type_mro_modified()).
- before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type,
it must first be set on all super types.
@@ -2571,7 +2571,7 @@
/* Initialize tp_flags */
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)
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
@@ -5179,10 +5179,7 @@
COPYSLOT(tp_init);
COPYSLOT(tp_alloc);
COPYSLOT(tp_is_gc);
- if ((type->tp_flags & Py_TPFLAGS_HAVE_FINALIZE) &&
- (base->tp_flags & Py_TPFLAGS_HAVE_FINALIZE)) {
- COPYSLOT(tp_finalize);
- }
+ COPYSLOT(tp_finalize);
if ((type->tp_flags & Py_TPFLAGS_HAVE_GC) ==
(base->tp_flags & Py_TPFLAGS_HAVE_GC)) {
/* They agree about gc. */