Merge pull request #9374 from heitbaum/python

Python: update to 3.13.5
This commit is contained in:
Christian Hewitt 2025-06-20 15:58:58 +04:00 committed by GitHub
commit 2572200318
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 55 additions and 749 deletions

View File

@ -3,8 +3,8 @@
PKG_NAME="Python3"
# When changing PKG_VERSION remember to sync PKG_PYTHON_VERSION!
PKG_VERSION="3.12.11"
PKG_SHA256="c30bb24b7f1e9a19b11b55a546434f74e739bb4c271a3e3a80ff4380d49f7adb"
PKG_VERSION="3.13.5"
PKG_SHA256="93e583f243454e6e9e4588ca2c2662206ad961659863277afcdb96801647d640"
PKG_LICENSE="OSS"
PKG_SITE="https://www.python.org/"
PKG_URL="https://www.python.org/ftp/python/${PKG_VERSION}/${PKG_NAME::-1}-${PKG_VERSION}.tar.xz"
@ -14,7 +14,7 @@ PKG_LONGDESC="Python3 is an interpreted object-oriented programming language."
PKG_BUILD_FLAGS="-cfg-libs -cfg-libs:host"
PKG_TOOLCHAIN="autotools"
PKG_PYTHON_VERSION="python3.12"
PKG_PYTHON_VERSION="python3.13"
PKG_CONFIGURE_OPTS_HOST="ac_cv_prog_HAS_HG=/bin/false
ac_cv_prog_SVNVERSION=/bin/false
@ -39,7 +39,6 @@ PKG_CONFIGURE_OPTS_HOST="ac_cv_prog_HAS_HG=/bin/false
--disable-curses
--disable-pydoc
--disable-test-modules
--disable-lib2to3
--disable-idle3
--with-expat=builtin
--with-doc-strings
@ -78,7 +77,6 @@ PKG_CONFIGURE_OPTS_TARGET="ac_cv_prog_HAS_HG=/bin/false
--enable-curses
--disable-pydoc
--disable-test-modules
--disable-lib2to3
--disable-idle3
--with-expat=system
--with-doc-strings
@ -128,7 +126,7 @@ post_makeinstall_target() {
PKG_INSTALL_PATH_LIB=${INSTALL}/usr/lib/${PKG_PYTHON_VERSION}
for dir in config compiler sysconfigdata lib-dynload/sysconfigdata lib2to3/tests test; do
for dir in config compiler sysconfigdata lib-dynload/sysconfigdata test; do
rm -rf ${PKG_INSTALL_PATH_LIB}/${dir}
done

View File

@ -20,27 +20,28 @@ diff --git a/Makefile.pre.in b/Makefile.pre.in
index 4a957fb004..9c5f3c031a 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2329,6 +2329,7 @@ libinstall: all $(srcdir)/Modules/xxmodule.c
$(DESTDIR)$(LIBDEST); \
$(INSTALL_DATA) $(srcdir)/LICENSE $(DESTDIR)$(LIBDEST)/LICENSE.txt
@@ -2576,6 +2576,7 @@ libinstall: all $(srcdir)/Modules/xxmodule.c
patch --force --reject-file "$(abs_builddir)/app-store-compliance.rej" --strip 2 --directory "$(DESTDIR)$(LIBDEST)" --input "$(abs_srcdir)/$(APP_STORE_COMPLIANCE_PATCH)" || true ; \
fi
@ # Build PYC files for the 3 optimization levels (0, 1, 2)
+ifeq (@PYC_BUILD@,yes)
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
$(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
-o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST) -f \
@@ -2338,6 +2339,7 @@ libinstall: all $(srcdir)/Modules/xxmodule.c
@@ -2585,7 +2586,8 @@ libinstall: all $(srcdir)/Modules/xxmodule.c
$(PYTHON_FOR_BUILD) -Wi $(DESTDIR)$(LIBDEST)/compileall.py \
-o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
+endif
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
$(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/Grammar.txt
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
# bpo-21536: Misc/python-config.sh is generated in the build directory
# from $(srcdir)Misc/python-config.sh.in.
python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh
diff --git a/configure.ac b/configure.ac
index 8a32cb58f4..611c33949a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1479,6 +1479,12 @@ fi
@@ -1510,6 +1510,12 @@ fi
AC_MSG_CHECKING([LDLIBRARY])
@ -50,7 +51,7 @@ index 8a32cb58f4..611c33949a 100644
+ AS_HELP_STRING([--disable-pyc-build], [disable build of pyc files]),
+ [ PYC_BUILD="${enableval}" ], [ PYC_BUILD=yes ])
+
# MacOSX framework builds need more magic. LDLIBRARY is the dynamic
# Apple framework builds need more magic. LDLIBRARY is the dynamic
# library that we build, but we do not want to link against it (we
# will find it with a -framework option). For this reason there is an
--

View File

@ -23,25 +23,25 @@ diff --git a/Makefile.pre.in b/Makefile.pre.in
index 9c5f3c031a..2243a658a9 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2050,7 +2050,9 @@ bininstall: commoninstall altbininstall
@@ -2293,7 +2293,9 @@ bininstall: commoninstall altbininstall
-rm -f $(DESTDIR)$(BINDIR)/idle3
(cd $(DESTDIR)$(BINDIR); $(LN) -s idle$(VERSION) idle3)
-rm -f $(DESTDIR)$(BINDIR)/pydoc3
+ifeq (@PYDOC@,yes)
(cd $(DESTDIR)$(BINDIR); $(LN) -s pydoc$(VERSION) pydoc3)
+endif
-rm -f $(DESTDIR)$(BINDIR)/2to3
(cd $(DESTDIR)$(BINDIR); $(LN) -s 2to3-$(VERSION) 2to3)
if test "x$(LIPO_32BIT_FLAGS)" != "x" ; then \
@@ -2102,7 +2104,6 @@ LIBSUBDIRS= asyncio \
lib2to3 lib2to3/fixes lib2to3/pgen2 \
rm -f $(DESTDIR)$(BINDIR)/python3-32$(EXE); \
(cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-32$(EXE) python3-32$(EXE)) \
@@ -2343,7 +2345,6 @@ LIBSUBDIRS= asyncio \
logging \
multiprocessing multiprocessing/dummy \
pathlib \
- pydoc_data \
re \
site-packages \
sqlite3 \
@@ -2257,6 +2258,10 @@ TESTSUBDIRS= idlelib/idle_test \
@@ -2496,6 +2497,10 @@ TESTSUBDIRS= idlelib/idle_test \
COMPILEALL_OPTS=-j0
@ -52,9 +52,9 @@ index 9c5f3c031a..2243a658a9 100644
TEST_MODULES=@TEST_MODULES@
.PHONY: libinstall
@@ -2471,7 +2476,9 @@ libainstall: all scripts
@@ -2723,7 +2728,9 @@ libainstall: all scripts
$(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py
$(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(LDVERSION)-config
$(INSTALL_SCRIPT) $(SCRIPT_2TO3) $(DESTDIR)$(BINDIR)/2to3-$(VERSION)
$(INSTALL_SCRIPT) $(SCRIPT_IDLE) $(DESTDIR)$(BINDIR)/idle$(VERSION)
+ifeq (@PYDOC@,yes)
$(INSTALL_SCRIPT) $(SCRIPT_PYDOC) $(DESTDIR)$(BINDIR)/pydoc$(VERSION)
@ -66,7 +66,7 @@ diff --git a/configure.ac b/configure.ac
index 059ac2f883..1a2dd28d1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4511,6 +4511,12 @@ AS_VAR_IF([posix_threads], [stub], [
@@ -4636,6 +4636,12 @@ AS_VAR_IF([posix_threads], [stub], [
AC_DEFINE([HAVE_PTHREAD_STUBS], [1], [Define if platform requires stubbed pthreads support])
])

View File

@ -1,114 +0,0 @@
From 572f3164d1dce13db30e897ab0be7c706fa7b731 Mon Sep 17 00:00:00 2001
From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Date: Wed, 22 Feb 2017 17:15:31 -0800
Subject: [PATCH] Add an option to disable lib2to3
lib2to3 is a library to convert Python 2.x code to Python 3.x. As
such, it is probably not very useful on embedded system targets.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Signed-off-by: Samuel Martin <s.martin49@gmail.com>
[ Andrey Smirnov: ported to Python 3.6 ]
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
[ Adam Duskett: ported to Python 3.10.0 ]
Signed-off-by: Adam Duskett <aduskett@gmail.com>
[ Bernd Kuhls: ported to Python 3.11.4]
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
[ Adam Duskett: ported to Python 3.12.1 ]
Signed-off-by: Adam Duskett <adam.duskett@amarulasolutions.com>
---
Makefile.pre.in | 19 ++++++++++++++-----
configure.ac | 6 ++++++
2 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 2243a658a9..3f314d1354 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2054,7 +2054,9 @@ ifeq (@PYDOC@,yes)
(cd $(DESTDIR)$(BINDIR); $(LN) -s pydoc$(VERSION) pydoc3)
endif
-rm -f $(DESTDIR)$(BINDIR)/2to3
+ifeq (@LIB2TO3@,yes)
(cd $(DESTDIR)$(BINDIR); $(LN) -s 2to3-$(VERSION) 2to3)
+endif
if test "x$(LIPO_32BIT_FLAGS)" != "x" ; then \
rm -f $(DESTDIR)$(BINDIR)/python3-32$(EXE); \
(cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-32$(EXE) python3-32$(EXE)) \
@@ -2101,7 +2103,6 @@ LIBSUBDIRS= asyncio \
idlelib idlelib/Icons \
importlib importlib/resources importlib/metadata \
json \
- lib2to3 lib2to3/fixes lib2to3/pgen2 \
logging \
multiprocessing multiprocessing/dummy \
re \
@@ -2207,10 +2208,6 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_importlib/resources/zipdata02 \
test/test_importlib/source \
test/test_json \
- test/test_lib2to3 \
- test/test_lib2to3/data \
- test/test_lib2to3/data/fixers \
- test/test_lib2to3/data/fixers/myfixes \
test/test_module \
test/test_peg_generator \
test/test_pydoc \
@@ -2262,6 +2259,14 @@ ifeq (@PYDOC@,yes)
LIBSUBDIRS += pydoc_data
endif
+ifeq (@LIB2TO3@,yes)
+LIBSUBDIRS += lib2to3 lib2to3/fixes lib2to3/pgen2
+TESTSUBDIRS += test/test_lib2to3 \
+ test/test_lib2to3/data \
+ test/test_lib2to3/data/fixers \
+ test/test_lib2to3/data/fixers/myfixes
+endif
+
TEST_MODULES=@TEST_MODULES@
.PHONY: libinstall
@@ -2345,10 +2350,12 @@ ifeq (@PYC_BUILD@,yes)
-o 0 -o 1 -o 2 $(COMPILEALL_OPTS) -d $(LIBDEST)/site-packages -f \
-x badsyntax $(DESTDIR)$(LIBDEST)/site-packages
endif
+ifeq (@LIB2TO3@,yes)
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
$(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/Grammar.txt
-PYTHONPATH=$(DESTDIR)$(LIBDEST) $(RUNSHARED) \
$(PYTHON_FOR_BUILD) -m lib2to3.pgen2.driver $(DESTDIR)$(LIBDEST)/lib2to3/PatternGrammar.txt
+endif
# bpo-21536: Misc/python-config.sh is generated in the build directory
# from $(srcdir)Misc/python-config.sh.in.
@@ -2474,7 +2481,9 @@ libainstall: all scripts
$(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
$(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py
$(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(LDVERSION)-config
+ifeq (@LIB2TO3@,yes)
$(INSTALL_SCRIPT) $(SCRIPT_2TO3) $(DESTDIR)$(BINDIR)/2to3-$(VERSION)
+endif
$(INSTALL_SCRIPT) $(SCRIPT_IDLE) $(DESTDIR)$(BINDIR)/idle$(VERSION)
ifeq (@PYDOC@,yes)
$(INSTALL_SCRIPT) $(SCRIPT_PYDOC) $(DESTDIR)$(BINDIR)/pydoc$(VERSION)
diff --git a/configure.ac b/configure.ac
index 1a2dd28d1e..f0354c580d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7561,6 +7561,12 @@ PY_STDLIB_MOD([xxlimited_35], [test "$with_trace_refs" = "no"], [test "$ac_cv_fu
# substitute multiline block, must come after last PY_STDLIB_MOD()
AC_SUBST([MODULE_BLOCK])
+AC_SUBST(LIB2TO3)
+
+AC_ARG_ENABLE(lib2to3,
+ AS_HELP_STRING([--disable-lib2to3], [disable lib2to3]),
+ [ LIB2TO3="${enableval}" ], [ LIB2TO3=yes ])
+
# generate output files
AC_CONFIG_FILES(m4_normalize([
Makefile.pre
--
2.34.1

View File

@ -22,7 +22,7 @@ diff --git a/Makefile.pre.in b/Makefile.pre.in
index 3f314d1354..5fad7f82fb 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2048,7 +2048,9 @@ bininstall: commoninstall altbininstall
@@ -2291,7 +2291,9 @@ bininstall: commoninstall altbininstall
-rm -f $(DESTDIR)$(LIBPC)/python3-embed.pc
(cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION)-embed.pc python3-embed.pc)
-rm -f $(DESTDIR)$(BINDIR)/idle3
@ -32,7 +32,7 @@ index 3f314d1354..5fad7f82fb 100644
-rm -f $(DESTDIR)$(BINDIR)/pydoc3
ifeq (@PYDOC@,yes)
(cd $(DESTDIR)$(BINDIR); $(LN) -s pydoc$(VERSION) pydoc3)
@@ -2100,7 +2102,6 @@ LIBSUBDIRS= asyncio \
@@ -2339,7 +2341,6 @@ LIBSUBDIRS= asyncio \
ensurepip ensurepip/_bundled \
html \
http \
@ -40,8 +40,8 @@ index 3f314d1354..5fad7f82fb 100644
importlib importlib/resources importlib/metadata \
json \
logging \
@@ -2267,6 +2268,10 @@ TESTSUBDIRS += test/test_lib2to3 \
test/test_lib2to3/data/fixers/myfixes
@@ -2501,6 +2502,10 @@ TESTSUBDIRS += test/test_lib2to3 \
LIBSUBDIRS += pydoc_data
endif
+ifeq (@IDLE@,yes)
@ -51,10 +51,10 @@ index 3f314d1354..5fad7f82fb 100644
TEST_MODULES=@TEST_MODULES@
.PHONY: libinstall
@@ -2484,7 +2489,9 @@ libainstall: all scripts
ifeq (@LIB2TO3@,yes)
$(INSTALL_SCRIPT) $(SCRIPT_2TO3) $(DESTDIR)$(BINDIR)/2to3-$(VERSION)
endif
@@ -2727,7 +2732,9 @@ libainstall: all scripts
$(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh
$(INSTALL_SCRIPT) python-config.py $(DESTDIR)$(LIBPL)/python-config.py
$(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(LDVERSION)-config
+ifeq (@IDLE@,yes)
$(INSTALL_SCRIPT) $(SCRIPT_IDLE) $(DESTDIR)$(BINDIR)/idle$(VERSION)
+endif
@ -65,9 +65,9 @@ diff --git a/configure.ac b/configure.ac
index f0354c580d..43086962e9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7567,6 +7567,12 @@ AC_ARG_ENABLE(lib2to3,
AS_HELP_STRING([--disable-lib2to3], [disable lib2to3]),
[ LIB2TO3="${enableval}" ], [ LIB2TO3=yes ])
@@ -7788,6 +7788,12 @@ AC_ARG_ENABLE(lib2to3,
# substitute multiline block, must come after last PY_STDLIB_MOD()
AC_SUBST([MODULE_BLOCK])
+AC_SUBST(IDLE)
+

View File

@ -15,10 +15,11 @@ diff --git a/configure.ac b/configure.ac
index 43086962e9..561e33f550 100644
--- a/configure.ac
+++ b/configure.ac
@@ -95,6 +95,11 @@ AC_DEFUN([PY_CHECK_EMSCRIPTEN_PORT], [
@@ -95,6 +95,12 @@ AC_DEFUN([PY_CHECK_EMSCRIPTEN_PORT], [
AS_VAR_POPDEF([py_libs])
])
+# stdlib
+AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
+ m4_foreach([mod], [$@], [
+ AS_VAR_SET([py_cv_module_]mod, [n/a])])
@ -27,10 +28,11 @@ index 43086962e9..561e33f550 100644
AC_SUBST([BASECPPFLAGS])
if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then
# If we're building out-of-tree, we need to make sure the following
@@ -7258,11 +7263,6 @@ AC_ARG_ENABLE([test-modules],
AC_MSG_RESULT([$TEST_MODULES])
AC_SUBST([TEST_MODULES])
@@ -7457,12 +7463,6 @@ AC_ARG_ENABLE([test-modules],
_RESTORE_VAR([CPPFLAGS])
-# stdlib
-AC_DEFUN([PY_STDLIB_MOD_SET_NA], [
- m4_foreach([mod], [$@], [
- AS_VAR_SET([py_cv_module_]mod, [n/a])])
@ -38,7 +40,7 @@ index 43086962e9..561e33f550 100644
-
# stdlib not available
dnl Modules that are not available on some platforms
dnl AIX has shadow passwords, but access is not via getspent()
AS_CASE([$ac_sys_system],
--
2.34.1

View File

@ -19,15 +19,15 @@ diff --git a/Makefile.pre.in b/Makefile.pre.in
index 5fad7f82fb..7b6c9811a6 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2108,7 +2108,6 @@ LIBSUBDIRS= asyncio \
multiprocessing multiprocessing/dummy \
@@ -2348,7 +2348,6 @@ LIBSUBDIRS= asyncio \
pathlib \
re \
site-packages \
- sqlite3 \
sysconfig \
tkinter \
tomllib \
turtledemo \
@@ -2272,6 +2271,10 @@ ifeq (@IDLE@,yes)
@@ -2506,6 +2505,10 @@ ifeq (@IDLE@,yes)
LIBSUBDIRS += idlelib idlelib/Icons
endif
@ -42,7 +42,7 @@ diff --git a/configure.ac b/configure.ac
index 561e33f550..d1c54bd67c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4516,6 +4516,13 @@ AS_VAR_IF([posix_threads], [stub], [
@@ -4642,6 +4642,13 @@ AS_VAR_IF([posix_threads], [stub], [
AC_DEFINE([HAVE_PTHREAD_STUBS], [1], [Define if platform requires stubbed pthreads support])
])

View File

@ -22,23 +22,23 @@ diff --git a/Makefile.pre.in b/Makefile.pre.in
index 7b6c9811a6..6d9527ddd0 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -2108,7 +2108,6 @@ LIBSUBDIRS= asyncio \
multiprocessing multiprocessing/dummy \
@@ -2349,7 +2349,6 @@ LIBSUBDIRS= asyncio \
re \
site-packages \
sysconfig \
- tkinter \
tomllib \
turtledemo \
unittest \
@@ -2212,7 +2211,6 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_peg_generator \
@@ -2457,7 +2456,6 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_pydoc \
test/test_pyrepl \
test/test_sqlite3 \
- test/test_tkinter \
test/test_tomllib \
test/test_tomllib/data \
test/test_tomllib/data/invalid \
@@ -2232,7 +2230,6 @@ TESTSUBDIRS= idlelib/idle_test \
@@ -2478,7 +2476,6 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_tools \
test/test_tools/i18n_data \
test/test_tools/msgfmt_data \
@ -46,9 +46,9 @@ index 7b6c9811a6..6d9527ddd0 100644
test/test_unittest \
test/test_unittest/testmock \
test/test_warnings \
@@ -2253,6 +2250,11 @@ TESTSUBDIRS= idlelib/idle_test \
test/test_multiprocessing_forkserver \
test/test_multiprocessing_spawn
@@ -2500,6 +2497,11 @@ TESTSUBDIRS= idlelib/idle_test \
test/xmltestdata/c14n-20 \
test/zipimport_data
+ifeq (@TK@,yes)
+LIBSUBDIRS += tkinter
@ -62,7 +62,7 @@ diff --git a/configure.ac b/configure.ac
index d1c54bd67c..4c5cbe4153 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4529,6 +4529,13 @@ AC_ARG_ENABLE(pydoc,
@@ -4658,6 +4658,13 @@ AC_ARG_ENABLE(pydoc,
AS_HELP_STRING([--disable-pydoc], [disable pydoc]),
[ PYDOC="${enableval}" ], [ PYDOC=yes ])

View File

@ -1,140 +0,0 @@
From e7fa6023be567251b409527bd005b93335914501 Mon Sep 17 00:00:00 2001
From: Vincent Fazio <5265893+vfazio@users.noreply.github.com>
Date: Wed, 28 Feb 2024 13:55:04 -0600
Subject: [PATCH] gh-115382: Fix cross compiles when host and target use same
SOABI
Previously, when a build was configured to use a host interpreter via
--with-build-python, the PYTHON_FOR_BUILD config value included a path
in PYTHONPATH that pointed to the target's built external modules.
For "normal" foreign architecture cross compiles, when loading compiled
external libraries, the target libraries were processed first due to
their precedence in sys.path. These libraries were then ruled out due to
a mismatch in the SOABI so the import mechanism continued searching
until it found the host's native modules.
However, if the host interpreter and the target python were on the same
version + SOABI combination, the host interpreter would attempt to load
the target's external modules due to their precedence in sys.path.
Despite the "match", the target build may have been linked against a
different libc or may include unsupported instructions so loading or
executing the target's external modules can lead to crashes.
Now, the path to the target's external modules is no longer defined in
PYTHONPATH to prevent accidentally loading these foreign modules.
One caveat is that during certain build stages, the target's sysconfig
module requires higher precedence than the host's version in order to
accurately query the target build's configuration.
This worked previously due to the target's sysconfig data module having
precedence over the host's (see above). In order to keep this desired
behavior, a new environment variable, _PYTHON_SYSCONFIGDATA_PATH, has
been defined so sysconfig can search this directory for the target's
sysconfig data.
Signed-off-by: Vincent Fazio <vfazio@gmail.com>
Upstream-issue: https://github.com/python/cpython/issues/115382
Upstream: https://github.com/python/cpython/pull/116294
---
Lib/sysconfig.py | 15 ++++++++++++++-
Lib/test/libregrtest/main.py | 1 +
Lib/test/pythoninfo.py | 1 +
Tools/scripts/run_tests.py | 1 +
configure | 2 +-
configure.ac | 2 +-
6 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py
index 122d441bd1..260aec3127 100644
--- a/Lib/sysconfig.py
+++ b/Lib/sysconfig.py
@@ -533,7 +533,20 @@ def _init_posix(vars):
"""Initialize the module as appropriate for POSIX systems."""
# _sysconfigdata is generated at build time, see _generate_posix_vars()
name = _get_sysconfigdata_name()
- _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
+
+ # For cross builds, the path to the target's sysconfigdata must be specified
+ # so it can be imported. It cannot be in PYTHONPATH, as foreign modules in
+ # sys.path can cause crashes when loaded by the host interpreter.
+ # Rely on truthiness as a valueless env variable is still an empty string.
+ # See OS X note in _generate_posix_vars re _sysconfigdata.
+ if (path := os.environ.get('_PYTHON_SYSCONFIGDATA_PATH')):
+ from importlib.machinery import FileFinder, SourceFileLoader, SOURCE_SUFFIXES
+ from importlib.util import module_from_spec
+ spec = FileFinder(path, (SourceFileLoader, SOURCE_SUFFIXES)).find_spec(name)
+ _temp = module_from_spec(spec)
+ spec.loader.exec_module(_temp)
+ else:
+ _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
build_time_vars = _temp.build_time_vars
vars.update(build_time_vars)
diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py
index e41646d2d1..f54e570728 100644
--- a/Lib/test/libregrtest/main.py
+++ b/Lib/test/libregrtest/main.py
@@ -576,6 +576,7 @@ def _add_cross_compile_opts(self, regrtest_opts):
'_PYTHON_PROJECT_BASE',
'_PYTHON_HOST_PLATFORM',
'_PYTHON_SYSCONFIGDATA_NAME',
+ "_PYTHON_SYSCONFIGDATA_PATH",
'PYTHONPATH'
}
old_environ = os.environ
diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py
index 6efeaad812..d43e52c9e4 100644
--- a/Lib/test/pythoninfo.py
+++ b/Lib/test/pythoninfo.py
@@ -326,6 +326,7 @@ def format_groups(groups):
"_PYTHON_HOST_PLATFORM",
"_PYTHON_PROJECT_BASE",
"_PYTHON_SYSCONFIGDATA_NAME",
+ "_PYTHON_SYSCONFIGDATA_PATH",
"__PYVENV_LAUNCHER__",
# Sanitizer options
diff --git a/Tools/scripts/run_tests.py b/Tools/scripts/run_tests.py
index 445a34ae3e..4077a83424 100644
--- a/Tools/scripts/run_tests.py
+++ b/Tools/scripts/run_tests.py
@@ -42,6 +42,7 @@ def main(regrtest_args):
'_PYTHON_PROJECT_BASE',
'_PYTHON_HOST_PLATFORM',
'_PYTHON_SYSCONFIGDATA_NAME',
+ "_PYTHON_SYSCONFIGDATA_PATH",
'PYTHONPATH'
}
environ = {
diff --git a/configure b/configure
index 6dc8a66e48..a69346db8c 100755
--- a/configure
+++ b/configure
@@ -3689,7 +3689,7 @@ fi
fi
ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python
PYTHON_FOR_FREEZE="$with_build_python"
- PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python
+ PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_build_python" >&5
printf "%s\n" "$with_build_python" >&6; }
diff --git a/configure.ac b/configure.ac
index 1cb95f41fd..de420dde2c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -169,7 +169,7 @@ AC_ARG_WITH([build-python],
dnl Build Python interpreter is used for regeneration and freezing.
ac_cv_prog_PYTHON_FOR_REGEN=$with_build_python
PYTHON_FOR_FREEZE="$with_build_python"
- PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`:)$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) '$with_build_python
+ PYTHON_FOR_BUILD='_PYTHON_PROJECT_BASE=$(abs_builddir) _PYTHON_HOST_PLATFORM=$(_PYTHON_HOST_PLATFORM) PYTHONPATH=$(srcdir)/Lib _PYTHON_SYSCONFIGDATA_NAME=_sysconfigdata_$(ABIFLAGS)_$(MACHDEP)_$(MULTIARCH) _PYTHON_SYSCONFIGDATA_PATH=$(shell test -f pybuilddir.txt && echo $(abs_builddir)/`cat pybuilddir.txt`) '$with_build_python
AC_MSG_RESULT([$with_build_python])
], [
AS_VAR_IF([cross_compiling], [yes],
--
2.34.1

View File

@ -1,370 +0,0 @@
From 21f8fbaa7c01a8ec2fa2420f44f5cb05a54f55b6 Mon Sep 17 00:00:00 2001
From: Neil Schemenauer <nas@arctrix.com>
Date: Wed, 27 Mar 2024 09:54:02 -0700
Subject: [PATCH] Use pointer for interp->obmalloc state.
For interpreters that share state with the main interpreter, this points
to the same static memory structure. For interpreters with their own
obmalloc state, it is heap allocated. Add free_obmalloc_arenas() which
will free the obmalloc arenas and radix tree structures for interpreters
with their own obmalloc state.
---
Include/internal/pycore_interp.h | 12 +-
Include/internal/pycore_obmalloc.h | 2 +
Include/internal/pycore_obmalloc_init.h | 7 -
Include/internal/pycore_runtime_init.h | 1 -
...-12-22-13-21-39.gh-issue-113055.47xBMF.rst | 5 +
Objects/obmalloc.c | 121 +++++++++++++++++-
Python/pylifecycle.c | 16 +++
Python/pystate.c | 13 +-
Tools/c-analyzer/cpython/ignored.tsv | 3 +-
9 files changed, 157 insertions(+), 23 deletions(-)
create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-12-22-13-21-39.gh-issue-113055.47xBMF.rst
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 37cc88ed081b72..a0ef5990259e29 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -178,7 +178,17 @@ struct _is {
struct _warnings_runtime_state warnings;
struct atexit_state atexit;
- struct _obmalloc_state obmalloc;
+ // Per-interpreter state for the obmalloc allocator. For the main
+ // interpreter and for all interpreters that don't have their
+ // own obmalloc state, this points to the static structure in
+ // obmalloc.c obmalloc_state_main. For other interpreters, it is
+ // heap allocated by _PyMem_init_obmalloc() and freed when the
+ // interpreter structure is freed. In the case of a heap allocated
+ // obmalloc state, it is not safe to hold on to or use memory after
+ // the interpreter is freed. The obmalloc state corresponding to
+ // that allocated memory is gone. See free_obmalloc_arenas() for
+ // more comments.
+ struct _obmalloc_state *obmalloc;
PyObject *audit_hooks;
PyType_WatchCallback type_watchers[TYPE_MAX_WATCHERS];
diff --git a/Include/internal/pycore_obmalloc.h b/Include/internal/pycore_obmalloc.h
index b1c00654ac1c5d..38427e194956ac 100644
--- a/Include/internal/pycore_obmalloc.h
+++ b/Include/internal/pycore_obmalloc.h
@@ -686,6 +686,8 @@ extern Py_ssize_t _Py_GetGlobalAllocatedBlocks(void);
_Py_GetGlobalAllocatedBlocks()
extern Py_ssize_t _PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *);
extern void _PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *);
+extern int _PyMem_init_obmalloc(PyInterpreterState *interp);
+extern bool _PyMem_obmalloc_state_on_heap(PyInterpreterState *interp);
#ifdef WITH_PYMALLOC
diff --git a/Include/internal/pycore_obmalloc_init.h b/Include/internal/pycore_obmalloc_init.h
index 8ee72ff2d4126f..e6811b7aeca73c 100644
--- a/Include/internal/pycore_obmalloc_init.h
+++ b/Include/internal/pycore_obmalloc_init.h
@@ -59,13 +59,6 @@ extern "C" {
.dump_debug_stats = -1, \
}
-#define _obmalloc_state_INIT(obmalloc) \
- { \
- .pools = { \
- .used = _obmalloc_pools_INIT(obmalloc.pools), \
- }, \
- }
-
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index e5f9e17efff24b..d3a64b3d4a7895 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -88,7 +88,6 @@ extern PyTypeObject _PyExc_MemoryError;
{ \
.id_refcount = -1, \
.imports = IMPORTS_INIT, \
- .obmalloc = _obmalloc_state_INIT(INTERP.obmalloc), \
.ceval = { \
.recursion_limit = Py_DEFAULT_RECURSION_LIMIT, \
}, \
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-22-13-21-39.gh-issue-113055.47xBMF.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-22-13-21-39.gh-issue-113055.47xBMF.rst
new file mode 100644
index 00000000000000..90f49272218c96
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-22-13-21-39.gh-issue-113055.47xBMF.rst
@@ -0,0 +1,5 @@
+Make interp->obmalloc a pointer. For interpreters that share state with the
+main interpreter, this points to the same static memory structure. For
+interpreters with their own obmalloc state, it is heap allocated. Add
+free_obmalloc_arenas() which will free the obmalloc arenas and radix tree
+structures for interpreters with their own obmalloc state.
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 9620a8fbb44cac..acbefef614195c 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -3,6 +3,7 @@
#include "Python.h"
#include "pycore_code.h" // stats
#include "pycore_pystate.h" // _PyInterpreterState_GET
+#include "pycore_obmalloc_init.h"
#include "pycore_obmalloc.h"
#include "pycore_pymem.h"
@@ -852,6 +853,13 @@ static int running_on_valgrind = -1;
typedef struct _obmalloc_state OMState;
+/* obmalloc state for main interpreter and shared by all interpreters without
+ * their own obmalloc state. By not explicitly initalizing this structure, it
+ * will be allocated in the BSS which is a small performance win. The radix
+ * tree arrays are fairly large but are sparsely used. */
+static struct _obmalloc_state obmalloc_state_main;
+static bool obmalloc_state_initialized;
+
static inline int
has_own_state(PyInterpreterState *interp)
{
@@ -864,10 +872,8 @@ static inline OMState *
get_state(void)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
- if (!has_own_state(interp)) {
- interp = _PyInterpreterState_Main();
- }
- return &interp->obmalloc;
+ assert(interp->obmalloc != NULL); // otherwise not initialized or freed
+ return interp->obmalloc;
}
// These macros all rely on a local "state" variable.
@@ -893,7 +899,11 @@ _PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *interp)
"the interpreter doesn't have its own allocator");
}
#endif
- OMState *state = &interp->obmalloc;
+ OMState *state = interp->obmalloc;
+
+ if (state == NULL) {
+ return 0;
+ }
Py_ssize_t n = raw_allocated_blocks;
/* add up allocated blocks for used pools */
@@ -915,13 +925,25 @@ _PyInterpreterState_GetAllocatedBlocks(PyInterpreterState *interp)
return n;
}
+static void free_obmalloc_arenas(PyInterpreterState *interp);
+
void
_PyInterpreterState_FinalizeAllocatedBlocks(PyInterpreterState *interp)
{
- if (has_own_state(interp)) {
+ if (has_own_state(interp) && interp->obmalloc != NULL) {
Py_ssize_t leaked = _PyInterpreterState_GetAllocatedBlocks(interp);
assert(has_own_state(interp) || leaked == 0);
interp->runtime->obmalloc.interpreter_leaks += leaked;
+ if (_PyMem_obmalloc_state_on_heap(interp) && leaked == 0) {
+ // free the obmalloc arenas and radix tree nodes. If leaked > 0
+ // then some of the memory allocated by obmalloc has not been
+ // freed. It might be safe to free the arenas in that case but
+ // it's possible that extension modules are still using that
+ // memory. So, it is safer to not free and to leak. Perhaps there
+ // should be warning when this happens. It should be possible to
+ // use a tool like "-fsanitize=address" to track down these leaks.
+ free_obmalloc_arenas(interp);
+ }
}
}
@@ -2511,9 +2533,96 @@ _PyDebugAllocatorStats(FILE *out,
(void)printone(out, buf2, num_blocks * sizeof_block);
}
+// Return true if the obmalloc state structure is heap allocated,
+// by PyMem_RawCalloc(). For the main interpreter, this structure
+// allocated in the BSS. Allocating that way gives some memory savings
+// and a small performance win (at least on a demand paged OS). On
+// 64-bit platforms, the obmalloc structure is 256 kB. Most of that
+// memory is for the arena_map_top array. Since normally only one entry
+// of that array is used, only one page of resident memory is actually
+// used, rather than the full 256 kB.
+bool _PyMem_obmalloc_state_on_heap(PyInterpreterState *interp)
+{
+#if WITH_PYMALLOC
+ return interp->obmalloc && interp->obmalloc != &obmalloc_state_main;
+#else
+ return false;
+#endif
+}
+
+#ifdef WITH_PYMALLOC
+static void
+init_obmalloc_pools(PyInterpreterState *interp)
+{
+ // initialize the obmalloc->pools structure. This must be done
+ // before the obmalloc alloc/free functions can be called.
+ poolp temp[OBMALLOC_USED_POOLS_SIZE] =
+ _obmalloc_pools_INIT(interp->obmalloc->pools);
+ memcpy(&interp->obmalloc->pools.used, temp, sizeof(temp));
+}
+#endif /* WITH_PYMALLOC */
+
+int _PyMem_init_obmalloc(PyInterpreterState *interp)
+{
+#ifdef WITH_PYMALLOC
+ /* Initialize obmalloc, but only for subinterpreters,
+ since the main interpreter is initialized statically. */
+ if (_Py_IsMainInterpreter(interp)
+ || _PyInterpreterState_HasFeature(interp,
+ Py_RTFLAGS_USE_MAIN_OBMALLOC)) {
+ interp->obmalloc = &obmalloc_state_main;
+ if (!obmalloc_state_initialized) {
+ init_obmalloc_pools(interp);
+ obmalloc_state_initialized = true;
+ }
+ } else {
+ interp->obmalloc = PyMem_RawCalloc(1, sizeof(struct _obmalloc_state));
+ if (interp->obmalloc == NULL) {
+ return -1;
+ }
+ init_obmalloc_pools(interp);
+ }
+#endif /* WITH_PYMALLOC */
+ return 0; // success
+}
+
#ifdef WITH_PYMALLOC
+static void
+free_obmalloc_arenas(PyInterpreterState *interp)
+{
+ OMState *state = interp->obmalloc;
+ for (uint i = 0; i < maxarenas; ++i) {
+ // free each obmalloc memory arena
+ struct arena_object *ao = &allarenas[i];
+ _PyObject_Arena.free(_PyObject_Arena.ctx,
+ (void *)ao->address, ARENA_SIZE);
+ }
+ // free the array containing pointers to all arenas
+ PyMem_RawFree(allarenas);
+#if WITH_PYMALLOC_RADIX_TREE
+#ifdef USE_INTERIOR_NODES
+ // Free the middle and bottom nodes of the radix tree. These are allocated
+ // by arena_map_mark_used() but not freed when arenas are freed.
+ for (int i1 = 0; i1 < MAP_TOP_LENGTH; i1++) {
+ arena_map_mid_t *mid = arena_map_root.ptrs[i1];
+ if (mid == NULL) {
+ continue;
+ }
+ for (int i2 = 0; i2 < MAP_MID_LENGTH; i2++) {
+ arena_map_bot_t *bot = arena_map_root.ptrs[i1]->ptrs[i2];
+ if (bot == NULL) {
+ continue;
+ }
+ PyMem_RawFree(bot);
+ }
+ PyMem_RawFree(mid);
+ }
+#endif
+#endif
+}
+
#ifdef Py_DEBUG
/* Is target in the list? The list is traversed via the nextpool pointers.
* The list may be NULL-terminated, or circular. Return 1 if target is in
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index a0130fde15d574..fb833ba61cbd9b 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -28,6 +28,7 @@
#include "pycore_typeobject.h" // _PyTypes_InitTypes()
#include "pycore_typevarobject.h" // _Py_clear_generic_types()
#include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
+#include "pycore_obmalloc.h" // _PyMem_init_obmalloc()
#include "opcode.h"
#include <locale.h> // setlocale()
@@ -636,6 +637,13 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
return status;
}
+ // initialize the interp->obmalloc state. This must be done after
+ // the settings are loaded (so that feature_flags are set) but before
+ // any calls are made to obmalloc functions.
+ if (_PyMem_init_obmalloc(interp) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+
/* Auto-thread-state API */
status = _PyGILState_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
@@ -2051,6 +2059,14 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
return _PyStatus_OK();
}
+ // initialize the interp->obmalloc state. This must be done after
+ // the settings are loaded (so that feature_flags are set) but before
+ // any calls are made to obmalloc functions.
+ if (_PyMem_init_obmalloc(interp) < 0) {
+ status = _PyStatus_NO_MEMORY();
+ goto error;
+ }
+
PyThreadState *tstate = _PyThreadState_New(interp);
if (tstate == NULL) {
PyInterpreterState_Delete(interp);
diff --git a/Python/pystate.c b/Python/pystate.c
index 1337516aa59cbc..a25c3dcf9d09ea 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -14,6 +14,7 @@
#include "pycore_pystate.h"
#include "pycore_runtime_init.h" // _PyRuntimeState_INIT
#include "pycore_sysmodule.h"
+#include "pycore_obmalloc.h" // _PyMem_obmalloc_state_on_heap()
/* --------------------------------------------------------------------------
CAUTION
@@ -636,6 +637,11 @@ free_interpreter(PyInterpreterState *interp)
// The main interpreter is statically allocated so
// should not be freed.
if (interp != &_PyRuntime._main_interpreter) {
+ if (_PyMem_obmalloc_state_on_heap(interp)) {
+ // interpreter has its own obmalloc state, free it
+ PyMem_RawFree(interp->obmalloc);
+ interp->obmalloc = NULL;
+ }
PyMem_RawFree(interp);
}
}
@@ -679,14 +685,6 @@ init_interpreter(PyInterpreterState *interp,
assert(next != NULL || (interp == runtime->interpreters.main));
interp->next = next;
- /* Initialize obmalloc, but only for subinterpreters,
- since the main interpreter is initialized statically. */
- if (interp != &runtime->_main_interpreter) {
- poolp temp[OBMALLOC_USED_POOLS_SIZE] = \
- _obmalloc_pools_INIT(interp->obmalloc.pools);
- memcpy(&interp->obmalloc.pools.used, temp, sizeof(temp));
- }
-
// We would call _PyObject_InitState() at this point
// if interp->feature_flags were alredy set.
diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv
index 9f36c47ca7ea03..7bcca27ecc32f6 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -318,7 +318,8 @@ Objects/obmalloc.c - _PyMem_Debug -
Objects/obmalloc.c - _PyMem_Raw -
Objects/obmalloc.c - _PyObject -
Objects/obmalloc.c - last_final_leaks -
-Objects/obmalloc.c - usedpools -
+Objects/obmalloc.c - obmalloc_state_main -
+Objects/obmalloc.c - obmalloc_state_initialized -
Objects/typeobject.c - name_op -
Objects/typeobject.c - slotdefs -
Objects/unicodeobject.c - stripfuncnames -

View File

@ -1,71 +0,0 @@
From a867732a619e1cc02369cf0185b53a484d049369 Mon Sep 17 00:00:00 2001
From: Neil Schemenauer <nas@arctrix.com>
Date: Mon, 6 May 2024 10:02:17 -0700
Subject: [PATCH] Fix merge, move _PyMem_init_obmalloc() calls.
---
Python/pylifecycle.c | 30 +++++++++++++++---------------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index fb833ba61cbd9b..31a24d4a65aebf 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -637,13 +637,6 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
return status;
}
- // initialize the interp->obmalloc state. This must be done after
- // the settings are loaded (so that feature_flags are set) but before
- // any calls are made to obmalloc functions.
- if (_PyMem_init_obmalloc(interp) < 0) {
- return _PyStatus_NO_MEMORY();
- }
-
/* Auto-thread-state API */
status = _PyGILState_Init(interp);
if (_PyStatus_EXCEPTION(status)) {
@@ -662,6 +655,13 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
// didn't depend on interp->feature_flags being set already.
_PyObject_InitState(interp);
+ // initialize the interp->obmalloc state. This must be done after
+ // the settings are loaded (so that feature_flags are set) but before
+ // any calls are made to obmalloc functions.
+ if (_PyMem_init_obmalloc(interp) < 0) {
+ return _PyStatus_NO_MEMORY();
+ }
+
PyThreadState *tstate = _PyThreadState_New(interp);
if (tstate == NULL) {
return _PyStatus_ERR("can't make first thread");
@@ -2072,14 +2072,6 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
return _PyStatus_OK();
}
- // initialize the interp->obmalloc state. This must be done after
- // the settings are loaded (so that feature_flags are set) but before
- // any calls are made to obmalloc functions.
- if (_PyMem_init_obmalloc(interp) < 0) {
- status = _PyStatus_NO_MEMORY();
- goto error;
- }
-
PyThreadState *tstate = _PyThreadState_New(interp);
if (tstate == NULL) {
PyInterpreterState_Delete(interp);
@@ -2110,6 +2102,14 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
goto error;
}
+ // initialize the interp->obmalloc state. This must be done after
+ // the settings are loaded (so that feature_flags are set) but before
+ // any calls are made to obmalloc functions.
+ if (_PyMem_init_obmalloc(interp) < 0) {
+ status = _PyStatus_NO_MEMORY();
+ goto error;
+ }
+
status = init_interp_create_gil(tstate, config->gil);
if (_PyStatus_EXCEPTION(status)) {
goto error;