Skip to content

'pyo3' is in scope, but it is a crate, not an attribute when used with cfg_attr() #5125

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

Open
altendky opened this issue May 8, 2025 · 2 comments
Labels

Comments

@altendky
Copy link

altendky commented May 8, 2025

Bug Description

Cargo.toml

[package]
name = "pyo3_cfg_attr"
version = "0.1.0"
edition = "2024"

[dependencies]
pyo3 = "0.24.2"

[features]
py-bindings = []
work = []
fail = []

src/main.rs

#[cfg(feature = "fail")]
#[cfg_attr(feature = "py-bindings", pyo3::prelude::pyclass)]
pub struct MyClass(
    #[cfg_attr(
        feature="py-bindings",
        pyo3(get, name = "raw"),
    )]
    u8,
);

#[cfg(feature = "work")]
#[cfg_attr(feature = "py-bindings", pyo3::prelude::pyclass)]
pub struct MyClass(
    #[pyo3(get, name = "raw")]
    u8,
);

fn main() {
    println!("Hello, world!");
}

working

$ cargo +1.86.0 build --features py-bindings,work
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03s

failing

$ cargo +1.86.0 build --features py-bindings,fail
   Compiling pyo3_cfg_attr v0.1.0 (/home/altendky/tmp/r/pyo3_cfg_attr)
error: cannot find attribute `pyo3` in this scope
 --> src/main.rs:6:9
  |
6 |         pyo3(get, name = "raw"),
  |         ^^^^
  |
  = note: `pyo3` is in scope, but it is a crate, not an attribute

error: could not compile `pyo3_cfg_attr` (bin "pyo3_cfg_attr") due to 1 previous error

Steps to Reproduce

Copy files above locally. Build with --features py-bindings,fail.

Backtrace

Your operating system and version

Ubuntu 22.04.5 LTS

Your Python version (python --version)

Python 3.12.7 (main, Nov 20 2024, 20:26:30) [GCC 11.4.0] (local pyenv build)

Your Rust version (rustc --version)

rustc 1.86.0 (05f9846f8 2025-03-31)

Your PyO3 version

0.24.2

How did you install python? Did you use a virtualenv?

Python was built with pyenv. I normally do work in virtualenvs but did not create one for this report.

Additional Info

I have worked around this by duplicating code guarded by #[cfg(feature = "py-bindings")] and #[cfg(not(feature = "py-bindings"))].

@altendky altendky added the bug label May 8, 2025
@altendky altendky changed the title \pyo3\ is in scope, but it is a crate, not an attribute when used with cfg_attr() 'pyo3' is in scope, but it is a crate, not an attribute when used with cfg_attr() May 8, 2025
@mejrs
Copy link
Member

mejrs commented May 9, 2025

In general that is hard because pyo3 macros see the cfg_attr, not what it would expand into (in other words, the expansion order is the other way around). You can use #[cfg_eval] to invert that order but there is no buy-in to that feature and its future is unclear, so you should not rely on it.

We're open to supporting use cases like this, but something like #[cfg_attr(thing, pyo3(get, name = "raw"))] appears to be impossible to do in a non-hacky way.

There is some code in pyo3 that just forwards cfgs to generated items, but that does not work for this case.

Also see #1003 and #780

@mejrs
Copy link
Member

mejrs commented May 9, 2025

See also #2692 which introduced #[pyclass(set_all, get_all)], which probably works for your case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants