Skip to content

Commit 632e8a6

Browse files
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 a4760cc) Co-authored-by: Petr Viktorin <[email protected]>
1 parent c589992 commit 632e8a6

File tree

7 files changed

+24
-56
lines changed

7 files changed

+24
-56
lines changed

Doc/c-api/typeobj.rst

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,8 +1097,7 @@ and :c:type:`PyType_Type` effectively act as defaults.)
10971097

10981098
This is a bitmask of all the bits that pertain to the existence of certain
10991099
fields in the type object and its extension structures. Currently, it includes
1100-
the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`,
1101-
:const:`Py_TPFLAGS_HAVE_VERSION_TAG`.
1100+
the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`.
11021101

11031102
**Inheritance:**
11041103

@@ -1178,14 +1177,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
11781177

11791178
.. versionadded:: 3.9
11801179

1181-
1182-
.. data:: Py_TPFLAGS_HAVE_AM_SEND
1183-
1184-
This bit is set when the :c:member:`~PyAsyncMethods.am_send` entry is present in the
1185-
:c:member:`~PyTypeObject.tp_as_async` slot of type structure.
1186-
1187-
.. versionadded:: 3.10
1188-
11891180
.. data:: Py_TPFLAGS_IMMUTABLETYPE
11901181

11911182
This bit is set for type objects that are immutable: type attributes cannot be set nor deleted.

Include/object.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -368,18 +368,12 @@ given type object has a specified feature.
368368
/* Objects behave like an unbound method */
369369
#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17)
370370

371-
/* Objects support type attribute cache */
372-
#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18)
371+
/* Object has up-to-date type attribute cache */
373372
#define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19)
374373

375374
/* Type is abstract and cannot be instantiated */
376375
#define Py_TPFLAGS_IS_ABSTRACT (1UL << 20)
377376

378-
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
379-
/* Type has am_send entry in tp_as_async slot */
380-
#define Py_TPFLAGS_HAVE_AM_SEND (1UL << 21)
381-
#endif
382-
383377
// This undocumented flag gives certain built-ins their unique pattern-matching
384378
// behavior, which allows a single positional subpattern to match against the
385379
// subject itself (rather than a mapped attribute on it):
@@ -397,19 +391,23 @@ given type object has a specified feature.
397391

398392
#define Py_TPFLAGS_DEFAULT ( \
399393
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
400-
Py_TPFLAGS_HAVE_VERSION_TAG | \
401394
0)
402395

403-
/* NOTE: The following flags reuse lower bits (removed as part of the
396+
/* NOTE: Some of the following flags reuse lower bits (removed as part of the
404397
* Python 3.0 transition). */
405398

406-
/* The following flag is kept for compatibility. Starting with 3.8,
407-
* binary compatibility of C extensions across feature releases of
408-
* Python is not supported anymore, except when using the stable ABI.
399+
/* The following flags are kept for compatibility; in previous
400+
* versions they indicated presence of newer tp_* fields on the
401+
* type struct.
402+
* Starting with 3.8, binary compatibility of C extensions across
403+
* feature releases of Python is not supported anymore (except when
404+
* using the stable ABI, in which all classes are created dynamically,
405+
* using the interpreter's memory layout.)
406+
* Note that older extensions using the stable ABI set these flags,
407+
* so the bits must not be repurposed.
409408
*/
410-
411-
/* Type structure has tp_finalize member (3.4) */
412409
#define Py_TPFLAGS_HAVE_FINALIZE (1UL << 0)
410+
#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18)
413411

414412

