Conversation
2f8f123 to
031f033
Compare
Co-authored-by: David Hewitt <mail@davidhewitt.dev>
031f033 to
9db0ea9
Compare
Icxolu
left a comment
There was a problem hiding this comment.
Nice to see this getting closer to landing. After this I think we can really start to update documentation and examples! 🚀
I have added some thoughts, but you should definitely wait for a second opinion.
| @@ -126,13 +126,42 @@ macro_rules! py_run_impl { | |||
| macro_rules! wrap_pyfunction { | |||
There was a problem hiding this comment.
This one should now get a deprecation warning I thing
There was a problem hiding this comment.
Good spot! I think maybe this makes sense to do in a separate PR since it'll cause a lot of churn in tests.
Co-authored-by: Matthew Neeley <mneeley@gmail.com>
This allows us to remove the awkward `PyFunctionArgumentsBound` enum.
|
I pushed a final commit which removes the I couldn't find a good way to describe what I was thinking until I'd tried it out, at which point I had the commit ready to go 🙈 Do let me know what you think of that last commit, if it seems good, maybe this is ready to merge?! |
|
Ok so I had a slightly nutty magical idea to use some trickery to automatically infer the output type of If the input argument is The nice thing about this is that then for the vast majority of user code they don't need to change anything in their I pushed that as a final commit. What do you think? |
CodSpeed Performance ReportMerging #3897 will improve performances by 11.35%Comparing Summary
Benchmarks breakdown
|
| use #krate::prelude::PyModuleMethods; | ||
| use ::std::convert::Into; | ||
| module.add_function(&#krate::types::PyCFunction::internal_new(&DEF, module.as_gil_ref().into())?) | ||
| module.add_function(#krate::types::PyCFunction::internal_new(&DEF, module.as_gil_ref().into())?) |
There was a problem hiding this comment.
It's a bit sad to still need this as_gil_ref() call for now.
maffoo
left a comment
There was a problem hiding this comment.
LGTM. I think it'd be good to move forward with this and we can revisit the macro import hygiene in a follow-up.
|
|
||
| let mut stmts: Vec<syn::Stmt> = vec![syn::parse_quote!( | ||
| #[allow(unknown_lints, unused_imports, redundant_imports)] | ||
| use #krate::{PyNativeType, types::PyModuleMethods}; |
There was a problem hiding this comment.
I'm hesitant to add this kind of use statement, which transparently injects things into the namespace of user code and so would seem to violate hygiene (see discussion in the follow-up PR here: #3899 (comment)). An alternative would be to use fully-qualified references to trait methods in the macro-generated code. But as @Icxolu noted in that discussion, the patterns around these new *Methods traits are not very well established, so I could be persuaded :-)
There was a problem hiding this comment.
Yeah, after that discussion I tend to agree, that we should not inject these traits silently. If we still want to do it we should probably at least import them anonymously e.g. as use "Trait" as _. I would not consider it a blocker here, we can change in a followup if needed. Another thing would be if we should seal these traits, but that's another discussion entirely.
There was a problem hiding this comment.
Agreed. Maybe a good solution here it to write a private trait in impl_/pymodule.rs which has just the methods we need implemented for both Bound<'_, PyModule> and &'py PyModule, which we can then call directly without imports.
(This is actually probably very similar to what @LilyFoote had already done with the #[doc(hidden)] fn wrap_pyfunction, just located as a private trait inside the impl codebase.)
Icxolu
left a comment
There was a problem hiding this comment.
Nice solution, this look pretty elegant. I have found a minor point regarding PyFunction::internal_new_bound plus two general comments, otherwise LGTM!
| } | ||
|
|
||
| #[doc(hidden)] | ||
| pub(crate) fn internal_new_bound<'py>( |
There was a problem hiding this comment.
I think we don't need this. We can change the signature of internal_new to match the new _bound APIs and move let (py, module) = py_or_module.into_py_and_maybe_module(); into the deprecated gil-ref APIs
| /// [1]: crate::prelude::pyfunction | ||
| /// [2]: crate::wrap_pyfunction | ||
| fn add_function(&self, fun: &Bound<'_, PyCFunction>) -> PyResult<()>; | ||
| fn add_function(&self, fun: Bound<'_, PyCFunction>) -> PyResult<()>; |
There was a problem hiding this comment.
I guess this is just to make it nicer, so that we don't have to use&wrap_pyfunction! instead of just wrap_pyfunction!?
There was a problem hiding this comment.
Yeah I think it's probably worth making this change? It's not like we expect this to be called in a hot loop. I guess we could also have impl AsRef<Bound<'_, PyCFunction>>?
| pub trait WrapPyFunctionArg<'py, T> { | ||
| fn wrap_pyfunction(self, method_def: &PyMethodDef) -> PyResult<T>; | ||
| } |
There was a problem hiding this comment.
Very interesting solution! I guess T could also be an associated type given that it's not intended to be implemented more than once per type. But since this is internal API, I'm fine either way.
There was a problem hiding this comment.
Yes actually I was thinking that later on today, I had generic originally because I wanted to play with type inference but given that each type now implements only once we could go for the associated type.
|
|
||
| let mut stmts: Vec<syn::Stmt> = vec![syn::parse_quote!( | ||
| #[allow(unknown_lints, unused_imports, redundant_imports)] | ||
| use #krate::{PyNativeType, types::PyModuleMethods}; |
There was a problem hiding this comment.
Yeah, after that discussion I tend to agree, that we should not inject these traits silently. If we still want to do it we should probably at least import them anonymously e.g. as use "Trait" as _. I would not consider it a blocker here, we can change in a followup if needed. Another thing would be if we should seal these traits, but that's another discussion entirely.
|
Thanks all! I think given this PR seems to be blocking a lot of the final refinements to the codebase which we need for 0.21, and we're happy enough with this as-is, I think let's merge this as-is. There are quite a few follow-up items. Anyone got time / interest in taking them on? Otherwise I can try to do these maybe at the weekend. (I also just made some comments on other issues specifically about the trait sealing...) |
Builds upon #3744.