From fa4092259763ffad45a5bb9ef55f515dc6a69ad2 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 8 Nov 2024 16:44:44 +0000 Subject: [PATCH] GH-126547: Pre-assign version numbers for a few common classes (GH-126551) --- Include/internal/pycore_runtime_init.h | 2 +- Include/internal/pycore_typeobject.h | 15 +++++++++++++++ Objects/bytearrayobject.c | 1 + Objects/bytesobject.c | 1 + Objects/complexobject.c | 1 + Objects/dictobject.c | 1 + Objects/floatobject.c | 1 + Objects/listobject.c | 1 + Objects/longobject.c | 1 + Objects/setobject.c | 2 ++ Objects/tupleobject.c | 1 + Objects/typeobject.c | 4 +++- 12 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h index bd3d704cb77..8a8f47695fb 100644 --- a/Include/internal/pycore_runtime_init.h +++ b/Include/internal/pycore_runtime_init.h @@ -87,7 +87,7 @@ extern PyTypeObject _PyExc_MemoryError; .double_format = _py_float_format_unknown, \ }, \ .types = { \ - .next_version_tag = 1, \ + .next_version_tag = _Py_TYPE_VERSION_NEXT, \ }, \ .static_objects = { \ .singletons = { \ diff --git a/Include/internal/pycore_typeobject.h b/Include/internal/pycore_typeobject.h index e72592b8e98..5debdd68fe9 100644 --- a/Include/internal/pycore_typeobject.h +++ b/Include/internal/pycore_typeobject.h @@ -14,6 +14,21 @@ extern "C" { /* state */ +#define _Py_TYPE_VERSION_INT 1 +#define _Py_TYPE_VERSION_FLOAT 2 +#define _Py_TYPE_VERSION_LIST 3 +#define _Py_TYPE_VERSION_TUPLE 4 +#define _Py_TYPE_VERSION_STR 5 +#define _Py_TYPE_VERSION_SET 6 +#define _Py_TYPE_VERSION_FROZEN_SET 7 +#define _Py_TYPE_VERSION_DICT 8 +#define _Py_TYPE_VERSION_BYTEARRAY 9 +#define _Py_TYPE_VERSION_BYTES 10 +#define _Py_TYPE_VERSION_COMPLEX 11 + +#define _Py_TYPE_VERSION_NEXT 16 + + #define _Py_TYPE_BASE_VERSION_TAG (2<<16) #define _Py_MAX_GLOBAL_TYPE_VERSION_TAG (_Py_TYPE_BASE_VERSION_TAG - 1) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index fd2a85a3fe0..5a52b2f702a 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2452,6 +2452,7 @@ PyTypeObject PyByteArray_Type = { PyType_GenericAlloc, /* tp_alloc */ PyType_GenericNew, /* tp_new */ PyObject_Free, /* tp_free */ + .tp_version_tag = _Py_TYPE_VERSION_BYTEARRAY, }; /*********************** Bytearray Iterator ****************************/ diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index dcc1aba76ab..ac02cfe7cf0 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3080,6 +3080,7 @@ PyTypeObject PyBytes_Type = { bytes_alloc, /* tp_alloc */ bytes_new, /* tp_new */ PyObject_Free, /* tp_free */ + .tp_version_tag = _Py_TYPE_VERSION_BYTES, }; void diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 787235c63a6..7b4948fc8eb 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -1250,4 +1250,5 @@ PyTypeObject PyComplex_Type = { PyType_GenericAlloc, /* tp_alloc */ actual_complex_new, /* tp_new */ PyObject_Free, /* tp_free */ + .tp_version_tag = _Py_TYPE_VERSION_COMPLEX, }; diff --git a/Objects/dictobject.c b/Objects/dictobject.c index f28a9265783..2090008055b 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -4912,6 +4912,7 @@ PyTypeObject PyDict_Type = { dict_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ .tp_vectorcall = dict_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_DICT, }; /* For backward compatibility with old dictionary interface */ diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 7e14a8ad959..f00b6a6b4b2 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1916,6 +1916,7 @@ PyTypeObject PyFloat_Type = { 0, /* tp_alloc */ float_new, /* tp_new */ .tp_vectorcall = (vectorcallfunc)float_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_FLOAT, }; static void diff --git a/Objects/listobject.c b/Objects/listobject.c index 930aefde325..bb0040cbe9f 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -3774,6 +3774,7 @@ PyTypeObject PyList_Type = { PyType_GenericNew, /* tp_new */ PyObject_GC_Del, /* tp_free */ .tp_vectorcall = list_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_LIST, }; /*********************** List Iterator **************************/ diff --git a/Objects/longobject.c b/Objects/longobject.c index 4e948940485..b4c0f63a984 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -6584,6 +6584,7 @@ PyTypeObject PyLong_Type = { long_new, /* tp_new */ PyObject_Free, /* tp_free */ .tp_vectorcall = long_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_INT, }; static PyTypeObject Int_InfoType; diff --git a/Objects/setobject.c b/Objects/setobject.c index 2671792190d..955ccbebf74 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -2520,6 +2520,7 @@ PyTypeObject PySet_Type = { set_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ .tp_vectorcall = set_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_SET, }; /* frozenset object ********************************************************/ @@ -2610,6 +2611,7 @@ PyTypeObject PyFrozenSet_Type = { frozenset_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ .tp_vectorcall = frozenset_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_FROZEN_SET, }; diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index f3132e0933a..193914d54bd 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -909,6 +909,7 @@ PyTypeObject PyTuple_Type = { tuple_new, /* tp_new */ PyObject_GC_Del, /* tp_free */ .tp_vectorcall = tuple_vectorcall, + .tp_version_tag = _Py_TYPE_VERSION_TUPLE, }; /* The following function breaks the notion that tuples are immutable: diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 88db29e14b0..4af7f0273aa 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -8613,7 +8613,9 @@ init_static_type(PyInterpreterState *interp, PyTypeObject *self, self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; assert(NEXT_GLOBAL_VERSION_TAG <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG); - _PyType_SetVersion(self, NEXT_GLOBAL_VERSION_TAG++); + if (self->tp_version_tag == 0) { + _PyType_SetVersion(self, NEXT_GLOBAL_VERSION_TAG++); + } } else { assert(!initial);