-
Notifications
You must be signed in to change notification settings - Fork 903
refactor #[setter] argument extraction
#4002
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -73,7 +73,7 @@ pub fn is_forwarded_args(signature: &FunctionSignature<'_>) -> bool { | |
| ) | ||
| } | ||
|
|
||
| fn check_arg_for_gil_refs( | ||
| pub(crate) fn check_arg_for_gil_refs( | ||
| tokens: TokenStream, | ||
| gil_refs_checker: syn::Ident, | ||
| ctx: &Ctx, | ||
|
|
@@ -120,7 +120,11 @@ pub fn impl_arg_params( | |
| .iter() | ||
| .enumerate() | ||
| .map(|(i, arg)| { | ||
| impl_arg_param(arg, i, &mut 0, &args_array, holders, ctx).map(|tokens| { | ||
| let from_py_with = | ||
| syn::Ident::new(&format!("from_py_with_{}", i), Span::call_site()); | ||
| let arg_value = quote!(#args_array[0].as_deref()); | ||
|
|
||
| impl_arg_param(arg, from_py_with, arg_value, holders, ctx).map(|tokens| { | ||
| check_arg_for_gil_refs( | ||
| tokens, | ||
| holders.push_gil_refs_checker(arg.ty.span()), | ||
|
|
@@ -161,14 +165,20 @@ pub fn impl_arg_params( | |
|
|
||
| let num_params = positional_parameter_names.len() + keyword_only_parameters.len(); | ||
|
|
||
| let mut option_pos = 0; | ||
| let mut option_pos = 0usize; | ||
| let param_conversion = spec | ||
| .signature | ||
| .arguments | ||
| .iter() | ||
| .enumerate() | ||
| .map(|(i, arg)| { | ||
| impl_arg_param(arg, i, &mut option_pos, &args_array, holders, ctx).map(|tokens| { | ||
| let from_py_with = syn::Ident::new(&format!("from_py_with_{}", i), Span::call_site()); | ||
| let arg_value = quote!(#args_array[#option_pos].as_deref()); | ||
| if arg.is_regular() { | ||
| option_pos += 1; | ||
| } | ||
|
Comment on lines
+177
to
+179
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a little unfortunate to have the coupling between incrementing the option and Maybe it's better for me to try to implement what I mean than add a drive by comment for that, though?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Feel free to continue/add something here if you have something in mind. I wasn't really satisfied by how this turned out either (which is why I left it as draft for now)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure thing, I'll try to find a good moment to do this soon
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have played around a bit with your enum idea over here. Maybe that goes into the direction that you hand in mind? That does definetly decouple the different branches from each other, but it's a bit more involved and not really relevant to the
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That definitely looks like the idea I had in mind. Does it feel like a step in the right direction as you're working on it?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It does feel nicer in my opinion. Having an enum over a bunch of booleans not only makes it much clearer what the branches are, but also make a lot of weird combinations (like optional py/varargs, required kwargs, ...) unrepresentable, which is always good. This also moves the error checking of those cases to construction/parsing side instead of usage side, which for me feels a more appropriate place for them. In some places the matching is bit more verbose, but maybe there could be some helper methods for those (or maybe its even fine like it is)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great! In which case let's merge this one now so that it's possible to start reviewing the follow up :) |
||
|
|
||
| impl_arg_param(arg, from_py_with, arg_value, holders, ctx).map(|tokens| { | ||
| check_arg_for_gil_refs(tokens, holders.push_gil_refs_checker(arg.ty.span()), ctx) | ||
| }) | ||
| }) | ||
|
|
@@ -234,11 +244,10 @@ pub fn impl_arg_params( | |
|
|
||
| /// Re option_pos: The option slice doesn't contain the py: Python argument, so the argument | ||
| /// index and the index in option diverge when using py: Python | ||
| fn impl_arg_param( | ||
| pub(crate) fn impl_arg_param( | ||
| arg: &FnArg<'_>, | ||
| pos: usize, | ||
| option_pos: &mut usize, | ||
| args_array: &syn::Ident, | ||
| from_py_with: syn::Ident, | ||
| arg_value: TokenStream, // expected type: Option<&'a Bound<'py, PyAny>> | ||
| holders: &mut Holders, | ||
| ctx: &Ctx, | ||
| ) -> Result<TokenStream> { | ||
|
|
@@ -291,9 +300,6 @@ fn impl_arg_param( | |
| }); | ||
| } | ||
|
|
||
| let arg_value = quote_arg_span!(#args_array[#option_pos]); | ||
| *option_pos += 1; | ||
|
|
||
| let mut default = arg.default.as_ref().map(|expr| quote!(#expr)); | ||
|
|
||
| // Option<T> arguments have special treatment: the default should be specified _without_ the | ||
|
|
@@ -312,11 +318,10 @@ fn impl_arg_param( | |
| .map(|attr| &attr.value) | ||
| .is_some() | ||
| { | ||
| let from_py_with = syn::Ident::new(&format!("from_py_with_{}", pos), Span::call_site()); | ||
| if let Some(default) = default { | ||
| quote_arg_span! { | ||
| #pyo3_path::impl_::extract_argument::from_py_with_with_default( | ||
| #arg_value.as_deref(), | ||
| #arg_value, | ||
| #name_str, | ||
| #from_py_with as fn(_) -> _, | ||
| #[allow(clippy::redundant_closure)] | ||
|
|
@@ -328,7 +333,7 @@ fn impl_arg_param( | |
| } else { | ||
| quote_arg_span! { | ||
| #pyo3_path::impl_::extract_argument::from_py_with( | ||
| &#pyo3_path::impl_::extract_argument::unwrap_required_argument(#arg_value), | ||
| #pyo3_path::impl_::extract_argument::unwrap_required_argument(#arg_value), | ||
| #name_str, | ||
| #from_py_with as fn(_) -> _, | ||
| )? | ||
|
|
@@ -338,7 +343,7 @@ fn impl_arg_param( | |
| let holder = holders.push_holder(arg.name.span()); | ||
| quote_arg_span! { | ||
| #pyo3_path::impl_::extract_argument::extract_optional_argument( | ||
| #arg_value.as_deref(), | ||
| #arg_value, | ||
| &mut #holder, | ||
| #name_str, | ||
| #[allow(clippy::redundant_closure)] | ||
|
|
@@ -351,7 +356,7 @@ fn impl_arg_param( | |
| let holder = holders.push_holder(arg.name.span()); | ||
| quote_arg_span! { | ||
| #pyo3_path::impl_::extract_argument::extract_argument_with_default( | ||
| #arg_value.as_deref(), | ||
| #arg_value, | ||
| &mut #holder, | ||
| #name_str, | ||
| #[allow(clippy::redundant_closure)] | ||
|
|
@@ -364,7 +369,7 @@ fn impl_arg_param( | |
| let holder = holders.push_holder(arg.name.span()); | ||
| quote_arg_span! { | ||
| #pyo3_path::impl_::extract_argument::extract_argument( | ||
| &#pyo3_path::impl_::extract_argument::unwrap_required_argument(#arg_value), | ||
| #pyo3_path::impl_::extract_argument::unwrap_required_argument(#arg_value), | ||
| &mut #holder, | ||
| #name_str | ||
| )? | ||
|
|
||
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.
Seeing this I'm thinking
FnArgmight want to be reworked to be anenum. Not sure if it's worth trying to make that part of this PR or we punt for another time.