diff --git a/recipes/cpython/all/conandata.yml b/recipes/cpython/all/conandata.yml
index 3959aff0dc825..0cacdfda89c31 100644
--- a/recipes/cpython/all/conandata.yml
+++ b/recipes/cpython/all/conandata.yml
@@ -1,4 +1,7 @@
sources:
+ "3.13.0":
+ url: "https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tgz"
+ sha256: "12445c7b3db3126c41190bfdc1c8239c39c719404e844babbd015a1bc3fafcd4"
"3.12.7":
url: "https://www.python.org/ftp/python/3.12.7/Python-3.12.7.tgz"
sha256: "73ac8fe780227bf371add8373c3079f42a0dc62deff8d612cd15a618082ab623"
@@ -18,6 +21,16 @@ sources:
url: "https://www.python.org/ftp/python/3.8.19/Python-3.8.19.tgz"
sha256: "c7fa55a36e5c7a19ec37d8f90f60a2197548908c9ac8b31e7c0dbffdd470eeac"
patches:
+ "3.13.0":
+ - patch_file: "patches/3.13/3.13.0-0001-_ctypes-ffi.patch"
+ patch_description: "Support shared libffi"
+ patch_type: "portability"
+ - patch_file: "patches/3.13/3.13.0-0002-remove-module-deps.patch"
+ patch_description: "Remove section of solution file forcing projects to be built that might not be used for this recipe"
+ patch_type: "conan"
+ - patch_file: "patches/3.13/3.13.0-0003-relocatable-python-config.patch"
+ patch_description: "Allow package to be relocatable"
+ patch_type: "conan"
"3.12.7":
- patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch"
patch_description: "Fix ARM/ARM64 mismatch in project file"
diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py
index c98c3381c1c65..0008a2254f8ca 100644
--- a/recipes/cpython/all/conanfile.py
+++ b/recipes/cpython/all/conanfile.py
@@ -120,12 +120,14 @@ def requirements(self):
if self.settings.os != "Windows":
if not is_apple_os(self):
self.requires("util-linux-libuuid/2.39.2")
- # In <3.9 and lower patch versions of 3.9/10/11, crypt.h was exposed in Python.h
- # This was removed in 3.11 and backported: https://github.com/python/cpython/issues/88914
- # For the sake of this recipe, we only have later patch versions, so this version check
- # may be slightly inaccurate if a lower patch version is desired.
- transitive_crypt = Version(self.version) < "3.9"
- self.requires("libxcrypt/4.4.36", transitive_headers=transitive_crypt, transitive_libs=transitive_crypt)
+ if Version(self.version) < "3.13":
+ # In <3.9 and lower patch versions of 3.9/10/11, crypt.h was exposed in Python.h
+ # This was removed in 3.11 and backported: https://github.com/python/cpython/issues/88914
+ # For the sake of this recipe, we only have later patch versions, so this version check
+ # may be slightly inaccurate if a lower patch version is desired.
+ # This dependency is removed entirely in 3.13.
+ transitive_crypt = Version(self.version) < "3.9"
+ self.requires("libxcrypt/4.4.36", transitive_headers=transitive_crypt, transitive_libs=transitive_crypt)
if self.options.get_safe("with_bz2"):
self.requires("bzip2/1.0.8")
if self.options.get_safe("with_gdbm", False):
@@ -315,13 +317,21 @@ def _patch_msvc_projects(self):
replace_in_file(self, self._msvc_project_path("_ssl"), '', "")
# For mpdecimal, we need to remove all headers and all c files *except* the main module file, _decimal.c
- self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\.*\.h.*', "")
- self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\libmpdec\\.*\.c.*', "")
+ if Version(self.version) < "3.13":
+ self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\.*\.h.*', "")
+ self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\libmpdec\\.*\.c.*', "")
+ # Remove extra include directory
+ replace_in_file(self, self._msvc_project_path("_decimal"), r"..\Modules\_decimal\libmpdec;", "")
+ else:
+ # https://github.com/python/cpython/commit/849e0716d378d6f9f724d1b3c386f6613d52a49d
+ # changed _decimal.vcxproj enough that we need different patching code.
+ self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\windows\\.*\.h.*', "")
+ self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\$\(mpdecimalDir\)\\libmpdec\\.*\.h.*', "")
+ self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\$\(mpdecimalDir\)\\libmpdec\\.*\.c.*', "")
+ replace_in_file(self, self._msvc_project_path("_decimal"), r"..\Modules\_decimal\windows;$(mpdecimalDir)\libmpdec;", "")
# There is also an assembly file with a complicated build step as part of the mpdecimal build
replace_in_file(self, self._msvc_project_path("_decimal"), "", "-->")
- # Remove extra include directory
- replace_in_file(self, self._msvc_project_path("_decimal"), r"..\Modules\_decimal\libmpdec;", "")
# Don't include vendored sqlite3
replace_in_file(self, self._msvc_project_path("_sqlite3"),
@@ -826,7 +836,7 @@ def package_info(self):
["pathcch", "shlwapi", "version", "ws2_32"]
)
self.cpp_info.components["python"].requires = ["zlib::zlib"]
- if self.settings.os != "Windows":
+ if self.settings.os != "Windows" and Version(self.version) < "3.13":
self.cpp_info.components["python"].requires.append("libxcrypt::libxcrypt")
self.cpp_info.components["python"].set_property(
"pkg_config_name", f"python-{py_version.major}.{py_version.minor}"
@@ -867,7 +877,8 @@ def package_info(self):
if self.settings.os != "Windows":
if not is_apple_os(self):
self.cpp_info.components["_hidden"].requires.append("util-linux-libuuid::util-linux-libuuid")
- self.cpp_info.components["_hidden"].requires.append("libxcrypt::libxcrypt")
+ if Version(self.version) < "3.13":
+ self.cpp_info.components["_hidden"].requires.append("libxcrypt::libxcrypt")
if self.options.with_bz2:
self.cpp_info.components["_hidden"].requires.append("bzip2::bzip2")
if self.options.get_safe("with_gdbm", False):
diff --git a/recipes/cpython/all/patches/3.13/3.13.0-0001-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.13/3.13.0-0001-_ctypes-ffi.patch
new file mode 100644
index 0000000000000..784733c023219
--- /dev/null
+++ b/recipes/cpython/all/patches/3.13/3.13.0-0001-_ctypes-ffi.patch
@@ -0,0 +1,37 @@
+diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
+index 128506a9ee..ee9ade67b8 100644
+--- a/Modules/_ctypes/cfield.c
++++ b/Modules/_ctypes/cfield.c
+@@ -1462,7 +1462,11 @@ P_get(void *ptr, Py_ssize_t size)
+ return PyLong_FromVoidPtr(*(void **)ptr);
+ }
+
+-static struct fielddesc formattable[] = {
++#define FORMATTABLE_SIZE 30
++static struct fielddesc formattable[FORMATTABLE_SIZE];
++
++static void formattable_init(void) {
++struct fielddesc my_formattable[] = {
+ { 's', s_set, s_get, NULL},
+ { 'b', b_set, b_get, NULL},
+ { 'B', B_set, B_get, NULL},
+@@ -1499,6 +1503,11 @@ static struct fielddesc formattable[] = {
+ { 'O', O_set, O_get, NULL},
+ { 0, NULL, NULL, NULL},
+ };
++ size_t nb = 1;
++ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb);
++ if (FORMATTABLE_SIZE < nb) abort();
++ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc));
++}
+
+ /*
+ Ideas: Implement VARIANT in this table, using 'V' code.
+@@ -1586,6 +1595,7 @@ _ctypes_get_fielddesc(const char *fmt)
+
+ if (!initialized) {
+ initialized = 1;
++ formattable_init();
+ _ctypes_init_fielddesc();
+ }
+
diff --git a/recipes/cpython/all/patches/3.13/3.13.0-0002-remove-module-deps.patch b/recipes/cpython/all/patches/3.13/3.13.0-0002-remove-module-deps.patch
new file mode 100644
index 0000000000000..7b918d63713e0
--- /dev/null
+++ b/recipes/cpython/all/patches/3.13/3.13.0-0002-remove-module-deps.patch
@@ -0,0 +1,50 @@
+diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln
+index bdddec60da..f6a30955bf 100644
+--- a/PCbuild/pcbuild.sln
++++ b/PCbuild/pcbuild.sln
+@@ -9,45 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
+ EndProjectSection
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}"
+- ProjectSection(ProjectDependencies) = postProject
+- {01FDF29A-40A1-46DF-84F5-85EBBD2A2410} = {01FDF29A-40A1-46DF-84F5-85EBBD2A2410}
+- {0E9791DB-593A-465F-98BC-681011311617} = {0E9791DB-593A-465F-98BC-681011311617}
+- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618}
+- {12728250-16EC-4DC6-94D7-E21DD88947F8} = {12728250-16EC-4DC6-94D7-E21DD88947F8}
+- {13CECB97-4119-4316-9D42-8534019A5A44} = {13CECB97-4119-4316-9D42-8534019A5A44}
+- {16BFE6F0-22EF-40B5-B831-7E937119EF10} = {16BFE6F0-22EF-40B5-B831-7E937119EF10}
+- {17E1E049-C309-4D79-843F-AE483C264AEA} = {17E1E049-C309-4D79-843F-AE483C264AEA}
+- {18CAE28C-B454-46C1-87A0-493D91D97F03} = {18CAE28C-B454-46C1-87A0-493D91D97F03}
+- {2097F1C1-597C-4167-93E3-656A7D6339B2} = {2097F1C1-597C-4167-93E3-656A7D6339B2}
+- {28B5D777-DDF2-4B6B-B34F-31D938813856} = {28B5D777-DDF2-4B6B-B34F-31D938813856}
+- {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} = {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781}
+- {384C224A-7474-476E-A01B-750EA7DE918C} = {384C224A-7474-476E-A01B-750EA7DE918C}
+- {447F05A8-F581-4CAC-A466-5AC7936E207E} = {447F05A8-F581-4CAC-A466-5AC7936E207E}
+- {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} = {4946ECAC-2E69-4BF8-A90A-F5136F5094DF}
+- {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} = {494BAC80-A60C-43A9-99E7-ACB691CE2C4D}
+- {54B1431F-B86B-4ACB-B28C-88BCF93191D8} = {54B1431F-B86B-4ACB-B28C-88BCF93191D8}
+- {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} = {6901D91C-6E48-4BB7-9FEC-700C8131DF1D}
+- {6DAC66D9-E703-4624-BE03-49112AB5AA62} = {6DAC66D9-E703-4624-BE03-49112AB5AA62}
+- {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} = {73FCD2BD-F133-46B7-8EC1-144CD82A59D5}
+- {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} = {78D80A15-BD8C-44E2-B49E-1F05B0A0A687}
+- {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480}
+- {885D4898-D08D-4091-9C40-C700CFE3FC5A} = {885D4898-D08D-4091-9C40-C700CFE3FC5A}
+- {900342D7-516A-4469-B1AD-59A66E49A25F} = {900342D7-516A-4469-B1AD-59A66E49A25F}
+- {9E48B300-37D1-11DD-8C41-005056C00008} = {9E48B300-37D1-11DD-8C41-005056C00008}
+- {9EC7190A-249F-4180-A900-548FDCF3055F} = {9EC7190A-249F-4180-A900-548FDCF3055F}
+- {A2697BD3-28C1-4AEC-9106-8B748639FD16} = {A2697BD3-28C1-4AEC-9106-8B748639FD16}
+- {A840DDFB-ED50-484B-B527-B32E7CF90FD5} = {A840DDFB-ED50-484B-B527-B32E7CF90FD5}
+- {B244E787-C445-441C-BDF4-5A4F1A3A1E51} = {B244E787-C445-441C-BDF4-5A4F1A3A1E51}
+- {C6E20F84-3247-4AD6-B051-B073268F73BA} = {C6E20F84-3247-4AD6-B051-B073268F73BA}
+- {CB435430-EBB1-478B-8F4E-C256F6838F55} = {CB435430-EBB1-478B-8F4E-C256F6838F55}
+- {D06B6426-4762-44CC-8BAD-D79052507F2F} = {D06B6426-4762-44CC-8BAD-D79052507F2F}
+- {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} = {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E}
+- {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} = {ECC7CEAC-A5E5-458E-BB9E-2413CC847881}
+- {F749B822-B489-4CA5-A3AD-CE078F5F338A} = {F749B822-B489-4CA5-A3AD-CE078F5F338A}
+- {F9D71780-F393-11E0-BE50-0800200C9A66} = {F9D71780-F393-11E0-BE50-0800200C9A66}
+- {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} = {FCBE1EF2-E0F0-40B1-88B5-00A35D378742}
+- {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} = {FDB84CBB-2FB6-47C8-A2D6-091E0833239D}
+- EndProjectSection
+ EndProject
+ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}"
+ ProjectSection(ProjectDependencies) = postProject
diff --git a/recipes/cpython/all/patches/3.13/3.13.0-0003-relocatable-python-config.patch b/recipes/cpython/all/patches/3.13/3.13.0-0003-relocatable-python-config.patch
new file mode 100644
index 0000000000000..8704135a1423e
--- /dev/null
+++ b/recipes/cpython/all/patches/3.13/3.13.0-0003-relocatable-python-config.patch
@@ -0,0 +1,11 @@
+--- Misc/python-config.sh.in
++++ Misc/python-config.sh.in
+@@ -36,7 +36,7 @@
+ # locations. Keep prefix & exec_prefix using their original values in case
+ # they are referenced in other configure variables, to prevent double
+ # substitution, issue #22140.
+-prefix="@prefix@"
++prefix="$PYTHON_ROOT"
+ exec_prefix="@exec_prefix@"
+ exec_prefix_real=${prefix_real}
+ includedir=$(echo "@includedir@" | sed "s#$prefix#$prefix_real#")
diff --git a/recipes/cpython/all/test_package/conanfile.py b/recipes/cpython/all/test_package/conanfile.py
index 6f20bfa199e7a..5e7591e78f56f 100644
--- a/recipes/cpython/all/test_package/conanfile.py
+++ b/recipes/cpython/all/test_package/conanfile.py
@@ -71,19 +71,19 @@ def generate(self):
deps = CMakeDeps(self)
deps.generate()
- try:
- # CMakeToolchain might generate VCVars, but we need it
- # unconditionally for the setuptools build.
- VCVars(self).generate()
- except ConanException:
- pass
-
# The build also needs access to the run environment to run the python executable
VirtualRunEnv(self).generate(scope="run")
VirtualRunEnv(self).generate(scope="build")
if self._test_setuptools:
- # Just for the distutils build
+ try:
+ # CMakeToolchain might generate VCVars, but we need it
+ # unconditionally for the setuptools build.
+ VCVars(self).generate()
+ except ConanException:
+ pass
+
+ # Just for the setuptools build
AutotoolsDeps(self).generate(scope="build")
def build(self):
@@ -92,8 +92,6 @@ def build(self):
cmake.build()
if self._test_setuptools:
- os.environ["DISTUTILS_USE_SDK"] = "1"
- os.environ["MSSdk"] = "1"
setup_args = [
os.path.join(self.source_folder, "setup.py"),
"build",
@@ -109,7 +107,11 @@ def build(self):
if self.settings.build_type == "Debug":
setup_args.append("--debug")
args = " ".join(f'"{a}"' for a in setup_args)
- self.run(f"{self._python} {args}")
+ env = Environment()
+ env.define("DISTUTILS_USE_SDK", "1")
+ env.define("MSSdk", "1")
+ with env.vars(self).apply():
+ self.run(f"{self._python} {args}")
def _test_module(self, module, should_work):
try:
@@ -144,8 +146,10 @@ def test(self):
self._test_module("bz2", self._cpython_option("with_bz2"))
self._test_module("lzma", self._cpython_option("with_lzma"))
self._test_module("tkinter", self._cpython_option("with_tkinter"))
- os.environ["TERM"] = "ansi"
- self._test_module("curses", self._cpython_option("with_curses"))
+ env = Environment()
+ env.define("TERM", "ansi")
+ with env.vars(self).apply():
+ self._test_module("curses", self._cpython_option("with_curses"))
self._test_module("expat", True)
self._test_module("sqlite3", self._cpython_option("with_sqlite3"))
self._test_module("decimal", True)
@@ -164,22 +168,25 @@ def test(self):
# FIXME: find out why cpython on apple does not allow to use modules linked against a static python
else:
if self._supports_modules:
- os.environ["PYTHONPATH"] = os.path.join(self.build_folder, self.cpp.build.libdirs[0])
+ env = Environment()
+ env.define_path("PYTHONPATH", os.path.join(self.build_folder, self.cpp.build.libdirs[0]))
self.output.info("Testing module (spam) using cmake built module")
- self._test_module("spam", True)
+ with env.vars(self).apply():
+ self._test_module("spam", True)
if self._test_setuptools:
- os.environ["PYTHONPATH"] = os.path.join(self.build_folder, "lib_setuptools")
+ env.define_path("PYTHONPATH", os.path.join(self.build_folder, "lib_setuptools"))
self.output.info("Testing module (spam) using setup.py built module")
- self._test_module("spam", True)
-
- del os.environ["PYTHONPATH"]
+ with env.vars(self).apply():
+ self._test_module("spam", True)
# MSVC builds need PYTHONHOME set. Linux and Mac don't require it to be set if tested after building,
# but if the package is relocated then it needs to be set.
+ env = Environment()
if conan2:
- os.environ["PYTHONHOME"] = self.dependencies["cpython"].conf_info.get("user.cpython:pythonhome", check_type=str)
+ env.define_path("PYTHONHOME", self.dependencies["cpython"].conf_info.get("user.cpython:pythonhome", check_type=str))
else:
- os.environ["PYTHONHOME"] = self.deps_user_info["cpython"].pythonhome
+ env.define_path("PYTHONHOME", self.deps_user_info["cpython"].pythonhome)
bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package")
- self.run(bin_path, env="conanrun")
+ with env.vars(self).apply():
+ self.run(bin_path, env="conanrun")
diff --git a/recipes/cpython/config.yml b/recipes/cpython/config.yml
index a2b9627fa470b..9e701ac2116d4 100644
--- a/recipes/cpython/config.yml
+++ b/recipes/cpython/config.yml
@@ -1,4 +1,6 @@
versions:
+ "3.13.0":
+ folder: "all"
"3.12.7":
folder: "all"
"3.12.2":