fn impl_arg_param(
    arg: &FnArg<'_>,
    spec: &FnSpec<'_>,
    idx: usize,
    self_: Option<&syn::Type>,
    option_pos: &mut usize,
    py: &syn::Ident,
    args_array: &syn::Ident,
) -> Result<TokenStream> {
    // Use this macro inside this function, to ensure that all code generated here is associated
    // with the function argument
    macro_rules! quote_arg_span {
        ($($tokens:tt)*) => { quote_spanned!(arg.ty.span() => $($tokens)*) }
    }

    let arg_name = syn::Ident::new(&format!("arg{}", idx), Span::call_site());

    if arg.py {
        return Ok(quote_arg_span! { let #arg_name = #py; });
    }

    let ty = arg.ty;
    let name = arg.name;
    let name_str = name.to_string();

    if is_args(&spec.attrs, name) {
        ensure_spanned!(
            arg.optional.is_none(),
            arg.name.span() => "args cannot be optional"
        );
        return Ok(quote_arg_span! {
            let #arg_name = _pyo3::impl_::extract_argument::extract_argument(_args, #name_str)?;
        });
    } else if is_kwargs(&spec.attrs, name) {
        ensure_spanned!(
            arg.optional.is_some(),
            arg.name.span() => "kwargs must be Option<_>"
        );
        return Ok(quote_arg_span! {
            let #arg_name = _pyo3::impl_::extract_argument::extract_optional_argument(_kwargs.map(|kwargs| kwargs.as_ref()), #name_str)?;
        });
    }

    let arg_value = quote_arg_span!(#args_array[#option_pos]);
    *option_pos += 1;

    let arg_value_or_default = if let Some(FromPyWithAttribute(expr_path)) = &arg.attrs.from_py_with
    {
        match (spec.default_value(name), arg.optional.is_some()) {
            (Some(default), true) if default.to_string() != "None" => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with_with_default(#arg_value, #name_str, #expr_path, || Some(#default))
                }
            }
            (Some(default), _) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with_with_default(#arg_value, #name_str, #expr_path, || #default)
                }
            }
            (None, true) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with_with_default(#arg_value, #name_str, #expr_path, || Some(None))
                }
            }
            (None, false) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with(
                        _pyo3::impl_::extract_argument::unwrap_required_argument(#arg_value),
                        #name_str,
                        #expr_path,
                    )
                }
            }
        }
    } else {
        match (spec.default_value(name), arg.optional.is_some()) {
            (Some(default), true) if default.to_string() != "None" => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_argument_with_default(#arg_value, #name_str, || Some(#default))
                }
            }
            (Some(default), _) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_argument_with_default(#arg_value, #name_str, || #default)
                }
            }
            (None, true) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_optional_argument(#arg_value, #name_str)
                }
            }
            (None, false) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_argument(
                        _pyo3::impl_::extract_argument::unwrap_required_argument(#arg_value),
                        #name_str
                    )
                }
            }
        }
    };

    return if let syn::Type::Reference(tref) = unwrap_ty_group(arg.optional.unwrap_or(ty)) {
        let mut tref = remove_lifetime(tref);
        if let Some(cls) = self_ {
            replace_self(&mut tref.elem, cls);
        }
        let mut_ = tref.mutability;
        let (target_ty, borrow_tmp) = if arg.optional.is_some() {
            // Get Option<&T> from Option<PyRef<T>>
            (
                quote_arg_span! { ::std::option::Option<<#tref as _pyo3::derive_utils::ExtractExt<'_>>::Target> },
                if mut_.is_some() {
                    quote_arg_span! { _tmp.as_deref_mut() }
                } else {
                    quote_arg_span! { _tmp.as_deref() }
                },
            )
        } else {
            // Get &T from PyRef<T>
            (
                quote_arg_span! { <#tref as _pyo3::derive_utils::ExtractExt<'_>>::Target },
                quote_arg_span! { &#mut_ *_tmp },
            )
        };

        Ok(quote_arg_span! {
            let #mut_ _tmp: #target_ty = #arg_value_or_default?;
            #[allow(clippy::needless_option_as_deref)]
            let #arg_name = #borrow_tmp;
        })
    } else {
        Ok(quote_arg_span! {
            let #arg_name = #arg_value_or_default?;
        })
    };
}
/// 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
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
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(
    arg: &FnArg<'_>,
    spec: &FnSpec<'_>,
    idx: usize,
    self_: Option<&syn::Type>,
    option_pos: &mut usize,
    py: &syn::Ident,
    args_array: &syn::Ident,
) -> Result<TokenStream> {
    // Use this macro inside this function, to ensure that all code generated here is associated
    // with the function argument
    macro_rules! quote_arg_span {
        ($($tokens:tt)*) => { quote_spanned!(arg.ty.span() => $($tokens)*) }
    }
    let arg_name = syn::Ident::new(&format!("arg{}", idx), Span::call_site());
    if arg.py {
        return Ok(quote_arg_span! { let #arg_name = #py; });
    }
    let ty = arg.ty;
    let name = arg.name;
    let name_str = name.to_string();
    if is_args(&spec.attrs, name) {
        ensure_spanned!(
            arg.optional.is_none(),
            arg.name.span() => "args cannot be optional"
        );
        return Ok(quote_arg_span! {
            let #arg_name = _pyo3::impl_::extract_argument::extract_argument(_args, #name_str)?;
        });
    } else if is_kwargs(&spec.attrs, name) {
        ensure_spanned!(
            arg.optional.is_some(),
            arg.name.span() => "kwargs must be Option<_>"
        );
        return Ok(quote_arg_span! {
            let #arg_name = _pyo3::impl_::extract_argument::extract_optional_argument(_kwargs.map(|kwargs| kwargs.as_ref()), #name_str)?;
        });
    }
    let arg_value = quote_arg_span!(#args_array[#option_pos]);
    *option_pos += 1;
    let arg_value_or_default = if let Some(FromPyWithAttribute(expr_path)) = &arg.attrs.from_py_with
    {
        match (spec.default_value(name), arg.optional.is_some()) {
            (Some(default), true) if default.to_string() != "None" => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with_with_default(#arg_value, #name_str, #expr_path, || Some(#default))
                }
            }
            (Some(default), _) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with_with_default(#arg_value, #name_str, #expr_path, || #default)
                }
            }
            (None, true) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with_with_default(#arg_value, #name_str, #expr_path, || Some(None))
                }
            }
            (None, false) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::from_py_with(
                        _pyo3::impl_::extract_argument::unwrap_required_argument(#arg_value),
                        #name_str,
                        #expr_path,
                    )
                }
            }
        }
    } else {
        match (spec.default_value(name), arg.optional.is_some()) {
            (Some(default), true) if default.to_string() != "None" => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_argument_with_default(#arg_value, #name_str, || Some(#default))
                }
            }
            (Some(default), _) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_argument_with_default(#arg_value, #name_str, || #default)
                }
            }
            (None, true) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_optional_argument(#arg_value, #name_str)
                }
            }
            (None, false) => {
                quote_arg_span! {
                    _pyo3::impl_::extract_argument::extract_argument(
                        _pyo3::impl_::extract_argument::unwrap_required_argument(#arg_value),
                        #name_str
                    )
                }
            }
        }
    };
    return if let syn::Type::Reference(tref) = unwrap_ty_group(arg.optional.unwrap_or(ty)) {
        let mut tref = remove_lifetime(tref);
        if let Some(cls) = self_ {
            replace_self(&mut tref.elem, cls);
        }
        let mut_ = tref.mutability;
        let (target_ty, borrow_tmp) = if arg.optional.is_some() {
            // Get Option<&T> from Option<PyRef<T>>
            (
                quote_arg_span! { ::std::option::Option<<#tref as _pyo3::derive_utils::ExtractExt<'_>>::Target> },
                if mut_.is_some() {
                    quote_arg_span! { _tmp.as_deref_mut() }
                } else {
                    quote_arg_span! { _tmp.as_deref() }
                },
            )
        } else {
            // Get &T from PyRef<T>
            (
                quote_arg_span! { <#tref as _pyo3::derive_utils::ExtractExt<'_>>::Target },
                quote_arg_span! { &#mut_ *_tmp },
            )
        };
        Ok(quote_arg_span! {
            let #mut_ _tmp: #target_ty = #arg_value_or_default?;
            #[allow(clippy::needless_option_as_deref)]
            let #arg_name = #borrow_tmp;
        })
    } else {
        Ok(quote_arg_span! {
            let #arg_name = #arg_value_or_default?;
        })
    };
}
fn impl_arg_param ( arg : & FnArg < ' _ > , spec : & FnSpec < ' _ > , idx : usize , self_ : Option < & syn :: Type > , option_pos : & mut usize , py : & syn :: Ident , args_array : & syn :: Ident , ) -> Result < TokenStream > { // Use this macro inside this function, to ensure that all code generated here is associated // with the function argument macro_rules! quote_arg_span { ( $ ( $tokens : tt ) * ) => { quote_spanned ( arg ty span ( ) $ ( $tokens ) * ) } } let arg_name = syn :: Ident :: new ( & format ! ( " " idx ) , Span :: call_site ( ) ) ; if arg . py { return Ok ( quote_arg_span ! { let arg_name py } ) ; } let ty = arg . ty ; let name = arg . name ; let name_str = name . to_string ( ) ; if is_args ( & spec . attrs , name ) { ensure_spanned ! ( arg optional is_none ( ) arg name span ( ) " " ) ; return Ok ( quote_arg_span ! { let arg_name _pyo3 impl_ extract_argument extract_argument ( _args name_str ) } ) ; } else if is_kwargs ( & spec . attrs , name ) { ensure_spanned ! ( arg optional is_some ( ) arg name span ( ) " " ) ; return Ok ( quote_arg_span ! { let arg_name _pyo3 impl_ extract_argument extract_optional_argument ( _kwargs map ( kwargs kwargs as_ref ( ) ) name_str ) } ) ; } let arg_value = quote_arg_span ! ( args_array [ option_pos ] ) ; * option_pos += 1 ; let arg_value_or_default = if let Some ( FromPyWithAttribute ( expr_path ) ) = & arg . attrs . from_py_with { match ( spec . default_value ( name ) , arg . optional . is_some ( ) ) { ( Some ( default ) , true ) if default . to_string ( ) != " " => { quote_arg_span ! { _pyo3 impl_ extract_argument from_py_with_with_default ( arg_value name_str expr_path Some ( default ) ) } } ( Some ( default ) , _ ) => { quote_arg_span ! { _pyo3 impl_ extract_argument from_py_with_with_default ( arg_value name_str expr_path default ) } } ( None , true ) => { quote_arg_span ! { _pyo3 impl_ extract_argument from_py_with_with_default ( arg_value name_str expr_path Some ( None ) ) } } ( None , false ) => { quote_arg_span ! { _pyo3 impl_ extract_argument from_py_with ( _pyo3 impl_ extract_argument unwrap_required_argument ( arg_value ) name_str expr_path ) } } } } else { match ( spec . default_value ( name ) , arg . optional . is_some ( ) ) { ( Some ( default ) , true ) if default . to_string ( ) != " " => { quote_arg_span ! { _pyo3 impl_ extract_argument extract_argument_with_default ( arg_value name_str Some ( default ) ) } } ( Some ( default ) , _ ) => { quote_arg_span ! { _pyo3 impl_ extract_argument extract_argument_with_default ( arg_value name_str default ) } } ( None , true ) => { quote_arg_span ! { _pyo3 impl_ extract_argument extract_optional_argument ( arg_value name_str ) } } ( None , false ) => { quote_arg_span ! { _pyo3 impl_ extract_argument extract_argument ( _pyo3 impl_ extract_argument unwrap_required_argument ( arg_value ) name_str ) } } } } ; return if let syn :: Type :: Reference ( tref ) = unwrap_ty_group ( arg . optional . unwrap_or ( ty ) ) { let mut tref = remove_lifetime ( tref ) ; if let Some ( cls ) = self_ { replace_self ( & mut tref . elem , cls ) ; } let mut_ = tref . mutability ; let ( target_ty , borrow_tmp ) = if arg . optional . is_some ( ) { // Get Option<&T> from Option<PyRef<T>> ( quote_arg_span ! { std option Option tref as _pyo3 derive_utils ExtractExt ' Target } , if mut_ . is_some ( ) { quote_arg_span ! { _tmp as_deref_mut ( ) } } else { quote_arg_span ! { _tmp as_deref ( ) } } , ) } else { // Get &T from PyRef<T> ( quote_arg_span ! { tref as _pyo3 derive_utils ExtractExt ' Target } , quote_arg_span ! { mut_ tmp } , ) } ; Ok ( quote_arg_span ! { let mut_ _tmp target_ty arg_value_or_default [ allow ( clippy needless_option_as_deref ) ] let arg_name borrow_tmp } ) } else { Ok ( quote_arg_span ! { let arg_name arg_value_or_default } ) } ; }
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
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
arg
&FnArg<'_>
spec
&FnSpec<'_>
idx
usize
self_
Option<&syn::Type>
option_pos
&mut usize
py
&syn::Ident
args_array
&syn::Ident
arg
&FnArg<'_>
spec
&FnSpec<'_>
idx
usize
self_
Option<&syn::Type>
option_pos
&mut usize
py
&syn::Ident
args_array
&syn::Ident