From e65b849ab66b5e7f651536c9e74463e5df51b005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20P=C3=BCtz?= Date: Sat, 5 Sep 2020 10:06:24 +0200 Subject: [PATCH] Doc fixes, changelog and rename. --- CHANGELOG.md | 4 ++++ guide/src/function.md | 16 ++++++---------- pyo3-derive-backend/src/module.rs | 10 +++++----- pyo3-derive-backend/src/pyfunction.rs | 6 +++--- tests/test_module.rs | 12 ++++++------ tests/ui/invalid_need_module_arg_position.rs | 2 +- tests/ui/invalid_need_module_arg_position.stderr | 2 +- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3886d0e..bd649b91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Add optional implementations of `ToPyObject`, `IntoPy`, and `FromPyObject` for [hashbrown](https://crates.io/crates/hashbrown)'s `HashMap` and `HashSet` types. The `hashbrown` feature must be enabled for these implementations to be built. [#1114](https://github.com/PyO3/pyo3/pull/1114/) - Allow other `Result` types when using `#[pyfunction]`. [#1106](https://github.com/PyO3/pyo3/issues/1106). - Add `#[derive(FromPyObject)]` macro for enums and structs. [#1065](https://github.com/PyO3/pyo3/pull/1065) +- Add macro attribute to `#[pyfn]` and `#[pyfunction]` to pass the module of a Python function to the function + body. [#1143](https://github.com/PyO3/pyo3/pull/1143) +- Add `add_function()` and `add_submodule()` functions to `PyModule` [#1143](https://github.com/PyO3/pyo3/pull/1143) ### Changed - Exception types have been renamed from e.g. `RuntimeError` to `PyRuntimeError`, and are now only accessible by `&T` or `Py` similar to other Python-native types. The old names continue to exist but are deprecated. [#1024](https://github.com/PyO3/pyo3/pull/1024) @@ -50,6 +53,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Link against libpython on android with `extension-module` set. [#1095](https://github.com/PyO3/pyo3/pull/1095) - Fix support for both `__add__` and `__radd__` in the `+` operator when both are defined in `PyNumberProtocol` (and similar for all other reversible operators). [#1107](https://github.com/PyO3/pyo3/pull/1107) +- Associate Python functions with their module by passing the Module and Module name [#1143](https://github.com/PyO3/pyo3/pull/1143) ## [0.11.1] - 2020-06-30 ### Added diff --git a/guide/src/function.md b/guide/src/function.md index 99487a1b..82d3669a 100644 --- a/guide/src/function.md +++ b/guide/src/function.md @@ -192,15 +192,14 @@ If you have a static function, you can expose it with `#[pyfunction]` and use [` ### Accessing the module of a function -Functions are usually associated with modules, in the C-API, the self parameter in a function call corresponds -to the module of the function. It is possible to access the module of a `#[pyfunction]` and `#[pyfn]` in the -function body by passing the `need_module` argument to the attribute: +It is possible to access the module of a `#[pyfunction]` and `#[pyfn]` in the +function body by passing the `pass_module` argument to the attribute: ```rust use pyo3::wrap_pyfunction; use pyo3::prelude::*; -#[pyfunction(need_module)] +#[pyfunction(pass_module)] fn pyfunction_with_module( module: &PyModule ) -> PyResult<&str> { @@ -215,8 +214,8 @@ fn module_with_fn(py: Python, m: &PyModule) -> PyResult<()> { # fn main() {} ``` -If `need_module` is set, the first argument **must** be the `&PyModule`. It is then possible to interact with -the module. +If `pass_module` is set, the first argument **must** be the `&PyModule`. It is then possible to use the module +in the function body. The same works for `#[pyfn]`: @@ -227,7 +226,7 @@ use pyo3::prelude::*; #[pymodule] fn module_with_fn(py: Python, m: &PyModule) -> PyResult<()> { - #[pyfn(m, "module_name", need_module)] + #[pyfn(m, "module_name", pass_module)] fn module_name(module: &PyModule) -> PyResult<&str> { module.name() } @@ -236,6 +235,3 @@ fn module_with_fn(py: Python, m: &PyModule) -> PyResult<()> { # fn main() {} ``` - -Within Python, the name of the module that a function belongs to can be accessed through the `__module__` -attribute. \ No newline at end of file diff --git a/pyo3-derive-backend/src/module.rs b/pyo3-derive-backend/src/module.rs index 2493caa6..a706100e 100644 --- a/pyo3-derive-backend/src/module.rs +++ b/pyo3-derive-backend/src/module.rs @@ -158,7 +158,7 @@ pub fn add_fn_to_module( )) } syn::FnArg::Typed(ref cap) => { - if pyfn_attrs.need_module && i == 0 { + if pyfn_attrs.pass_module && i == 0 { if let syn::Type::Reference(tyref) = cap.ty.as_ref() { if let syn::Type::Path(typath) = tyref.elem.as_ref() { if typath @@ -174,7 +174,7 @@ pub fn add_fn_to_module( } return Err(syn::Error::new_spanned( cap, - "Expected &PyModule as first argument with `need_module`.", + "Expected &PyModule as first argument with `pass_module`.", )); } else { arguments.push(wrap_fn_argument(cap)?); @@ -204,7 +204,7 @@ pub fn add_fn_to_module( let python_name = &spec.python_name; - let wrapper = function_c_wrapper(&func.sig.ident, &spec, pyfn_attrs.need_module); + let wrapper = function_c_wrapper(&func.sig.ident, &spec, pyfn_attrs.pass_module); Ok(quote! { fn #function_wrapper_ident<'a>( @@ -247,11 +247,11 @@ pub fn add_fn_to_module( } /// Generate static function wrapper (PyCFunction, PyCFunctionWithKeywords) -fn function_c_wrapper(name: &Ident, spec: &method::FnSpec<'_>, need_module: bool) -> TokenStream { +fn function_c_wrapper(name: &Ident, spec: &method::FnSpec<'_>, pass_module: bool) -> TokenStream { let names: Vec = get_arg_names(&spec); let cb; let slf_module; - if need_module { + if pass_module { cb = quote! { #name(_slf, #(#names),*) }; diff --git a/pyo3-derive-backend/src/pyfunction.rs b/pyo3-derive-backend/src/pyfunction.rs index cde619b7..80ac1cf3 100644 --- a/pyo3-derive-backend/src/pyfunction.rs +++ b/pyo3-derive-backend/src/pyfunction.rs @@ -24,7 +24,7 @@ pub struct PyFunctionAttr { has_kw: bool, has_varargs: bool, has_kwargs: bool, - pub need_module: bool, + pub pass_module: bool, } impl syn::parse::Parse for PyFunctionAttr { @@ -46,8 +46,8 @@ impl PyFunctionAttr { pub fn add_item(&mut self, item: &NestedMeta) -> syn::Result<()> { match item { - NestedMeta::Meta(syn::Meta::Path(ref ident)) if ident.is_ident("need_module") => { - self.need_module = true; + NestedMeta::Meta(syn::Meta::Path(ref ident)) if ident.is_ident("pass_module") => { + self.pass_module = true; } NestedMeta::Meta(syn::Meta::Path(ref ident)) => self.add_work(item, ident)?, NestedMeta::Meta(syn::Meta::NameValue(ref nv)) => { diff --git a/tests/test_module.rs b/tests/test_module.rs index 0b071af9..037c0217 100644 --- a/tests/test_module.rs +++ b/tests/test_module.rs @@ -49,7 +49,7 @@ fn module_with_functions(_py: Python, m: &PyModule) -> PyResult<()> { Ok(42) } - #[pyfn(m, "with_module", need_module)] + #[pyfn(m, "with_module", pass_module)] fn with_module(module: &PyModule) -> PyResult<&str> { module.name() } @@ -312,12 +312,12 @@ fn test_module_with_constant() { }); } -#[pyfunction(need_module)] +#[pyfunction(pass_module)] fn pyfunction_with_module(module: &PyModule) -> PyResult<&str> { module.name() } -#[pyfunction(need_module)] +#[pyfunction(pass_module)] fn pyfunction_with_module_and_py<'a>( module: &'a PyModule, _python: Python<'a>, @@ -325,12 +325,12 @@ fn pyfunction_with_module_and_py<'a>( module.name() } -#[pyfunction(need_module)] +#[pyfunction(pass_module)] fn pyfunction_with_module_and_arg(module: &PyModule, string: String) -> PyResult<(&str, String)> { module.name().map(|s| (s, string)) } -#[pyfunction(need_module, string = "\"foo\"")] +#[pyfunction(pass_module, string = "\"foo\"")] fn pyfunction_with_module_and_default_arg<'a>( module: &'a PyModule, string: &str, @@ -338,7 +338,7 @@ fn pyfunction_with_module_and_default_arg<'a>( module.name().map(|s| (s, string.into())) } -#[pyfunction(need_module, args = "*", kwargs = "**")] +#[pyfunction(pass_module, args = "*", kwargs = "**")] fn pyfunction_with_module_and_args_kwargs<'a>( module: &'a PyModule, args: &PyTuple, diff --git a/tests/ui/invalid_need_module_arg_position.rs b/tests/ui/invalid_need_module_arg_position.rs index 8f697161..607b2127 100644 --- a/tests/ui/invalid_need_module_arg_position.rs +++ b/tests/ui/invalid_need_module_arg_position.rs @@ -2,7 +2,7 @@ use pyo3::prelude::*; #[pymodule] fn module(_py: Python, m: &PyModule) -> PyResult<()> { - #[pyfn(m, "with_module", need_module)] + #[pyfn(m, "with_module", pass_module)] fn fail(string: &str, module: &PyModule) -> PyResult<&str> { module.name() } diff --git a/tests/ui/invalid_need_module_arg_position.stderr b/tests/ui/invalid_need_module_arg_position.stderr index ae0f261f..0fd00964 100644 --- a/tests/ui/invalid_need_module_arg_position.stderr +++ b/tests/ui/invalid_need_module_arg_position.stderr @@ -1,4 +1,4 @@ -error: Expected &PyModule as first argument with `need_module`. +error: Expected &PyModule as first argument with `pass_module`. --> $DIR/invalid_need_module_arg_position.rs:6:13 | 6 | fn fail(string: &str, module: &PyModule) -> PyResult<&str> {