Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cpython 3.13.0 #25536

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
13 changes: 13 additions & 0 deletions recipes/cpython/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"
uilianries marked this conversation as resolved.
Show resolved Hide resolved
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"
Expand Down
35 changes: 23 additions & 12 deletions recipes/cpython/all/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -315,13 +317,21 @@ def _patch_msvc_projects(self):
replace_in_file(self, self._msvc_project_path("_ssl"), '<Import Project="openssl.props" />', "")

# 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"), "<CustomBuild", "<!--<CustomBuild")
replace_in_file(self, self._msvc_project_path("_decimal"), "</CustomBuild>", "</CustomBuild>-->")
# 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"),
Expand Down Expand Up @@ -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}"
Expand Down Expand Up @@ -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):
Expand Down
37 changes: 37 additions & 0 deletions recipes/cpython/all/patches/3.13/3.13.0-0001-_ctypes-ffi.patch
Original file line number Diff line number Diff line change
@@ -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();
}

Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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#")
51 changes: 29 additions & 22 deletions recipes/cpython/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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",
Expand All @@ -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:
Expand Down Expand Up @@ -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)
Expand All @@ -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")
2 changes: 2 additions & 0 deletions recipes/cpython/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
versions:
"3.13.0":
folder: "all"
"3.12.7":
folder: "all"
"3.12.2":
Expand Down