415413
/*
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The ``Py_TPFLAGS_HAVE_VERSION_TAG`` type flag now does nothing. The
2+
``Py_TPFLAGS_HAVE_AM_SEND`` flag (which was added in 3.10) is removed. Both
3+
were unnecessary because it is not possible to have type objects with the
4+
relevant fields missing.

Modules/_asynciomodule.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,8 +1764,7 @@ static PyTypeObject FutureIterType = {
17641764
.tp_dealloc = (destructor)FutureIter_dealloc,
17651765
.tp_as_async = &FutureIterType_as_async,
17661766
.tp_getattro = PyObject_GenericGetAttr,
1767-
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1768-
Py_TPFLAGS_HAVE_AM_SEND,
1767+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
17691768
.tp_traverse = (traverseproc)FutureIter_traverse,
17701769
.tp_iter = PyObject_SelfIter,
17711770
.tp_iternext = (iternextfunc)FutureIter_iternext,

Objects/abstract.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2804,9 +2804,7 @@ PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result)
28042804
_Py_IDENTIFIER(send);
28052805
assert(arg != NULL);
28062806
assert(result != NULL);
2807-
if (PyType_HasFeature(Py_TYPE(iter), Py_TPFLAGS_HAVE_AM_SEND)) {
2808-
assert (Py_TYPE(iter)->tp_as_async != NULL);
2809-
assert (Py_TYPE(iter)->tp_as_async->am_send != NULL);
2807+
if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) {
28102808
PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result);
28112809
assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR));
28122810
return res;

Objects/genobject.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,7 @@ PyTypeObject PyGen_Type = {
782782
PyObject_GenericGetAttr, /* tp_getattro */
783783
0, /* tp_setattro */
784784
0, /* tp_as_buffer */
785-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
786-
Py_TPFLAGS_HAVE_AM_SEND, /* tp_flags */
785+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
787786
0, /* tp_doc */
788787
(traverseproc)gen_traverse, /* tp_traverse */
789788
0, /* tp_clear */
@@ -1030,8 +1029,7 @@ PyTypeObject PyCoro_Type = {
10301029
PyObject_GenericGetAttr, /* tp_getattro */
10311030
0, /* tp_setattro */
10321031
0, /* tp_as_buffer */
1033-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1034-
Py_TPFLAGS_HAVE_AM_SEND, /* tp_flags */
1032+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
10351033
0, /* tp_doc */
10361034
(traverseproc)gen_traverse, /* tp_traverse */
10371035
0, /* tp_clear */
@@ -1415,8 +1413,7 @@ PyTypeObject PyAsyncGen_Type = {
14151413
PyObject_GenericGetAttr, /* tp_getattro */
14161414
0, /* tp_setattro */
14171415
0, /* tp_as_buffer */
1418-
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
1419-
Py_TPFLAGS_HAVE_AM_SEND, /* tp_flags */
1416+
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
14201417
0, /* tp_doc */
14211418
(traverseproc)async_gen_traverse, /* tp_traverse */
14221419
0, /* tp_clear */

Objects/typeobject.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,6 @@ PyType_Modified(PyTypeObject *type)
316316
317317
Invariants:
318318
319-
- Py_TPFLAGS_VALID_VERSION_TAG is never set if
320-
Py_TPFLAGS_HAVE_VERSION_TAG is not set (in case of a
321-
bizarre MRO, see type_mro_modified()).
322-
323319
- before Py_TPFLAGS_VALID_VERSION_TAG can be set on a type,
324320
it must first be set on all super types.
325321
@@ -371,9 +367,6 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
371367
PyObject *mro_meth = NULL;
372368
PyObject *type_mro_meth = NULL;
373369

374-
if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
375-
return;
376-
377370
if (custom) {
378371
mro_meth = lookup_maybe_method(
379372
(PyObject *)type, &PyId_mro, &unbound);
@@ -396,17 +389,15 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
396389
assert(PyType_Check(b));
397390
cls = (PyTypeObject *)b;
398391

399-
if (!_PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
400-
!PyType_IsSubtype(type, cls)) {
392+
if (!PyType_IsSubtype(type, cls)) {
401393
goto clear;
402394
}
403395
}
404396
return;
405397
clear:
406398
Py_XDECREF(mro_meth);
407399
Py_XDECREF(type_mro_meth);
408-
type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
409-
Py_TPFLAGS_VALID_VERSION_TAG);
400+
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
410401
type->tp_version_tag = 0; /* 0 is not a valid version tag */
411402
}
412403

@@ -423,8 +414,6 @@ assign_version_tag(struct type_cache *cache, PyTypeObject *type)
423414

424415
if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
425416
return 1;
426-
if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
427-
return 0;
428417
if (!_PyType_HasFeature(type, Py_TPFLAGS_READY))
429418
return 0;
430419

@@ -5968,14 +5957,6 @@ type_ready_checks(PyTypeObject *type)
59685957
_PyObject_ASSERT((PyObject *)type, type->tp_call != NULL);
59695958
}
59705959

5971-
/* Consistency check for Py_TPFLAGS_HAVE_AM_SEND - flag requires
5972-
* type->tp_as_async->am_send to be present.
5973-
*/
5974-
if (type->tp_flags & Py_TPFLAGS_HAVE_AM_SEND) {
5975-
_PyObject_ASSERT((PyObject *)type, type->tp_as_async != NULL);
5976-
_PyObject_ASSERT((PyObject *)type, type->tp_as_async->am_send != NULL);
5977-
}
5978-
59795960
/* Consistency checks for pattern matching
59805961
* Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING are mutually exclusive */
59815962
_PyObject_ASSERT((PyObject *)type, (type->tp_flags & COLLECTION_FLAGS) != COLLECTION_FLAGS);

0 commit comments

Comments
 (0)