-
Notifications
You must be signed in to change notification settings - Fork 1.4k
python-cryptography: update to 49.0.0 #29942
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
Merged
+353
−6
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
327 changes: 327 additions & 0 deletions
327
mingw-w64-python-cryptography/pyo3-fix-python-abi-linking.patch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,327 @@ | ||
| --- a/Cargo.toml | ||
| +++ b/Cargo.toml | ||
| @@ -236,7 +236,17 @@ unsafe_op_in_unsafe_fn = "warn" | ||
| level = "warn" | ||
| check-cfg = [ | ||
| 'cfg(pyo3_disable_reference_pool)', | ||
| - 'cfg(pyo3_leak_on_drop_without_reference_pool)' | ||
| + 'cfg(pyo3_leak_on_drop_without_reference_pool)', | ||
| + 'cfg(pyo3_use_raw_dylib)', | ||
| + # this horrible hard-coded list should be kept in sync with the list of possible | ||
| + # cfgs in pyo3-ffi/src/impl_/macros.rs | ||
| + # | ||
| + # for library names outside of this set we don't support raw-dylib and require a | ||
| + # proper import library | ||
| + # | ||
| + # maybe in the future this list will not be necessary, see | ||
| + # internals.rust-lang.org/t/support-renames-with-link-name-kind-raw-dylib/24415 | ||
| + 'cfg(pyo3_dll, values("python3", "python3_d", "python3t", "python3t_d", "python38", "python38_d", "python39", "python39_d", "python310", "python310_d", "python311", "python311_d", "python312", "python312_d", "python313", "python313_d", "python313t", "python313t_d", "python314", "python314_d", "python314t", "python314t_d", "python315", "python315_d", "python315t", "python315t_d", "python316", "python316_d", "python316t", "python316t_d", "libpypy3.11-c"))', | ||
| ] | ||
|
|
||
|
|
||
| --- a/pyo3-build-config/src/impl_.rs | ||
| +++ b/pyo3-build-config/src/impl_.rs | ||
| @@ -25,15 +25,6 @@ use crate::{ | ||
| /// Minimum Python version PyO3 supports. | ||
| pub(crate) const MINIMUM_SUPPORTED_VERSION: PythonVersion = PythonVersion { major: 3, minor: 9 }; | ||
|
|
||
| -pub(crate) const MINIMUM_SUPPORTED_VERSION_PYPY: PythonVersion = PythonVersion { | ||
| - major: 3, | ||
| - minor: 11, | ||
| -}; | ||
| -pub(crate) const MAXIMUM_SUPPORTED_VERSION_PYPY: PythonVersion = PythonVersion { | ||
| - major: 3, | ||
| - minor: 11, | ||
| -}; | ||
| - | ||
| pub(crate) const MINIMUM_SUPPORTED_VERSION_ABI3T: PythonVersion = PythonVersion { | ||
| major: 3, | ||
| minor: 15, | ||
| @@ -2314,6 +2305,15 @@ fn default_lib_name_for_target(abi: PythonAbi, target: &Triple) -> String { | ||
| } | ||
|
|
||
| fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result<String> { | ||
| + // mingw formats lib names like unix, and uses a "lib" prefix. We could let the linker | ||
| + // handle "lib" prefix, but that means the `raw-dylib` name is incorrect (where the | ||
| + // "lib" prefix is not automatically added).) | ||
| + if mingw { | ||
| + let mut lib_name = default_lib_name_unix(abi, true, None)?; | ||
| + lib_name.insert_str(0, "lib"); | ||
| + return Ok(lib_name); | ||
| + } | ||
| + | ||
| if abi.implementation.is_pypy() { | ||
| // PyPy on Windows ships `libpypy3.X-c.dll` (e.g. `libpypy3.11-c.dll`), | ||
| // not CPython's `pythonXY.dll`. With raw-dylib linking we need the real | ||
| @@ -2341,13 +2341,6 @@ fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result< | ||
| lib_name = lib_name.replace("python3", "python3t"); | ||
| } | ||
| Ok(lib_name) | ||
| - } else if mingw { | ||
| - ensure!( | ||
| - !abi.kind.is_free_threaded(), | ||
| - "MinGW free-threaded builds are not currently tested or supported" | ||
| - ); | ||
| - // https://packages.msys2.org/base/mingw-w64-python | ||
| - Ok(format!("python{}.{}", abi.version.major, abi.version.minor)) | ||
| } else if abi.kind().is_free_threaded() { | ||
| #[expect(deprecated, reason = "using constant internally")] | ||
| { | ||
| @@ -2371,28 +2364,36 @@ fn default_lib_name_windows(abi: PythonAbi, mingw: bool, debug: bool) -> Result< | ||
| } | ||
| } | ||
|
|
||
| -fn default_lib_name_unix(abi: PythonAbi, cygwin: bool, ld_version: Option<&str>) -> Result<String> { | ||
| +fn default_lib_name_unix( | ||
| + abi: PythonAbi, | ||
| + use_stable_abi_lib: bool, | ||
| + ld_version: Option<&str>, | ||
| +) -> Result<String> { | ||
| match abi.implementation { | ||
| PythonImplementation::CPython => match ld_version { | ||
| Some(ld_version) => Ok(format!("python{ld_version}")), | ||
| - None => { | ||
| - if cygwin && matches!(abi.kind, PythonAbiKind::Stable(StableAbi::Abi3)) { | ||
| + None => match abi.kind { | ||
| + PythonAbiKind::Stable(StableAbi::Abi3) if use_stable_abi_lib => { | ||
| Ok("python3".to_string()) | ||
| - } else if cygwin && matches!(abi.kind, PythonAbiKind::Stable(StableAbi::Abi3t)) { | ||
| + } | ||
| + PythonAbiKind::Stable(StableAbi::Abi3t) if use_stable_abi_lib => { | ||
| Ok("python3t".to_string()) | ||
| - } else if abi.kind.is_free_threaded() { | ||
| - #[expect(deprecated, reason = "using constant internally")] | ||
| - { | ||
| - ensure!(abi.version >= PythonVersion::PY313, "Cannot compile extensions for the free-threaded build on Python versions earlier than 3.13, found {}.{}", abi.version.major, abi.version.minor); | ||
| + } | ||
| + _ => { | ||
| + if abi.kind.is_free_threaded() { | ||
| + #[expect(deprecated, reason = "using constant internally")] | ||
| + { | ||
| + ensure!(abi.version >= PythonVersion::PY313, "Cannot compile extensions for the free-threaded build on Python versions earlier than 3.13, found {}.{}", abi.version.major, abi.version.minor); | ||
| + } | ||
| + Ok(format!( | ||
| + "python{}.{}t", | ||
| + abi.version.major, abi.version.minor | ||
| + )) | ||
| + } else { | ||
| + Ok(format!("python{}.{}", abi.version.major, abi.version.minor)) | ||
| } | ||
| - Ok(format!( | ||
| - "python{}.{}t", | ||
| - abi.version.major, abi.version.minor | ||
| - )) | ||
| - } else { | ||
| - Ok(format!("python{}.{}", abi.version.major, abi.version.minor)) | ||
| } | ||
| - } | ||
| + }, | ||
| }, | ||
| PythonImplementation::PyPy => match ld_version { | ||
| Some(ld_version) => Ok(format!("pypy{ld_version}-c")), | ||
| --- a/pyo3-build-config/src/lib.rs | ||
| +++ b/pyo3-build-config/src/lib.rs | ||
| @@ -164,34 +164,6 @@ pub fn print_expected_cfgs() { | ||
| for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::STABLE_ABI_MAX_MINOR + 1 { | ||
| println!("cargo:rustc-check-cfg=cfg(Py_3_{i})"); | ||
| } | ||
| - | ||
| - // pyo3_dll cfg for raw-dylib linking on Windows | ||
| - let mut dll_names = vec![ | ||
| - "python3".to_string(), | ||
| - "python3_d".to_string(), | ||
| - "python3t".to_string(), | ||
| - "python3t_d".to_string(), | ||
| - ]; | ||
| - for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::STABLE_ABI_MAX_MINOR + 1 { | ||
| - dll_names.push(format!("python3{i}")); | ||
| - dll_names.push(format!("python3{i}_d")); | ||
| - if i >= 13 { | ||
| - dll_names.push(format!("python3{i}t")); | ||
| - dll_names.push(format!("python3{i}t_d")); | ||
| - } | ||
| - } | ||
| - // PyPy DLL names (libpypy3.X-c.dll) | ||
| - for i in | ||
| - impl_::MINIMUM_SUPPORTED_VERSION_PYPY.minor..=impl_::MAXIMUM_SUPPORTED_VERSION_PYPY.minor | ||
| - { | ||
| - dll_names.push(format!("libpypy3.{i}-c")); | ||
| - } | ||
| - let values = dll_names | ||
| - .iter() | ||
| - .map(|n| format!("\"{n}\"")) | ||
| - .collect::<Vec<_>>() | ||
| - .join(", "); | ||
| - println!("cargo:rustc-check-cfg=cfg(pyo3_dll, values({values}))"); | ||
| } | ||
|
|
||
| /// Private exports used in PyO3's build.rs | ||
| --- a/pyo3-ffi/build.rs | ||
| +++ b/pyo3-ffi/build.rs | ||
| @@ -191,15 +191,79 @@ fn ensure_target_pointer_width(interpreter_config: &InterpreterConfig) -> Result | ||
| Ok(()) | ||
| } | ||
|
|
||
| +/// `raw-dylib` currently does not support arbitrary names | ||
| +/// (see https://internals.rust-lang.org/t/support-renames-with-link-name-kind-raw-dylib/24415) | ||
| +/// so if the lib name is not one of the known subset, we must fall back to full linking. | ||
| +fn lib_name_is_known_for_raw_dylib(lib_name: &str) -> bool { | ||
| + // pyo3_dll cfg for raw-dylib linking on Windows | ||
| + if matches!( | ||
| + lib_name, | ||
| + "python3" | "python3_d" | "python3t" | "python3t_d" | ||
| + ) { | ||
| + return true; | ||
| + } | ||
| + | ||
| + // support raw-dylib linking for all CPython versions supported, plus the next prerelease | ||
| + for i in SUPPORTED_VERSIONS_CPYTHON.min.minor..=SUPPORTED_VERSIONS_CPYTHON.max.minor + 1 { | ||
| + if lib_name == format!("python3{i}") || lib_name == format!("python3{i}_d") { | ||
| + return true; | ||
| + } | ||
| + if i >= 13 && (lib_name == format!("python3{i}t") || lib_name == format!("python3{i}t_d")) { | ||
| + return true; | ||
| + } | ||
| + } | ||
| + // PyPy DLL names (libpypy3.X-c.dll) | ||
| + for i in SUPPORTED_VERSIONS_PYPY.min.minor..=SUPPORTED_VERSIONS_PYPY.max.minor { | ||
| + if lib_name == format!("libpypy3.{i}-c") { | ||
| + return true; | ||
| + } | ||
| + } | ||
| + | ||
| + false | ||
| +} | ||
| + | ||
| +/// Whether to use raw-dylib linking. | ||
| +/// | ||
| +/// Currently, this only applies if all of the following are true: | ||
| +/// - The target OS is Windows. | ||
| +/// - The Python library name is one of the [known subset][lib_name_is_known_for_raw_dylib]. | ||
| +/// - The `PYO3_USE_RAW_DYLIB` environment variable is not set, or is set to `1`. | ||
| +/// | ||
| +/// NB in some cases (e.g. mixed C / Rust builds) it might be necessary to link the full Python | ||
| +/// library rather than rely on the symbols which PyO3 defines as raw-dylib, which is why | ||
| +/// we have the opt-out env var. | ||
| +fn should_use_raw_dylib_linking(lib_name: &str) -> bool { | ||
| + let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap(); | ||
| + if target_os != "windows" { | ||
| + return false; | ||
| + } | ||
| + | ||
| + match ( | ||
| + lib_name_is_known_for_raw_dylib(lib_name), | ||
| + env_var("PYO3_USE_RAW_DYLIB"), | ||
| + ) { | ||
| + (true, None) => true, | ||
| + (true, Some(os_str)) if os_str == "1" => true, | ||
| + (false, Some(os_str)) if os_str == "1" => { | ||
| + warn!( | ||
| + "PYO3_USE_RAW_DYLIB is set to 1 but the Python library name is not recognized. \ | ||
| + Falling back to full linking." | ||
| + ); | ||
| + false | ||
| + } | ||
| + _ => false, | ||
| + } | ||
| +} | ||
| + | ||
| fn emit_link_config(build_config: &BuildConfig) -> Result<()> { | ||
| - let interpreter_config = &build_config.interpreter_config; | ||
| let target_os = cargo_env_var("CARGO_CFG_TARGET_OS").unwrap(); | ||
| + let interpreter_config = &build_config.interpreter_config; | ||
|
|
||
| let lib_name = interpreter_config | ||
| .lib_name() | ||
| .ok_or("attempted to link to Python shared library but config does not contain lib_name")?; | ||
|
|
||
| - if target_os == "windows" { | ||
| + if should_use_raw_dylib_linking(lib_name) { | ||
| // Use raw-dylib linking: emit a cfg so that `extern_libpython!` picks the | ||
| // right `#[link(name = "...", kind = "raw-dylib")]` attribute at compile time. | ||
| // This eliminates the need for import libraries (.lib files) entirely. | ||
| @@ -207,27 +271,36 @@ fn emit_link_config(build_config: &BuildConfig) -> Result<()> { | ||
| // Note: raw-dylib is inherently dynamic linking. Static embedding of the | ||
| // Python interpreter on Windows is not supported by this path (and is not | ||
| // officially supported by CPython on Windows). | ||
| + println!("cargo:rustc-cfg=pyo3_use_raw_dylib"); | ||
| println!("cargo:rustc-cfg=pyo3_dll=\"{lib_name}\""); | ||
| - } else { | ||
| - println!( | ||
| - "cargo:rustc-link-lib={link_model}{lib_name}", | ||
| - link_model = if interpreter_config.shared() { | ||
| - "" | ||
| - } else { | ||
| - "static=" | ||
| - }, | ||
| - ); | ||
| + return Ok(()); | ||
| + } | ||
|
|
||
| - if let Some(lib_dir) = interpreter_config.lib_dir() { | ||
| - println!("cargo:rustc-link-search=native={lib_dir}"); | ||
| - } else if matches!(build_config.source, BuildConfigSource::CrossCompile) { | ||
| - warn!( | ||
| - "The output binary will link to libpython, \ | ||
| - but PYO3_CROSS_LIB_DIR environment variable is not set. \ | ||
| - Ensure that the target Python library directory is \ | ||
| - in the rustc native library search path." | ||
| - ); | ||
| + println!( | ||
| + "cargo:rustc-link-lib={link_model}{alias}{lib_name}", | ||
| + link_model = if interpreter_config.shared() { | ||
| + "" | ||
| + } else { | ||
| + "static=" | ||
| + }, | ||
| + // on windows we emit `#[link(name = "pythonXY")]` attributes | ||
| + // and need this alias here to get the right name for the final link | ||
| + alias = if target_os == "windows" { | ||
| + "pythonXY:" | ||
| + } else { | ||
| + "" | ||
| } | ||
| + ); | ||
| + | ||
| + if let Some(lib_dir) = interpreter_config.lib_dir() { | ||
| + println!("cargo:rustc-link-search=native={lib_dir}"); | ||
| + } else if matches!(build_config.source, BuildConfigSource::CrossCompile) { | ||
| + warn!( | ||
| + "The output binary will link to libpython, \ | ||
| + but PYO3_CROSS_LIB_DIR environment variable is not set. \ | ||
| + Ensure that the target Python library directory is \ | ||
| + in the rustc native library search path." | ||
| + ); | ||
| } | ||
|
|
||
| Ok(()) | ||
| --- a/pyo3-ffi/src/impl_/macros.rs | ||
| +++ b/pyo3-ffi/src/impl_/macros.rs | ||
| @@ -268,10 +268,12 @@ macro_rules! extern_libpython { | ||
| "python313", "python313_d", | ||
| "python314", "python314_d", | ||
| "python315", "python315_d", | ||
| + "python316", "python316_d", | ||
| // free-threaded builds (3.13+) | ||
| "python313t", "python313t_d", | ||
| "python314t", "python314t_d", | ||
| "python315t", "python315t_d", | ||
| + "python316t", "python316t_d", | ||
| // PyPy (DLL is libpypy3.X-c.dll, not pythonXY.dll) | ||
| "libpypy3.11-c", | ||
| ); | ||
| @@ -286,11 +288,12 @@ macro_rules! extern_libpython { | ||
| // separate cfg_attr arms per architecture. | ||
| (@impl $abi:literal { $($body:tt)* } $($dll:literal),* $(,)?) => { | ||
| $( | ||
| - #[cfg_attr(all(windows, target_arch = "x86", pyo3_dll = $dll), | ||
| + #[cfg_attr(all(windows, pyo3_use_raw_dylib, target_arch = "x86", pyo3_dll = $dll), | ||
| link(name = $dll, kind = "raw-dylib", import_name_type = "undecorated"))] | ||
| - #[cfg_attr(all(windows, not(target_arch = "x86"), pyo3_dll = $dll), | ||
| + #[cfg_attr(all(windows, pyo3_use_raw_dylib, not(target_arch = "x86"), pyo3_dll = $dll), | ||
| link(name = $dll, kind = "raw-dylib"))] | ||
| )* | ||
| + #[cfg_attr(all(windows, not(pyo3_use_raw_dylib)), link(name = "pythonXY"))] | ||
| extern $abi { | ||
| extern_libpython_items! { $($body)* } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that you shouldn't need to set this - I think that PyO3 should automatically notice that your lib name isn't in the hardcoded set which support
raw-dyliblinking and toggle this mode automatically.(Hopefully in the future the
raw-dyliblink set shouldn't be hardcoded, this seems to be a limitation in rustc and I'll work to fix it there.)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
without env var it didn't work:(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please retry with latest commit PyO3/pyo3@9451f0e ? I think that should now remove the need for the env var properly (so mingw users do not need to set this for their arbitrary builds)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll try later in the evening
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll push these hunks, but it didn't work on my machine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, thanks. I guess we keep it like this for now in the patch release, I'll work on a better long-term fix upstream.