Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions newsfragments/6180.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed `PYO3_CONFIG_FILE` handling for free-threaded Python versions before 3.15 when `abi3t-py315` is enabled.
159 changes: 131 additions & 28 deletions pyo3-build-config/src/impl_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,31 @@ fn sanitize_stable_abi_version(
}
}

fn stable_abi_version_for_target(
implementation: PythonImplementation,
version: PythonVersion,
abi3_version: Option<PythonVersion>,
abi3t_version: Option<PythonVersion>,
gil_disabled: bool,
) -> Option<PythonVersion> {
if matches!(
implementation,
PythonImplementation::PyPy | PythonImplementation::GraalPy
) {
None
} else if version >= PythonVersion::PY315 {
match gil_disabled {
false => abi3t_version.or(abi3_version),
true => abi3t_version,
}
} else {
match gil_disabled {
false => abi3_version,
true => None,
}
}
}

/// Configuration needed by PyO3 to build for the correct Python implementation.
///
/// The version and implementation fields correspond to the interpreter
Expand Down Expand Up @@ -498,24 +523,13 @@ print("gil_disabled", get_config_var("Py_GIL_DISABLED"))
_ => panic!("Unknown Py_GIL_DISABLED value"),
};

let stable_abi_version = if !matches!(
let stable_abi_version = stable_abi_version_for_target(
implementation,
PythonImplementation::PyPy | PythonImplementation::GraalPy
) {
if version >= PythonVersion::PY315 {
match gil_disabled {
false => abi3t_version.or(abi3_version),
true => abi3t_version,
}
} else {
match gil_disabled {
false => abi3_version,
true => None,
}
}
} else {
None
};
version,
abi3_version,
abi3t_version,
gil_disabled,
);

let target_abi =
PythonAbi::from_build_env(implementation, version, stable_abi_version, gil_disabled)?;
Expand Down Expand Up @@ -883,20 +897,19 @@ print("gil_disabled", get_config_var("Py_GIL_DISABLED"))
}

fn apply_build_env(mut self) -> Result<InterpreterConfig> {
let abi3_version = if self.target_abi.kind.is_free_threaded()
|| matches!(
self.target_abi.implementation,
PythonImplementation::PyPy | PythonImplementation::GraalPy
) {
None
} else {
get_abi3_version()
};
let gil_disabled = self.target_abi.kind().is_free_threaded();
let stable_abi_version = stable_abi_version_for_target(
self.implementation,
self.version,
exact_stable_abi_version(get_abi3_version()),
exact_stable_abi_version(get_abi3t_version()),
gil_disabled,
);
self.target_abi = PythonAbi::from_build_env(
self.implementation,
self.version,
exact_stable_abi_version(abi3_version.or(get_abi3t_version())),
self.target_abi.kind().is_free_threaded(),
stable_abi_version,
gil_disabled,
)?;
Ok(self)
}
Expand Down Expand Up @@ -2797,6 +2810,96 @@ mod tests {
);
}

#[test]
fn stable_abi_version_for_target_matches_abi_support() {
let abi3_version = Some(PythonVersion::PY310);
let abi3t_version = Some(PythonVersion::PY315);

// A free-threaded 3.14 config from PYO3_CONFIG_FILE must remain
// version-specific, even when an abi3t-py315 feature is enabled.
assert_eq!(
stable_abi_version_for_target(
PythonImplementation::CPython,
PythonVersion::PY314,
abi3_version,
abi3t_version,
true,
),
None
);

assert_eq!(
stable_abi_version_for_target(
PythonImplementation::CPython,
PythonVersion::PY314,
abi3_version,
abi3t_version,
false,
),
abi3_version
);
assert_eq!(
stable_abi_version_for_target(
PythonImplementation::CPython,
PythonVersion::PY315,
abi3_version,
abi3t_version,
true,
),
abi3t_version
);
assert_eq!(
stable_abi_version_for_target(
PythonImplementation::CPython,
PythonVersion::PY315,
abi3_version,
abi3t_version,
false,
),
abi3t_version
);
assert_eq!(
stable_abi_version_for_target(
PythonImplementation::CPython,
PythonVersion::PY315,
abi3_version,
None,
true,
),
None
);
assert_eq!(
stable_abi_version_for_target(
PythonImplementation::CPython,
PythonVersion::PY315,
abi3_version,
None,
false,
),
abi3_version
);
assert_eq!(
stable_abi_version_for_target(
PythonImplementation::PyPy,
PythonVersion::PY315,
abi3_version,
abi3t_version,
false,
),
None
);
assert_eq!(
stable_abi_version_for_target(
PythonImplementation::GraalPy,
PythonVersion::PY315,
abi3_version,
abi3t_version,
false,
),
None
);
}

#[test]
fn abi3_from_old_config_file() {
let implementation = PythonImplementation::CPython;
Expand Down
Loading