From 4221b1b351cb4edddf76bb701a36361cbab6104f Mon Sep 17 00:00:00 2001 From: NiklasVousten <24965952+NiklasVousten@users.noreply.github.com> Date: Sun, 15 Sep 2024 21:14:23 +0200 Subject: [PATCH 1/3] Added optional parameter for py-parameters with defautls --- pyo3_bindgen_engine/src/syntax/function.rs | 39 +++++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/pyo3_bindgen_engine/src/syntax/function.rs b/pyo3_bindgen_engine/src/syntax/function.rs index bf046c3..854e141 100644 --- a/pyo3_bindgen_engine/src/syntax/function.rs +++ b/pyo3_bindgen_engine/src/syntax/function.rs @@ -376,15 +376,35 @@ impl Function { .iter() .zip(param_idents.iter()) .map(|(param, param_ident)| { - param + let bind = param .annotation - .preprocess_borrowed(param_ident, local_types) + .preprocess_borrowed(param_ident, local_types); + + if param.default.is_some() { + let option_ident = quote::format_ident!("optional_{}", param_ident); + quote::quote! { + let #option_ident = #param_ident.is_some(); + #bind + } + } else { + bind + } }) .collect(); let param_types: Vec = self .parameters .iter() - .map(|param| Result::Ok(param.annotation.clone().into_rs_borrowed(local_types))) + .map(|param| { + let local_type = param.annotation.clone().into_rs_borrowed(local_types); + let res = if param.default.is_some() { + quote::quote! { + Option<#local_type> + } + } else { + local_type + }; + Result::Ok(res)} + ) .collect::>>()?; let return_type = self.return_annotation.clone().into_rs_owned(local_types); let fn_contract = match &self.typ { @@ -568,6 +588,10 @@ impl Function { .iter() .map(|param| Ok(Ident::from_py(&format!("p_{}", param.name)).try_into()?)) .collect::>()?; + let keyword_args_idents_optional: Vec = keyword_args_idents + .iter() + .map(|param| quote::format_ident!("optional_{}", param)) + .collect::<_>(); let var_keyword_args_ident: Option = self .parameters .iter() @@ -580,11 +604,14 @@ impl Function { #var_keyword_args_ident } } else { + //let option_ident: syn::Ident = Ident::from_py(&format!("optional_{}", param.name)).try_into().unwrap(); quote::quote! { { let __internal__kwargs = #var_keyword_args_ident; #( - ::pyo3::types::PyDictMethods::set_item(&__internal__kwargs, ::pyo3::intern!(py, #keyword_args_names), #keyword_args_idents); + if format_ident!("optional{}", keyword_args_idents) { + ::pyo3::types::PyDictMethods::set_item(&__internal__kwargs, ::pyo3::intern!(py, #keyword_args_names), #keyword_args_idents); + }; )* __internal__kwargs } @@ -599,7 +626,9 @@ impl Function { { let __internal__kwargs = ::pyo3::types::PyDict::new_bound(py); #( - ::pyo3::types::PyDictMethods::set_item(&__internal__kwargs, ::pyo3::intern!(py, #keyword_args_names), #keyword_args_idents); + if #keyword_args_idents_optional { + ::pyo3::types::PyDictMethods::set_item(&__internal__kwargs, ::pyo3::intern!(py, #keyword_args_names), #keyword_args_idents); + }; )* __internal__kwargs } From cf9b8defe0ca36b8bfeb511e6e0307e3a336effb Mon Sep 17 00:00:00 2001 From: NiklasVousten <24965952+NiklasVousten@users.noreply.github.com> Date: Mon, 16 Sep 2024 08:34:24 +0200 Subject: [PATCH 2/3] Fixed small issues Fixed breaking test Optional Type excluded from option Cargo fmt Cargo clippy --- pyo3_bindgen_engine/src/syntax/function.rs | 25 +++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/pyo3_bindgen_engine/src/syntax/function.rs b/pyo3_bindgen_engine/src/syntax/function.rs index 854e141..73cec6c 100644 --- a/pyo3_bindgen_engine/src/syntax/function.rs +++ b/pyo3_bindgen_engine/src/syntax/function.rs @@ -379,8 +379,7 @@ impl Function { let bind = param .annotation .preprocess_borrowed(param_ident, local_types); - - if param.default.is_some() { + if param.default.is_some() && !matches!(param.annotation, Type::Optional(_)) { let option_ident = quote::format_ident!("optional_{}", param_ident); quote::quote! { let #option_ident = #param_ident.is_some(); @@ -396,15 +395,16 @@ impl Function { .iter() .map(|param| { let local_type = param.annotation.clone().into_rs_borrowed(local_types); - let res = if param.default.is_some() { - quote::quote! { - Option<#local_type> - } - } else { - local_type - }; - Result::Ok(res)} - ) + let res = + if param.default.is_some() && !matches!(param.annotation, Type::Optional(_)) { + quote::quote! { + Option<#local_type> + } + } else { + local_type + }; + Result::Ok(res) + }) .collect::>>()?; let return_type = self.return_annotation.clone().into_rs_owned(local_types); let fn_contract = match &self.typ { @@ -604,12 +604,13 @@ impl Function { #var_keyword_args_ident } } else { + //TODO:: //let option_ident: syn::Ident = Ident::from_py(&format!("optional_{}", param.name)).try_into().unwrap(); quote::quote! { { let __internal__kwargs = #var_keyword_args_ident; #( - if format_ident!("optional{}", keyword_args_idents) { + if #keyword_args_idents_optional { ::pyo3::types::PyDictMethods::set_item(&__internal__kwargs, ::pyo3::intern!(py, #keyword_args_names), #keyword_args_idents); }; )* From 2027605931a6397fffb1a07ccd71f8ff5c15c5e2 Mon Sep 17 00:00:00 2001 From: NiklasVousten <24965952+NiklasVousten@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:19:56 +0200 Subject: [PATCH 3/3] Fixed os_sys example --- examples/os_sys.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/os_sys.rs b/examples/os_sys.rs index 1242c7b..362be0a 100644 --- a/examples/os_sys.rs +++ b/examples/os_sys.rs @@ -26,7 +26,7 @@ fn main() -> pyo3::PyResult<()> { // Get the current working directory via "os" Python module let current_dir = os::getcwd(py)?; // Get the relative path to the Python executable via "posixpath" Python module - let relpath_to_python_exe = posixpath::relpath(py, python_exe_path, current_dir)?; + let relpath_to_python_exe = posixpath::relpath(py, python_exe_path, Some(current_dir))?; println!("Relative path to Python executable: '{relpath_to_python_exe}'"); Ok(())