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":