-
Notifications
You must be signed in to change notification settings - Fork 766
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
deprecate gil-refs in from_py_with
#3967
Conversation
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.
Ah, brilliant! I hadn't even gotten around to thinking about this one yet. I have a few thoughts...
Regarding the #[derive(FromPyObject)]
case, I suppose it'd be possible to spit out some code in an anonymous constant outside of the #[automatically_derived]
?
Something like
const _: () = {
let (_, e) = inspect_fn(function_to_inspect);
e.extract_from_py_with();
}
If those can be const fn
, that's probably sufficient to trigger the warnings? Probably worth deferring that to a separate PR as threading that code through to the top level might be painful.
src/impl_/pymethods.rs
Outdated
not(feature = "gil-refs"), | ||
deprecated( | ||
since = "0.21.0", | ||
note = "use `&Bound<'_, PyAny>` as argument for this `from_py_with` extractor" |
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.
note = "use `&Bound<'_, PyAny>` as argument for this `from_py_with` extractor" | |
note = "use `&Bound<'_, PyAny>` as the argument for this `from_py_with` extractor" |
src/impl_/pymethods.rs
Outdated
#[allow(clippy::type_complexity)] | ||
pub fn inspect_fn<A, T>(f: fn(A) -> PyResult<T>) -> (fn(A) -> PyResult<T>, Extractor<A>) { | ||
(f, Extractor::new()) | ||
} |
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.
Smart! In #3847 (which I'm slowing making progress on) I recently found that it's also possible to take the Extractor
as an argument by reference:
#[allow(clippy::type_complexity)] | |
pub fn inspect_fn<A, T>(f: fn(A) -> PyResult<T>) -> (fn(A) -> PyResult<T>, Extractor<A>) { | |
(f, Extractor::new()) | |
} | |
#[allow(clippy::type_complexity)] | |
pub fn inspect_fn<A, T>(f: fn(A) -> PyResult<T>, _: &Extractor<A>) -> fn(A) -> PyResult<T> { | |
f | |
} |
The nice thing about this is that the dance in the macro code gets simpler. Instead of:
let extractor;
let (thing, e) = inspect_fn(thing);
extractor = e;
can just write:
let extractor = Extractor::new();
let thing = inspect_fn(thing, &e);
So far this seems to be working for me for type inference just as well as the original form and seems to be easier to fit into macro code paths, I wonder if it will also simplify the return type and make clippy happier.
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.
Interesting! That does look nicer and easier to work with. In this particular case it does not make too much of a difference, because I did not need that empty binding, but it does not hurt either (and it makes clippy indeed happier)
Deref coercion is not allowed in consts 😢 |
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.
Looks good to me, thanks! Let's merge to resolve possible conflicts with #3968
Ah 😢. I wonder if there's some dirty hack like packaging into a non-const function, given this code doesn't need to run:
... from a quick test in the playground, this sort of structure can still trigger deprecation warnings: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=fac5238c3e4fdd1ce0da0b2209a64b6c (and because each anonymous constant block is its own scope, all these functions can share a common name, I think they won't conflict.) |
Hmm, it seems like this only works if the constant (anonymous or not) lives in the source itself, if it is generated by the macro it does not trigger. Are these const generated by proc macros handled specially by the compiler 🤔 |
Eurgh, I have no idea 😂 I guess unless we find new tricks, we have to accept that we can't emit a deprecation warning for that case. |
I actually got it to work 🎊 I forgot to set a span for the |
Great! |
This deprecates the use of gil-refs in
from_py_with
. This PR implements it only for#[pyfunction]
arguments. While it would be easily possible to generate the same code for#[derive(FromPyObject)]
the warning gets eaten by#[automatically_derived]
. I don't see a good way around that, but I'm happy to adapt if someone has an idea.