-
Notifications
You must be signed in to change notification settings - Fork 778
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
Hygiene: offer a way to set path to pyo3 crate #2022
Conversation
Thanks! Will try to give this a full review tomorrow sometime.
That's totally reasonable to me; I think that's the plan for 0.16. |
4e5999a
to
88e4025
Compare
When you review, you can exclude the first commit, which is just replacing |
88e4025
to
9c225a6
Compare
This is now feature complete, but I'm unsure how to test it: |
9c225a6
to
a695f68
Compare
Ah yes, and there is still the issue of generating unique but reproducible |
I think adding a separate crate like those in the examples folder as a kind of build test that is explicitly invoked by the CI could work? |
If we do away with the self-dependency: # features needed to run the PyO3 test suite
pyo3 = { path = ".", default-features = false, features = ["macros", "auto-initialize"] }
#[test]
fn test(){
#[crate::pyclass(pyo3_path=crate)]
struct Foo;
} |
#1817 seems to be blocked on some other things though. |
It should still raise a compilation error if types/functions/traits from For example, this test doesn't compile: pub struct Foo;
pub fn take_foo(_: Foo){}
#[cfg(test)]
#[test]
fn bar(){
let foo = crate::Foo;
::pyo3::take_foo(foo);
} |
@davidhewitt do you have an idea how to generate unique constant names for the |
Sorry was hoping to give this a full read soon! Can we get away with just doing |
Oh wow, that works? facepalm it does! |
caa3d06
to
515eb0d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do away with the self-dependency:
Seeing this very clever idea convinced me to take another look at that - see #2039
|
||
## I want to use the `pyo3` crate re-exported from from dependency but the proc-macros fail! | ||
|
||
All PyO3 proc-macros (`#[pyclass]`, `#[pyfunction]`, `#[derive(FromPyObject)]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be nice to document this alongside each macro too. I really like serde's reference on attributes e.g. https://serde.rs/container-attrs.html
I've tried to do this a bit for #[pyfunction]
in guide/function.md
, but it's sorely lacking. There's also some docs in pyo3-macros/lib.rs
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'll tackle this (also for the other attributes) in a follow-up? This attribute is certainly the least-needed one :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep I think that's fine!
guide/src/faq.md
Outdated
|
||
However, when the dependency is renamed, or your crate only indirectly depends | ||
on `pyo3`, you need to let the macro code know where to find the crate. This is | ||
done with the `pyo3_path` attribute: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you feel about it being #[pyo3(crate = "...")]
rather than pyo3_path
, so that we follow exactly the convention set by serde?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That was my first try, but unfortunately incompatible with the way we parse keywords (you can't pass crate
to syn::custom_keyword
, and r#crate
is invalid for some reason).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe it's Token![crate]
. FWIW, I personally prefer the crate = "…"
syntax as well 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect! (Also thanks a lot for your other PR, I've transplanted it onto this branch to see if the tests pass.)
So, rebased against main and moved the test into lib, as suggested. However, now I get a curious error which I can't make sense of:
Any ideas? Does the |
This removes the crate-root `pyo3` item to ensure that our selected pyo3_path needs to be taken into account.
Coverage failure is rust-lang/rust#91689 - I guess we'll just have to live with it broken for a day or two. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks great to me! I think it's a nice piece of flexibility this adds for users.
Just one thought about variable names, otherwise please merge!
@@ -43,6 +43,19 @@ impl Parse for NameAttribute { | |||
} | |||
} | |||
|
|||
/// For specifying the path to the pyo3 crate. | |||
#[derive(Clone, Debug, PartialEq)] | |||
pub struct PyO3PathAttribute(pub Path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have crate =
I'd be nice to call this PyO3CrateAttribute
or CrateAttribute
, similarly some variables called pyo3_path
might want to be called pyo3_crate
(or krate
?! - then expanding it inside proc-macros as #krate
is no longer than macro_rules $crate
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, done!
Perfect! Thanks @birkenfeld and @danielhenrymantilla! |
Unfinished: see
// TODO
comments. Need to be able to pass#[pyo3(pyo3_path)]
attributes to the FromPyObject derive macro, pyclass-enums, and pymethods.Implementation note: Since I didn't want to add
pyo3_path
args to dozens of functions, I used scopes whenever possible within which I can douse #pyo3_path as _pyo3;
and generate_pyo3::
references everywhere else. This meant adding someconst ()
for impl blocks.#pyproto
is a bit harder to support since it modifies function arguments of the existingimpl
and I didn't want to move that impl into a const block. We can just deprecate pyproto anyway and document that this feature doesn't work with it.