mirror of https://github.com/python/cpython
bpo-42747: Remove Py_TPFLAGS_HAVE_AM_SEND and make Py_TPFLAGS_HAVE_VERSION_TAG no-op (GH-27260)
* 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.
This commit is contained in:
parent
7d28a6eb90
commit
a4760cc32d
|
@ -1098,8 +1098,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
|
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
|
fields in the type object and its extension structures. Currently, it includes
|
||||||
the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`,
|
the following bits: :const:`Py_TPFLAGS_HAVE_STACKLESS_EXTENSION`.
|
||||||
:const:`Py_TPFLAGS_HAVE_VERSION_TAG`.
|
|
||||||
|
|
||||||
**Inheritance:**
|
**Inheritance:**
|
||||||
|
|
||||||
|
@ -1179,14 +1178,6 @@ and :c:type:`PyType_Type` effectively act as defaults.)
|
||||||
|
|
||||||
.. versionadded:: 3.9
|
.. 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
|
.. data:: Py_TPFLAGS_IMMUTABLETYPE
|
||||||
|
|
||||||
This bit is set for type objects that are immutable: type attributes cannot be set nor deleted.
|
This bit is set for type objects that are immutable: type attributes cannot be set nor deleted.
|
||||||
|
|
|
@ -368,18 +368,12 @@ given type object has a specified feature.
|
||||||
/* Objects behave like an unbound method */
|
/* Objects behave like an unbound method */
|
||||||
#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17)
|
#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17)
|
||||||
|
|
||||||
/* Objects support type attribute cache */
|
/* Object has up-to-date type attribute cache */
|
||||||
#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18)
|
|
||||||
#define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19)
|
#define Py_TPFLAGS_VALID_VERSION_TAG (1UL << 19)
|
||||||
|
|
||||||
/* Type is abstract and cannot be instantiated */
|
/* Type is abstract and cannot be instantiated */
|
||||||
#define Py_TPFLAGS_IS_ABSTRACT (1UL << 20)
|
#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
|
// This undocumented flag gives certain built-ins their unique pattern-matching
|
||||||
// behavior, which allows a single positional subpattern to match against the
|
// behavior, which allows a single positional subpattern to match against the
|
||||||
// subject itself (rather than a mapped attribute on it):
|
// subject itself (rather than a mapped attribute on it):
|
||||||
|
@ -397,19 +391,23 @@ given type object has a specified feature.
|
||||||
|
|
||||||
#define Py_TPFLAGS_DEFAULT ( \
|
#define Py_TPFLAGS_DEFAULT ( \
|
||||||
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
|
Py_TPFLAGS_HAVE_STACKLESS_EXTENSION | \
|
||||||
Py_TPFLAGS_HAVE_VERSION_TAG | \
|
|
||||||
0)
|
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). */
|
* Python 3.0 transition). */
|
||||||
|
|
||||||
/* The following flag is kept for compatibility. Starting with 3.8,
|
/* The following flags are kept for compatibility; in previous
|
||||||
* binary compatibility of C extensions across feature releases of
|
* versions they indicated presence of newer tp_* fields on the
|
||||||
* Python is not supported anymore, except when using the stable ABI.
|
* 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_FINALIZE (1UL << 0)
|
||||||
|
#define Py_TPFLAGS_HAVE_VERSION_TAG (1UL << 18)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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.
|
|
@ -1764,8 +1764,7 @@ static PyTypeObject FutureIterType = {
|
||||||
.tp_dealloc = (destructor)FutureIter_dealloc,
|
.tp_dealloc = (destructor)FutureIter_dealloc,
|
||||||
.tp_as_async = &FutureIterType_as_async,
|
.tp_as_async = &FutureIterType_as_async,
|
||||||
.tp_getattro = PyObject_GenericGetAttr,
|
.tp_getattro = PyObject_GenericGetAttr,
|
||||||
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
|
||||||
Py_TPFLAGS_HAVE_AM_SEND,
|
|
||||||
.tp_traverse = (traverseproc)FutureIter_traverse,
|
.tp_traverse = (traverseproc)FutureIter_traverse,
|
||||||
.tp_iter = PyObject_SelfIter,
|
.tp_iter = PyObject_SelfIter,
|
||||||
.tp_iternext = (iternextfunc)FutureIter_iternext,
|
.tp_iternext = (iternextfunc)FutureIter_iternext,
|
||||||
|
|
|
@ -2804,9 +2804,7 @@ PyIter_Send(PyObject *iter, PyObject *arg, PyObject **result)
|
||||||
_Py_IDENTIFIER(send);
|
_Py_IDENTIFIER(send);
|
||||||
assert(arg != NULL);
|
assert(arg != NULL);
|
||||||
assert(result != NULL);
|
assert(result != NULL);
|
||||||
if (PyType_HasFeature(Py_TYPE(iter), Py_TPFLAGS_HAVE_AM_SEND)) {
|
if (Py_TYPE(iter)->tp_as_async && Py_TYPE(iter)->tp_as_async->am_send) {
|
||||||
assert (Py_TYPE(iter)->tp_as_async != NULL);
|
|
||||||
assert (Py_TYPE(iter)->tp_as_async->am_send != NULL);
|
|
||||||
PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result);
|
PySendResult res = Py_TYPE(iter)->tp_as_async->am_send(iter, arg, result);
|
||||||
assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR));
|
assert(_Py_CheckSlotResult(iter, "am_send", res != PYGEN_ERROR));
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -782,8 +782,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_AM_SEND, /* tp_flags */
|
|
||||||
0, /* tp_doc */
|
0, /* tp_doc */
|
||||||
(traverseproc)gen_traverse, /* tp_traverse */
|
(traverseproc)gen_traverse, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
|
@ -1029,8 +1028,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_AM_SEND, /* tp_flags */
|
|
||||||
0, /* tp_doc */
|
0, /* tp_doc */
|
||||||
(traverseproc)gen_traverse, /* tp_traverse */
|
(traverseproc)gen_traverse, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
|
@ -1415,8 +1413,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_AM_SEND, /* 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 */
|
||||||
|
|
|
@ -324,10 +324,6 @@ PyType_Modified(PyTypeObject *type)
|
||||||
|
|
||||||
Invariants:
|
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,
|
- 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.
|
||||||
|
|
||||||
|
@ -379,9 +375,6 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
|
||||||
PyObject *mro_meth = NULL;
|
PyObject *mro_meth = NULL;
|
||||||
PyObject *type_mro_meth = NULL;
|
PyObject *type_mro_meth = NULL;
|
||||||
|
|
||||||
if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (custom) {
|
if (custom) {
|
||||||
mro_meth = lookup_maybe_method(
|
mro_meth = lookup_maybe_method(
|
||||||
(PyObject *)type, &PyId_mro, &unbound);
|
(PyObject *)type, &PyId_mro, &unbound);
|
||||||
|
@ -404,8 +397,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
|
||||||
assert(PyType_Check(b));
|
assert(PyType_Check(b));
|
||||||
cls = (PyTypeObject *)b;
|
cls = (PyTypeObject *)b;
|
||||||
|
|
||||||
if (!_PyType_HasFeature(cls, Py_TPFLAGS_HAVE_VERSION_TAG) ||
|
if (!PyType_IsSubtype(type, cls)) {
|
||||||
!PyType_IsSubtype(type, cls)) {
|
|
||||||
goto clear;
|
goto clear;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,8 +405,7 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) {
|
||||||
clear:
|
clear:
|
||||||
Py_XDECREF(mro_meth);
|
Py_XDECREF(mro_meth);
|
||||||
Py_XDECREF(type_mro_meth);
|
Py_XDECREF(type_mro_meth);
|
||||||
type->tp_flags &= ~(Py_TPFLAGS_HAVE_VERSION_TAG|
|
type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
|
||||||
Py_TPFLAGS_VALID_VERSION_TAG);
|
|
||||||
type->tp_version_tag = 0; /* 0 is not a valid version tag */
|
type->tp_version_tag = 0; /* 0 is not a valid version tag */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,8 +422,6 @@ assign_version_tag(struct type_cache *cache, PyTypeObject *type)
|
||||||
|
|
||||||
if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
|
if (_PyType_HasFeature(type, Py_TPFLAGS_VALID_VERSION_TAG))
|
||||||
return 1;
|
return 1;
|
||||||
if (!_PyType_HasFeature(type, Py_TPFLAGS_HAVE_VERSION_TAG))
|
|
||||||
return 0;
|
|
||||||
if (!_PyType_HasFeature(type, Py_TPFLAGS_READY))
|
if (!_PyType_HasFeature(type, Py_TPFLAGS_READY))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -5978,14 +5967,6 @@ type_ready_pre_checks(PyTypeObject *type)
|
||||||
_PyObject_ASSERT((PyObject *)type, type->tp_call != NULL);
|
_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
|
/* Consistency checks for pattern matching
|
||||||
* Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING are mutually exclusive */
|
* Py_TPFLAGS_SEQUENCE and Py_TPFLAGS_MAPPING are mutually exclusive */
|
||||||
_PyObject_ASSERT((PyObject *)type, (type->tp_flags & COLLECTION_FLAGS) != COLLECTION_FLAGS);
|
_PyObject_ASSERT((PyObject *)type, (type->tp_flags & COLLECTION_FLAGS) != COLLECTION_FLAGS);
|
||||||
|
|
Loading…
Reference in New Issue