Improvements based on code review: API and documentation.

This commit is contained in:
Ashley Anderson 2022-03-21 12:55:39 -04:00
parent bbe7a493d6
commit 4a62a62cae
4 changed files with 39 additions and 28 deletions

View File

@ -10,7 +10,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Allow to allow dependent crates to access values from `pyo3-build-config` via cargo link env vars. [#2092](https://github.com/PyO3/pyo3/pull/2092)
- Allow dependent crates to access config values from `pyo3-build-config` via cargo link dep env vars. [#2092](https://github.com/PyO3/pyo3/pull/2092)
- Added methods on `InterpreterConfig` to run Python scripts using the configured executable. [#2092](https://github.com/PyO3/pyo3/pull/2092)
### Fixed

View File

@ -341,12 +341,9 @@ print("mingw", get_platform().startswith("mingw"))
}
#[doc(hidden)]
pub fn from_cargo_link_env() -> Result<Self> {
// un-escape any newlines in the exported config
let buf = cargo_env_var("DEP_PYTHON_PYO3_CONFIG")
.unwrap()
.replace("\\n", "\n");
InterpreterConfig::from_reader(buf.as_bytes())
pub fn from_cargo_dep_env() -> Option<Result<Self>> {
cargo_env_var("DEP_PYTHON_PYO3_CONFIG")
.map(|buf| InterpreterConfig::from_reader(buf.replace("\\n", "\n").as_bytes()))
}
#[doc(hidden)]
@ -430,7 +427,17 @@ print("mingw", get_platform().startswith("mingw"))
}
#[doc(hidden)]
pub fn to_cargo_link_env(&self) -> Result<()> {
/// Serialize the `InterpreterConfig` and print it to the environment for Cargo to pass along
/// to dependent packages during build time.
///
/// NB: writing to the cargo environment requires the
/// [`links`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key)
/// manifest key to be set. In this case that means this is called by the `pyo3-ffi` crate and
/// available for dependent package build scripts in `DEP_PYTHON_PYO3_CONFIG`. See
/// documentation for the
/// [`DEP_<name>_<key>`](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts)
/// environment variable.
pub fn to_cargo_dep_env(&self) -> Result<()> {
let mut buf = Vec::new();
self.to_writer(&mut buf)?;
// escape newlines in env var
@ -485,8 +492,25 @@ print("mingw", get_platform().startswith("mingw"))
Ok(())
}
/// Run a python script using the executable of this InterpreterConfig with additional
/// Run a python script using the [`InterpreterConfig::executable`].
///
/// # Panics
///
/// This function will panic if the [`executable`](InterpreterConfig::executable) is `None`.
pub fn run_python_script(&self, script: &str) -> Result<String> {
run_python_script_with_envs(
Path::new(self.executable.as_ref().expect("no interpreter executable")),
script,
std::iter::empty::<(&str, &str)>(),
)
}
/// Run a python script using the [`InterpreterConfig::executable`] with additional
/// environment variables (e.g. PYTHONPATH) set.
///
/// # Panics
///
/// This function will panic if the [`executable`](InterpreterConfig::executable) is `None`.
pub fn run_python_script_with_envs<I, K, V>(&self, script: &str, envs: I) -> Result<String>
where
I: IntoIterator<Item = (K, V)>,
@ -499,15 +523,6 @@ print("mingw", get_platform().startswith("mingw"))
envs,
)
}
/// Run a python script using the executable of this InterpreterConfig.
pub fn run_python_script(&self, script: &str) -> Result<String> {
run_python_script_with_envs(
Path::new(self.executable.as_ref().expect("no interpreter executable")),
script,
std::iter::empty::<(&str, &str)>(),
)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
@ -592,11 +607,6 @@ fn is_abi3() -> bool {
cargo_env_var("CARGO_FEATURE_ABI3").is_some()
}
#[allow(unused)]
pub fn link_env_var_set() -> bool {
cargo_env_var("DEP_PYTHON_PYO3_CONFIG").is_some()
}
#[derive(Debug, PartialEq)]
struct TargetInfo {
/// The `arch` component of the compilation target triple.

View File

@ -65,18 +65,18 @@ fn _add_extension_module_link_args(target_os: &str, mut writer: impl std::io::Wr
pub fn get() -> &'static InterpreterConfig {
static CONFIG: OnceCell<InterpreterConfig> = OnceCell::new();
CONFIG.get_or_init(|| {
if !CONFIG_FILE.is_empty() {
if let Some(interpreter_config) = InterpreterConfig::from_cargo_dep_env() {
interpreter_config
} else if !CONFIG_FILE.is_empty() {
InterpreterConfig::from_reader(Cursor::new(CONFIG_FILE))
} else if !ABI3_CONFIG.is_empty() {
Ok(abi3_config())
} else if impl_::cross_compile_env_vars().any() {
InterpreterConfig::from_path(DEFAULT_CROSS_COMPILE_CONFIG_PATH)
} else if impl_::link_env_var_set() {
InterpreterConfig::from_cargo_link_env()
} else {
InterpreterConfig::from_reader(Cursor::new(HOST_CONFIG))
}
.expect("failed to parse PyO3 config file")
.expect("failed to parse PyO3 config")
})
}

View File

@ -70,7 +70,7 @@ fn emit_link_config(interpreter_config: &InterpreterConfig) -> Result<()> {
}
// serialize the whole interpreter config in DEP_PYTHON_PYO3_CONFIG
interpreter_config.to_cargo_link_env()?;
interpreter_config.to_cargo_dep_env()?;
Ok(())
}