From 541834ae673718144cf582788f97c60ad7f672ee Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 29 Apr 2026 10:19:41 +0200 Subject: [PATCH 1/4] gh-145497: Use same size of static_types array in all builds When someone adds a new type but doesn't increment `_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES` or `_Py_MAX_MANAGED_STATIC_EXT_TYPES`, JIT tests fail, because JIT builds define an extra type. But the JIT tests don't necessarily run for the commit that causes the failure. As a workaround, use the same size for the array for all builds, potentially with an empty spot. --- Include/internal/pycore_interp_structs.h | 4 +++- Objects/object.c | 10 +++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index 2bfb84da36cbc8..58961bf51d54f4 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -528,7 +528,9 @@ struct _py_func_state { /* For now we hard-code this to a value for which we are confident all the static builtin types will fit (for all builds). */ -#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES 202 +#define _Py_NUM_MANAGED_PREINITIALIZED_TYPES 119 +#define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES \ + (_Py_NUM_MANAGED_PREINITIALIZED_TYPES + 83) #define _Py_MAX_MANAGED_STATIC_EXT_TYPES 10 #define _Py_MAX_MANAGED_STATIC_TYPES \ (_Py_MAX_MANAGED_STATIC_BUILTIN_TYPES + _Py_MAX_MANAGED_STATIC_EXT_TYPES) diff --git a/Objects/object.c b/Objects/object.c index 3166254f6f640b..d3cc62acdeaef8 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2526,7 +2526,7 @@ extern PyTypeObject _PyMemoryIter_Type; extern PyTypeObject _PyPositionsIterator; extern PyTypeObject _Py_GenericAliasIterType; -static PyTypeObject* static_types[] = { +static PyTypeObject* static_types[_Py_NUM_MANAGED_PREINITIALIZED_TYPES] = { // The two most important base types: must be initialized first and // deallocated last. &PyBaseObject_Type, @@ -2643,6 +2643,8 @@ static PyTypeObject* static_types[] = { &_PyUnion_Type, #ifdef _Py_TIER2 &_PyUOpExecutor_Type, +#else + NULL, #endif &_PyWeakref_CallableProxyType, &_PyWeakref_ProxyType, @@ -2667,7 +2669,7 @@ _PyTypes_InitTypes(PyInterpreterState *interp) // All other static types (unless initialized elsewhere) for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { PyTypeObject *type = static_types[i]; - if (_PyStaticType_InitBuiltin(interp, type) < 0) { + if (type && _PyStaticType_InitBuiltin(interp, type) < 0) { return _PyStatus_ERR("Can't initialize builtin type"); } if (type == &PyType_Type) { @@ -2707,7 +2709,9 @@ _PyTypes_FiniTypes(PyInterpreterState *interp) // their base classes. for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) { PyTypeObject *type = static_types[i]; - _PyStaticType_FiniBuiltin(interp, type); + if (type) { + _PyStaticType_FiniBuiltin(interp, type); + } } } From dfe13a274fda47ba4adaa8ff831db881f882cdf0 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 29 Apr 2026 10:34:43 +0200 Subject: [PATCH 2/4] Add comment --- Objects/object.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Objects/object.c b/Objects/object.c index d8ea2de75ae9b7..08f6b4cb762bc5 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2645,6 +2645,7 @@ static PyTypeObject* static_types[_Py_NUM_MANAGED_PREINITIALIZED_TYPES] = { #ifdef _Py_TIER2 &_PyUOpExecutor_Type, #else + // The array should have the same size on all builds; see gh-149139 NULL, #endif &_PyWeakref_CallableProxyType, From 8c7ef0fef2d1460d9eb2bb0833b39f6bee107d25 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Wed, 29 Apr 2026 13:20:07 +0200 Subject: [PATCH 3/4] if (type == NULL) continue; --- Objects/object.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Objects/object.c b/Objects/object.c index 08f6b4cb762bc5..e0e26bb50d3653 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2671,7 +2671,10 @@ _PyTypes_InitTypes(PyInterpreterState *interp) // All other static types (unless initialized elsewhere) for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { PyTypeObject *type = static_types[i]; - if (type && _PyStaticType_InitBuiltin(interp, type) < 0) { + if (type == NULL) { + continue; + } + if (_PyStaticType_InitBuiltin(interp, type) < 0) { return _PyStatus_ERR("Can't initialize builtin type"); } if (type == &PyType_Type) { @@ -2711,9 +2714,10 @@ _PyTypes_FiniTypes(PyInterpreterState *interp) // their base classes. for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) { PyTypeObject *type = static_types[i]; - if (type) { - _PyStaticType_FiniBuiltin(interp, type); + if (type == NULL) { + continue; } + _PyStaticType_FiniBuiltin(interp, type); } } From 1e90d8972ac554974029a5989f3ffe350eae1b11 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Thu, 30 Apr 2026 09:53:30 +0200 Subject: [PATCH 4/4] Adjust comment --- Include/internal/pycore_interp_structs.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h index e5c61eff4116a7..5e6b2d98b74761 100644 --- a/Include/internal/pycore_interp_structs.h +++ b/Include/internal/pycore_interp_structs.h @@ -530,7 +530,10 @@ struct _py_func_state { /****** type state *********/ /* For now we hard-code this to a value for which we are confident - all the static builtin types will fit (for all builds). */ + all the static builtin types will fit (for all builds). + If you add a new static type to the standard library, you may have to + update one of these numbers. + */ #define _Py_NUM_MANAGED_PREINITIALIZED_TYPES 120 #define _Py_MAX_MANAGED_STATIC_BUILTIN_TYPES \ (_Py_NUM_MANAGED_PREINITIALIZED_TYPES + 83)