[Python-checkins] bpo-42747: Remove Py_TPFLAGS_HAVE_AM_SEND and make Py_TPFLAGS_HAVE_VERSION_TAG no-op (GH-27260) (GH-27306)
encukou
webhook-mailer at python.org
Fri Jul 23 10:57:03 EDT 2021
https://github.com/python/cpython/commit/632e8a69593efb12ec58d90e624ddf249a7a1b65
commit: 632e8a69593efb12ec58d90e624ddf249a7a1b65
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: encukou <encukou at gmail.com>
date: 2021-07-23T16:56:53+02:00
summary:
bpo-42747: Remove Py_TPFLAGS_HAVE_AM_SEND and make Py_TPFLAGS_HAVE_VERSION_TAG no-op (GH-27260) (GH-27306)
* Remove code that checks Py_TPFLAGS_HAVE_VERSION_TAG
The field is always present in the type struct, as explained
in the added comment.
* Remove Py_TPFLAGS_HAVE_AM_SEND
The flag is not needed, and since it was added in 3.10 it can be removed now.
(cherry picked from commit a4760cc32d9e5dac7be262e9736eb30502cd7be3)
Co-authored-by: Petr Viktorin <encukou at gmail.com>
files:
A Misc/NEWS.d/next/C API/2021-07-20-16-21-06.bpo-42747.rRxjUY.rst
M Doc/c-api/typeobj.rst
M Include/object.h
M Modules/_asynciomodule.c
M Objects/abstract.c
M Objects/genobject.c
M Objects/typeobject.c
diff --git a/Doc/c-api/typeobj.rst b/Doc/c-api/typeobj.rst
index ea811158fa8739..5fda9b086c0062 100644
--- a/Doc/c-api/typeobj.rst
+++ b/Doc/c-api/typeobj.rst
@@ -1097,8 +1097,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
This is a bitmask of all the bits that pertain to the existence of certain
fields in the type object and its extension structures. Currently, it includes
- the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`,
- :const:`Py_TPFLAGS_HAVE_VERSION_TAG`.
+ the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`.
**Inheritance:**
@@ -1178,14 +1177,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. versionadded:: 3.9
-
- .. data:: Py_TPFLAGS_HAVE_AM_SEND
-
- This bit is set when the :c:member:`~PyAsyncMethods.am_send` entry is present in the
- :c:member:`~PyTypeObject.tp_as_async` slot of type structure.
-
- .. versionadded:: 3.10
-
.. data:: Py_TPFLAGS_IMMUTABLETYPE
This bit is set for type objects that are immutable: type attributes cannot be set nor deleted.
diff --git a/Include/object.h b/Include/object.h
index 109f535249cda8..9e6a8f4656af0e 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -368,18 +368,12 @@ given type object has a specified feature.
/* Objects behave like an unbound method */
#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17)
-/* Objects support type attribute cache */
-#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18)
+/* Object has up-to-date type attribute cache */
#define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19)
/* Type is abstract and cannot be instantiated */
#define Py_TPFLAGS_IS_ABSTRACT (1UL << 20)
-#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
-/* Type has am_send entry in tp_as_async slot */
-#define Py_TPFLAGS_HAVE_AM_SEND (1UL << 21)
-#endif
-
// This undocumented flag gives certain built-ins their unique pattern-matching
// behavior, which allows a single positional subpattern to match against the
// subject itself (rather than a mapped attribute on it):
@@ -397,19 +391,23 @@ given type object has a specified feature.
#define Py_TPFLAGS_DEFAULT ( \
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
- Py_TPFLAGS_HAVE_VERSION_TAG | \
0)
-/* NOTE: The following flags reuse lower bits (removed as part of the
+/* NOTE: Some of the following flags reuse lower bits (removed as part of the
* Python 3.0 transition). */
-/* The following flag is kept for compatibility. Starting with 3.8,
- * binary compatibility of C extensions across feature releases of
- * Python is not supported anymore, except when using the stable ABI.
+/* The following flags are kept for compatibility; in previous
+ * versions they indicated presence of newer tp_* fields on the
+ * type struct.
+ * Starting with 3.8, binary compatibility of C extensions across
+ * feature releases of Python is not supported anymore (except when
+ * using the stable ABI, in which all classes are created dynamically,
+ * using the interpreter's memory layout.)
+ * Note that older extensions using the stable ABI set these flags,
+ * so the bits must not be repurposed.
*/
-
-/* Type structure has tp_finalize member (3.4) */
#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0)
+#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18)
/*
diff --git a/Misc/NEWS.d/next/C API/2021-07-20-16-21-06.bpo-42747.rRxjUY.rst b/Misc/NEWS.d/next/C API/2021-07-20-16-21-06.bpo-42747.rRxjUY.rst
new file mode 100644
index 00000000000000..c7ac5a776e2ed9
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2021-07-20-16-21-06.bpo-42747.rRxjUY.rst
@@ -0,0 +1,4 @@
+The ``Py_TPFLAGS_HAVE_VERSION_TAG`` type flag now does nothing. The
+``Py_TPFLAGS_HAVE_AM_SEND`` flag (which was added in 3.10) is removed. Both
+were unnecessary because it is not possible to have type objects with the
+relevant fields missing.
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c
index a4d5d4551e9b0a..ecc73d1ca8bf0f 100644
--- a/Modules/_asynciomodule.c
+++ b/Modules/_asynciomodule.c
@@ -1764,8 +1764,7 @@ static PyTypeObject FutureIterType = {
.tp_dealloc = (destructor)FutureIter_dealloc,
.tp_as_async = &FutureIterType_as_async,
.tp_getattro = PyObject_GenericGetAttr,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
- Py_TPFLAGS_HAVE_AM_SEND,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.tp_traverse = (traverseproc)FutureIter_traverse,
.tp_iter = PyObject_SelfIter,
.tp_iternext = (iternextfunc)FutureIter_iternext,
diff --git a/Objects/abstract.c b/Objects/abstract.c
index f14a923c4739be..842c36780de301 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -2804,9 +2804,7 @@ PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result)
_Py_IDENTIFIER(send);
assert(arg != NULL);
assert(result != NULL);
- if (PyType_HasFeature(Py_TYPE(iter), Py_TPFLAGS_HAVE_AM_SEND)) {
- assert (Py_TYPE(iter)->tp_as_async != NULL);
- assert (Py_TYPE(iter)->tp_as_async->am_send != NULL);
+ if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) {
PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result);
assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR));
return res;
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 1889df1d137786..3ac38de0c311bc 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -782,8 +782,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_AM_SEND, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)gen_traverse, /* tp_traverse */
0, /* tp_clear */
@@ -1030,8 +1029,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_AM_SEND, /* tp_flags */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
0, /* tp_doc */
(traverseproc)gen_traverse, /* tp_traverse */
0, /* tp_clear */
@@ -1415,8 +1413,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_AM_SEND, /* 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/typeobject.c b/Objects/typeobject.c
index 21e90e13e381ac..a84a17de06f13a 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -316,10 +316,6 @@ PyType_Modified(PyTypeObject *type)
Invariants:
- - Py_TPFLAGS_VALID_VERSION_TAG is never set if
- 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.
@@ -371,9 +367,6 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
PyObject *mro_meth = NULL;
PyObject *type_mro_meth = NULL;
- if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
- return;
-
if (custom) {
mro_meth = lookup_maybe_method(
(PyObject *)type, &PyId_mro, &unbound);
@@ -396,8 +389,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
assert(PyType_Check(b));
cls = (PyTypeObject *)b;
- if (!_PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
- !PyType_IsSubtype(type, cls)) {
+ if (!PyType_IsSubtype(type, cls)) {
goto clear;
}
}
@@ -405,8 +397,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
clear:
Py_XDECREF(mro_meth);
Py_XDECREF(type_mro_meth);
- type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
- Py_TPFLAGS_VALID_VERSION_TAG);
+ type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
type->tp_version_tag = 0; /* 0 is not a valid version tag */
}
@@ -423,8 +414,6 @@ assign_version_tag(struct type_cache *cache, PyTypeObject *type)
if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
return 1;
- if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
- return 0;
if (!_PyType_HasFeature(type, Py_TPFLAGS_READY))
return 0;
@@ -5968,14 +5957,6 @@ type_ready_checks(PyTypeObject *type)
_PyObject_ASSERT((PyObject *)type, type->tp_call != NULL);
}
- /* Consistency check for Py_TPFLAGS_HAVE_AM_SEND - flag requires
- * type->tp_as_async->am_send to be present.
- */
- if (type->tp_flags & Py_TPFLAGS_HAVE_AM_SEND) {
- _PyObject_ASSERT((PyObject *)type, type->tp_as_async != NULL);
- _PyObject_ASSERT((PyObject *)type, type->tp_as_async->am_send != NULL);
- }
-
/* Consistency checks for pattern matching
* Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING are mutually exclusive */
_PyObject_ASSERT((PyObject *)type, (type->tp_flags & COLLECTION_FLAGS) != COLLECTION_FLAGS);
More information about the Python-checkins
mailing list