diff --git a/noxfile.py b/noxfile.py index bd7bf17e7fc..956c9ce56a3 100644 --- a/noxfile.py +++ b/noxfile.py @@ -192,7 +192,8 @@ def generate_coverage_report(session: nox.Session) -> None: @nox.session(venv_backend="none") def rustfmt(session: nox.Session): _run_cargo(session, "fmt", "--all", "--check") - _run_cargo(session, "fmt", _FFI_CHECK, "--all", "--check") + with session.cd(_FFI_CHECK_DIR): + _run_cargo(session, "fmt", "--all", "--check") @nox.session(name="ruff") @@ -255,8 +256,8 @@ def _clippy_additional_workspaces(session: nox.Session) -> bool: target = os.environ.get("CARGO_BUILD_TARGET") if target is None or _get_rust_default_target() == target: try: - _build_docs_for_ffi_check(session) - _run_cargo(session, "clippy", _FFI_CHECK, "--workspace", "--all-targets") + with session.cd(_FFI_CHECK_DIR): + _run_cargo(session, "clippy", "--workspace", "--all-targets") except Exception: success = False return success @@ -939,10 +940,10 @@ def load_pkg_versions(): ) -@nox.session(name="ffi-check") +@nox.session(name="ffi-check", venv_backend="none") def ffi_check(session: nox.Session): - _build_docs_for_ffi_check(session) - _run_cargo(session, "run", _FFI_CHECK) + with session.cd(_FFI_CHECK_DIR): + _run_cargo(session, "run") @nox.session(name="test-version-limits") @@ -1131,13 +1132,6 @@ def test_introspection(session: nox.Session): ) -def _build_docs_for_ffi_check(session: nox.Session) -> None: - # pyo3-ffi-check needs to scrape docs of pyo3-ffi - env = os.environ.copy() - env["PYO3_PYTHON"] = sys.executable - _run_cargo(session, "doc", _FFI_CHECK, "-p", "pyo3-ffi", "--no-deps", env=env) - - @lru_cache() def _get_rust_info() -> Tuple[str, ...]: output = _get_output("rustc", "-vV") @@ -1345,4 +1339,7 @@ def _is_github_actions() -> bool: _BENCHES = "--manifest-path=pyo3-benches/Cargo.toml" -_FFI_CHECK = "--manifest-path=pyo3-ffi-check/Cargo.toml" + +# NB: to pick up correct cargo configuration, always invoke cargo commands for ffi-check +# from within the ffi-check directory +_FFI_CHECK_DIR = PYO3_DIR / "pyo3-ffi-check" diff --git a/pyo3-ffi-check/.cargo/config.toml b/pyo3-ffi-check/.cargo/config.toml new file mode 100644 index 00000000000..ab7fc1ea7c4 --- /dev/null +++ b/pyo3-ffi-check/.cargo/config.toml @@ -0,0 +1,5 @@ +[env] +# a lazy way to skip linking to Python; ffi-check uses the symbols and values but doesn't call any Python APIs +# +# NB this config file is only used when cargo is invoke from the pyo3-ffi-check directory. +PYO3_BUILD_EXTENSION_MODULE = "1" diff --git a/pyo3-ffi-check/Cargo.toml b/pyo3-ffi-check/Cargo.toml index cdf38c9f9bf..6c861139098 100644 --- a/pyo3-ffi-check/Cargo.toml +++ b/pyo3-ffi-check/Cargo.toml @@ -6,10 +6,7 @@ publish = false [dependencies] pyo3-ffi-check-macro = { path = "./macro" } - -[dependencies.pyo3-ffi] -path = "../pyo3-ffi" -features = ["extension-module"] # A lazy way of skipping linking in most cases (as we don't use any runtime symbols) +pyo3-ffi = { path = "../pyo3-ffi" } [build-dependencies] bindgen = "0.69.4" diff --git a/pyo3-ffi-check/build.rs b/pyo3-ffi-check/build.rs index e7cfbe40df3..5d7bfdd948d 100644 --- a/pyo3-ffi-check/build.rs +++ b/pyo3-ffi-check/build.rs @@ -21,6 +21,31 @@ impl bindgen::callbacks::ParseCallbacks for ParseCallbacks { fn main() { let config = pyo3_build_config::get(); + + // build docs for pyo3-ffi + let docs_build = std::process::Command::new("cargo") + .args([ + "doc", + "--manifest-path", + &format!("{}/Cargo.toml", env::var("CARGO_MANIFEST_DIR").unwrap()), + "--target-dir", + &format!("{}/doc_build", env::var("OUT_DIR").unwrap()), + "--no-deps", + "--package", + "pyo3-ffi", + ]) + .env( + "PYO3_PYTHON", + config + .executable + .as_ref() + .expect("need executable for ffi check"), + ) + .status() + .expect("failed to build pyo3-ffi docs"); + + assert!(docs_build.success(), "failed to build pyo3-ffi docs"); + let python_include_dir = config .run_python_script( "import sysconfig; print(sysconfig.get_config_var('INCLUDEPY'), end='');", diff --git a/pyo3-ffi-check/macro/src/lib.rs b/pyo3-ffi-check/macro/src/lib.rs index 41092b9020e..3a19fa8aa50 100644 --- a/pyo3-ffi-check/macro/src/lib.rs +++ b/pyo3-ffi-check/macro/src/lib.rs @@ -1,4 +1,7 @@ -use std::{env, fs, path::PathBuf}; +use std::{ + env, fs, + path::{Path, PathBuf}, +}; use proc_macro2::{Ident, Span, TokenStream, TokenTree}; use pyo3_build_config::PythonVersion; @@ -67,16 +70,7 @@ pub fn for_all_structs(input: proc_macro::TokenStream) -> proc_macro::TokenStrea } fn get_doc_dir() -> PathBuf { - let path = PathBuf::from(env::var_os("OUT_DIR").unwrap()); - path.parent() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .parent() - .unwrap() - .to_owned() + Path::new(&env::var_os("OUT_DIR").unwrap()).join("doc_build") } /// Macro which expands to multiple macro calls, one per field in a pyo3-ffi