From 72be1cddba022d9fbd8ce3275455966095d5712d Mon Sep 17 00:00:00 2001 From: Icxolu <10486322+Icxolu@users.noreply.github.com> Date: Wed, 8 May 2024 07:46:00 +0200 Subject: [PATCH] emit `cargo:rustc-check-cfg=CHECK_CFG` for `pyo3`s config names (#4163) --- build.rs | 1 + guide/src/migration.md | 4 ++-- pyo3-build-config/src/impl_.rs | 4 ++-- pyo3-build-config/src/lib.rs | 20 ++++++++++++++++++++ pyo3-ffi/build.rs | 1 + src/marker.rs | 2 +- src/tests/hygiene/pyclass.rs | 10 +++++----- 7 files changed, 32 insertions(+), 10 deletions(-) diff --git a/build.rs b/build.rs index 28592004..5d638291 100644 --- a/build.rs +++ b/build.rs @@ -46,6 +46,7 @@ fn configure_pyo3() -> Result<()> { } fn main() { + pyo3_build_config::print_expected_cfgs(); if let Err(e) = configure_pyo3() { eprintln!("error: {}", e.report()); std::process::exit(1) diff --git a/guide/src/migration.md b/guide/src/migration.md index ad39adfa..0a048bf0 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -339,12 +339,12 @@ To make PyO3's core functionality continue to work while the GIL Refs API is in PyO3 0.21 has introduced the [`PyBackedStr`]({{#PYO3_DOCS_URL}}/pyo3/pybacked/struct.PyBackedStr.html) and [`PyBackedBytes`]({{#PYO3_DOCS_URL}}/pyo3/pybacked/struct.PyBackedBytes.html) types to help with this case. The easiest way to avoid lifetime challenges from extracting `&str` is to use these. For more complex types like `Vec<&str>`, is now impossible to extract directly from a Python object and `Vec` is the recommended upgrade path. -A key thing to note here is because extracting to these types now ties them to the input lifetime, some extremely common patterns may need to be split into multiple Rust lines. For example, the following snippet of calling `.extract::<&str>()` directly on the result of `.getattr()` needs to be adjusted when deactivating the `gil-refs-migration` feature. +A key thing to note here is because extracting to these types now ties them to the input lifetime, some extremely common patterns may need to be split into multiple Rust lines. For example, the following snippet of calling `.extract::<&str>()` directly on the result of `.getattr()` needs to be adjusted when deactivating the `gil-refs` feature. Before: ```rust -# #[cfg(feature = "gil-refs-migration")] { +# #[cfg(feature = "gil-refs")] { # use pyo3::prelude::*; # use pyo3::types::{PyList, PyType}; # fn example<'py>(py: Python<'py>) -> PyResult<()> { diff --git a/pyo3-build-config/src/impl_.rs b/pyo3-build-config/src/impl_.rs index 2ee68503..35c300da 100644 --- a/pyo3-build-config/src/impl_.rs +++ b/pyo3-build-config/src/impl_.rs @@ -30,7 +30,7 @@ use crate::{ }; /// Minimum Python version PyO3 supports. -const MINIMUM_SUPPORTED_VERSION: PythonVersion = PythonVersion { major: 3, minor: 7 }; +pub(crate) const MINIMUM_SUPPORTED_VERSION: PythonVersion = PythonVersion { major: 3, minor: 7 }; /// GraalPy may implement the same CPython version over multiple releases. const MINIMUM_SUPPORTED_VERSION_GRAALPY: PythonVersion = PythonVersion { @@ -39,7 +39,7 @@ const MINIMUM_SUPPORTED_VERSION_GRAALPY: PythonVersion = PythonVersion { }; /// Maximum Python version that can be used as minimum required Python version with abi3. -const ABI3_MAX_MINOR: u8 = 12; +pub(crate) const ABI3_MAX_MINOR: u8 = 12; /// Gets an environment variable owned by cargo. /// diff --git a/pyo3-build-config/src/lib.rs b/pyo3-build-config/src/lib.rs index 1aa15d7d..24d3ae28 100644 --- a/pyo3-build-config/src/lib.rs +++ b/pyo3-build-config/src/lib.rs @@ -43,6 +43,7 @@ use target_lexicon::OperatingSystem; /// For examples of how to use these attributes, [see PyO3's guide](https://pyo3.rs/latest/building-and-distribution/multiple_python_versions.html). #[cfg(feature = "resolve-config")] pub fn use_pyo3_cfgs() { + print_expected_cfgs(); for cargo_command in get().build_script_outputs() { println!("{}", cargo_command) } @@ -153,6 +154,25 @@ pub fn print_feature_cfgs() { } } +/// Registers `pyo3`s config names as reachable cfg expressions +/// +/// - +/// - +#[doc(hidden)] +pub fn print_expected_cfgs() { + println!("cargo:rustc-check-cfg=cfg(Py_LIMITED_API)"); + println!("cargo:rustc-check-cfg=cfg(PyPy)"); + println!("cargo:rustc-check-cfg=cfg(GraalPy)"); + println!("cargo:rustc-check-cfg=cfg(py_sys_config, values(\"Py_DEBUG\", \"Py_REF_DEBUG\", \"Py_TRACE_REFS\", \"COUNT_ALLOCS\"))"); + println!("cargo:rustc-check-cfg=cfg(invalid_from_utf8_lint)"); + + // allow `Py_3_*` cfgs from the minimum supported version up to the + // maximum minor version (+1 for development for the next) + for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::ABI3_MAX_MINOR + 1 { + println!("cargo:rustc-check-cfg=cfg(Py_3_{i})"); + } +} + /// Private exports used in PyO3's build.rs /// /// Please don't use these - they could change at any time. diff --git a/pyo3-ffi/build.rs b/pyo3-ffi/build.rs index 405da889..23f03f1a 100644 --- a/pyo3-ffi/build.rs +++ b/pyo3-ffi/build.rs @@ -205,6 +205,7 @@ fn print_config_and_exit(config: &InterpreterConfig) { } fn main() { + pyo3_build_config::print_expected_cfgs(); if let Err(e) = configure_pyo3() { eprintln!("error: {}", e.report()); std::process::exit(1) diff --git a/src/marker.rs b/src/marker.rs index c975a4a3..2230d776 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -96,7 +96,7 @@ //! enabled, `Ungil` is defined as the following: //! //! ```rust -//! # #[cfg(FALSE)] +//! # #[cfg(any())] //! # { //! #![feature(auto_traits, negative_impls)] //! diff --git a/src/tests/hygiene/pyclass.rs b/src/tests/hygiene/pyclass.rs index 4d07009c..0bdb280d 100644 --- a/src/tests/hygiene/pyclass.rs +++ b/src/tests/hygiene/pyclass.rs @@ -39,11 +39,11 @@ pub enum Enum { #[pyo3(crate = "crate")] pub struct Foo3 { #[pyo3(get, set)] - #[cfg(FALSE)] + #[cfg(any())] field: i32, #[pyo3(get, set)] - #[cfg(not(FALSE))] + #[cfg(not(any()))] field: u32, } @@ -51,11 +51,11 @@ pub struct Foo3 { #[pyo3(crate = "crate")] pub struct Foo4 { #[pyo3(get, set)] - #[cfg(FALSE)] - #[cfg(not(FALSE))] + #[cfg(any())] + #[cfg(not(any()))] field: i32, #[pyo3(get, set)] - #[cfg(not(FALSE))] + #[cfg(not(any()))] field: u32, }