From 19770aeee5ae27f32f1271affc8913a6566418d5 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 6 May 2019 18:31:07 +0200 Subject: [PATCH 1/3] bpo-32388: Remove cross-version binary compatibility requirement in tp_flags It is now allowed to add new fields at the end of the PyTypeObject struct (and even in the middle, if we are so inclined) in feature releases 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. --- Doc/c-api/typeobj.rst | 5 +++++ Doc/whatsnew/3.8.rst | 7 +++++++ Include/object.h | 21 +++++++++++-------- .../2017-12-21-20-37-40.bpo-32388.6w-i5t.rst | 1 + Modules/_asynciomodule.c | 6 ++---- Modules/_io/bufferedio.c | 11 +++++----- Modules/_io/fileio.c | 6 +++--- Modules/_io/iobase.c | 4 ++-- Modules/_io/textio.c | 5 ++--- Modules/_io/winconsoleio.c | 2 +- Modules/_testmultiphase.c | 2 +- Modules/gcmodule.c | 1 - Modules/posixmodule.c | 3 +-- Modules/socketmodule.c | 3 +-- Modules/xxlimited.c | 2 +- Objects/genobject.c | 9 +++----- Objects/object.c | 5 +---- Objects/typeobject.c | 11 ++++------ 18 files changed, 52 insertions(+), 52 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst index 0647a493303d263..7b4638bdf6249d3 100644 --- a/Doc/c-api/typeobj.rst +++ b/Doc/c-api/typeobj.rst @@ -1073,6 +1073,11 @@ and :c:type:`PyType_Type` effectively act as defaults.) .. 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 diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 64ef6e1840605b4..40e6dd478e70827 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1019,6 +1019,13 @@ Changes in the C API (Contributed by Eddie Elizondo in :issue:`35810`.) +* 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`). + CPython bytecode changes ------------------------ diff --git a/Include/object.h b/Include/object.h index 13e88a6dc6f02a6..1eea0d46b65acc7 100644 --- a/Include/object.h +++ b/Include/object.h @@ -263,17 +263,14 @@ PyAPI_FUNC(void) Py_ReprLeave(PyObject *); #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 -fashion. Extensions can use the flags to indicate (and test) when a given -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). +These flags are used to change expected features and behavior for a +particular type. Arbitration of the flag bit positions will need to be coordinated among 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 flags are not for backwards compatibility but to indicate the presence of an @@ -297,7 +294,7 @@ given type object has a specified feature. /* Set while the type is being 'readied', to prevent recursive ready calls */ #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) /* These two bits are preserved for Stackless Python, next after this is 17 */ @@ -332,8 +329,14 @@ given type object has a specified feature. /* NOTE: The following flags reuse lower bits (removed as part of the * Python 3.0 transition). */ +/* The following flags are kept for compatibility, but all types are + * supposed to support the given functionality. 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) */ -#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) +#define Py_TPFLAGS_HAVE_FINALIZE Py_TPFLAGS_DEFAULT #ifdef Py_LIMITED_API # define PyType_HasFeature(t,f) ((PyType_GetFlags(t) & (f)) != 0) diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst b/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst new file mode 100644 index 000000000000000..60615d47f60d4dd --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-12-21-20-37-40.bpo-32388.6w-i5t.rst @@ -0,0 +1 @@ +Remove cross-version binary compatibility requirement in tp_flags. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index f9037c279ac9c34..7e71c749499d838 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -1431,8 +1431,7 @@ static PyTypeObject FutureType = { .tp_dealloc = FutureObj_dealloc, .tp_as_async = &FutureType_as_async, .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .tp_doc = _asyncio_Future___init____doc__, .tp_traverse = (traverseproc)FutureObj_traverse, .tp_clear = (inquiry)FutureObj_clear, @@ -2462,8 +2461,7 @@ static PyTypeObject TaskType = { .tp_dealloc = TaskObj_dealloc, .tp_as_async = &FutureType_as_async, .tp_repr = (reprfunc)FutureObj_repr, - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, .tp_doc = _asyncio_Task___init____doc__, .tp_traverse = (traverseproc)TaskObj_traverse, .tp_clear = (inquiry)TaskObj_clear, diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c index 6f855b9edd08428..9c0eeb56860eea2 100644 --- a/Modules/_io/bufferedio.c +++ b/Modules/_io/bufferedio.c @@ -2342,8 +2342,7 @@ PyTypeObject PyBufferedIOBase_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ bufferediobase_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -2434,7 +2433,7 @@ PyTypeObject PyBufferedReader_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ 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 */ (traverseproc)buffered_traverse, /* tp_traverse */ (inquiry)buffered_clear, /* tp_clear */ @@ -2520,7 +2519,7 @@ PyTypeObject PyBufferedWriter_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ 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 */ (traverseproc)buffered_traverse, /* tp_traverse */ (inquiry)buffered_clear, /* tp_clear */ @@ -2597,7 +2596,7 @@ PyTypeObject PyBufferedRWPair_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ 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 */ (traverseproc)bufferedrwpair_traverse, /* tp_traverse */ (inquiry)bufferedrwpair_clear, /* tp_clear */ @@ -2691,7 +2690,7 @@ PyTypeObject PyBufferedRandom_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ 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 */ (traverseproc)buffered_traverse, /* tp_traverse */ (inquiry)buffered_clear, /* tp_clear */ diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c index c502c430134ef6c..fc3a30ec6d157dd 100644 --- a/Modules/_io/fileio.c +++ b/Modules/_io/fileio.c @@ -1196,12 +1196,12 @@ PyTypeObject PyFileIO_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ 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 */ (traverseproc)fileio_traverse, /* tp_traverse */ (inquiry)fileio_clear, /* tp_clear */ 0, /* tp_richcompare */ - offsetof(fileio, weakreflist), /* tp_weaklistoffset */ + offsetof(fileio, weakreflist), /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ fileio_methods, /* tp_methods */ @@ -1211,7 +1211,7 @@ PyTypeObject PyFileIO_Type = { 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ - offsetof(fileio, dict), /* tp_dictoffset */ + offsetof(fileio, dict), /* tp_dictoffset */ _io_FileIO___init__, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ fileio_new, /* tp_new */ diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c index 6a0d9bec5af3205..f357a2410ad12df 100644 --- a/Modules/_io/iobase.c +++ b/Modules/_io/iobase.c @@ -856,7 +856,7 @@ PyTypeObject PyIOBase_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ 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 */ (traverseproc)iobase_traverse, /* tp_traverse */ (inquiry)iobase_clear, /* tp_clear */ @@ -1051,7 +1051,7 @@ PyTypeObject PyRawIOBase_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 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 */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c index 8c391659ecd8672..c71344289086ec9 100644 --- a/Modules/_io/textio.c +++ b/Modules/_io/textio.c @@ -183,8 +183,7 @@ PyTypeObject PyTextIOBase_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ textiobase_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ @@ -3184,7 +3183,7 @@ PyTypeObject PyTextIOWrapper_Type = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ 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 */ (traverseproc)textiowrapper_traverse, /* tp_traverse */ (inquiry)textiowrapper_clear, /* tp_clear */ diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 70a723ed746a75c..7700bd5b7c0d316 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -1133,7 +1133,7 @@ PyTypeObject PyWindowsConsoleIO_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ 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 */ (traverseproc)winconsoleio_traverse, /* tp_traverse */ (inquiry)winconsoleio_clear, /* tp_clear */ diff --git a/Modules/_testmultiphase.c b/Modules/_testmultiphase.c index db5bb7d6b8a22d8..4933abbabbe307e 100644 --- a/Modules/_testmultiphase.c +++ b/Modules/_testmultiphase.c @@ -98,7 +98,7 @@ static PyType_Spec Example_Type_spec = { "_testimportexec.Example", sizeof(ExampleObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, Example_Type_slots }; diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c index be9b73a8446073a..26e6afcfad38636 100644 --- a/Modules/gcmodule.c +++ b/Modules/gcmodule.c @@ -858,7 +858,6 @@ finalize_garbage(PyGC_Head *collectable) PyObject *op = FROM_GC(gc); gc_list_move(gc, &seen); if (!_PyGCHead_FINALIZED(gc) && - PyType_HasFeature(Py_TYPE(op), Py_TPFLAGS_HAVE_FINALIZE) && (finalize = Py_TYPE(op)->tp_finalize) != NULL) { _PyGCHead_SET_FINALIZED(gc); Py_INCREF(op); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 221f7101b21356f..cc7f4eac3c6e662 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -12905,8 +12905,7 @@ static PyTypeObject ScandirIteratorType = { 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT - | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index c024542fe70923c..5945c1f6c9b787c 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -5245,8 +5245,7 @@ static PyTypeObject sock_type = { PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE - | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ sock_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Modules/xxlimited.c b/Modules/xxlimited.c index 190f9937d0de9f4..ffc04e0310e3927 100644 --- a/Modules/xxlimited.c +++ b/Modules/xxlimited.c @@ -123,7 +123,7 @@ static PyType_Spec Xxo_Type_spec = { "xxlimited.Xxo", sizeof(XxoObject), 0, - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_HAVE_FINALIZE, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, Xxo_Type_slots }; diff --git a/Objects/genobject.c b/Objects/genobject.c index e2def38af541a55..0d0a02d76ccf21f 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -742,8 +742,7 @@ PyTypeObject PyGen_Type = { 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 @@ PyTypeObject PyCoro_Type = { 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 @@ PyTypeObject PyAsyncGen_Type = { 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 589bf365e870fdf..00f8ae05a146985 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -297,10 +297,7 @@ PyObject_CallFinalizer(PyObject *self) { 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 eeaae1f9f789475..54829ca5dfffd43 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -245,8 +245,8 @@ PyType_Modified(PyTypeObject *type) 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. @@ -2613,7 +2613,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) /* 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; @@ -5201,10 +5201,7 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base) 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. */ From 918263413b91cd40c4c5e1a093cb8feef8ab994e Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Mon, 6 May 2019 20:23:49 +0200 Subject: [PATCH 2/3] Address review comments --- Doc/whatsnew/3.8.rst | 2 ++ Include/object.h | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.8.rst b/Doc/whatsnew/3.8.rst index 40e6dd478e70827..392f8869c2ea0c1 100644 --- a/Doc/whatsnew/3.8.rst +++ b/Doc/whatsnew/3.8.rst @@ -1026,6 +1026,8 @@ Changes in the C API :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 ------------------------ diff --git a/Include/object.h b/Include/object.h index 1eea0d46b65acc7..b1f7bb49ef176e9 100644 --- a/Include/object.h +++ b/Include/object.h @@ -329,8 +329,7 @@ given type object has a specified feature. /* NOTE: The following flags reuse lower bits (removed as part of the * Python 3.0 transition). */ -/* The following flags are kept for compatibility, but all types are - * supposed to support the given functionality. Starting with 3.8, +/* 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. */ From 8dc3ca241a1ee3bd509a5621ab13ec6e63d6453b Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Wed, 29 May 2019 21:36:24 +0200 Subject: [PATCH 3/3] Restore previous tp_flag value --- Include/object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/object.h b/Include/object.h index 42f8cca5927aeaa..cc98d8a1def7e7a 100644 --- a/Include/object.h +++ b/Include/object.h @@ -343,7 +343,7 @@ given type object has a specified feature. */ /* Type structure has tp_finalize member (3.4) */ -#define Py_TPFLAGS_HAVE_FINALIZE Py_TPFLAGS_DEFAULT +#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0) #ifdef Py_LIMITED_API # define PyType_HasFeature(t,f) ((PyType_GetFlags(t) & (f)) != 0)