From b10cefdca2f3647daaa0feb5316bd3a151ce9259 Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Sat, 13 Mar 2021 17:36:17 +0000 Subject: [PATCH] pymodule: remove call_function etc. --- CHANGELOG.md | 2 +- guide/src/python_from_rust.md | 17 +++--- src/exceptions.rs | 2 +- src/types/module.rs | 99 ++++++++++++++--------------------- src/types/num.rs | 12 +++-- tests/test_datetime.rs | 4 +- tests/test_module.rs | 2 +- 7 files changed, 61 insertions(+), 77 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f5264d8..fb86dd68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Deprecate FFI definitions `PyModule_GetFilename`. [#1425](https://github.com/PyO3/pyo3/pull/1425) - The `auto-initialize` feature is no longer enabled by default. [#1443](https://github.com/PyO3/pyo3/pull/1443) - Change `PyCFunction::new()` and `PyCFunction::new_with_keywords()` to take `&'static str` arguments rather than implicitly copying (and leaking) them. [#1450](https://github.com/PyO3/pyo3/pull/1450) -- The `call/call0/call1` methods of `PyModule` have been renamed to `call_function` etc. for consistency with `call` and `call_method` on `PyAny`. The old names are still present, but deprecated. [#1467](https://github.com/PyO3/pyo3/pull/1467) +- Deprecate `PyModule` methods `call`, `call0`, `call1` and `get`. [#1492](https://github.com/PyO3/pyo3/pull/1492) ### Removed - Remove deprecated exception names `BaseException` etc. [#1426](https://github.com/PyO3/pyo3/pull/1426) diff --git a/guide/src/python_from_rust.md b/guide/src/python_from_rust.md index d2075eda..908247bf 100644 --- a/guide/src/python_from_rust.md +++ b/guide/src/python_from_rust.md @@ -115,7 +115,7 @@ use pyo3::prelude::*; fn main() -> PyResult<()> { Python::with_gil(|py| { let builtins = PyModule::import(py, "builtins")?; - let total: i32 = builtins.call_function1("sum", (vec![1, 2, 3],))?.extract()?; + let total: i32 = builtins.getattr("sum")?.call1((vec![1, 2, 3],))?.extract()?; assert_eq!(total, 6); Ok(()) }) @@ -215,12 +215,12 @@ def leaky_relu(x, slope=0.01): return x if x >= 0 else x * slope "#, "activators.py", "activators")?; - let relu_result: f64 = activators.call_function1("relu", (-1.0,))?.extract()?; + let relu_result: f64 = activators.getattr("relu")?.call1((-1.0,))?.extract()?; assert_eq!(relu_result, 0.0); let kwargs = [("slope", 0.2)].into_py_dict(py); let lrelu_result: f64 = activators - .call_function("leaky_relu", (-1.0,), Some(kwargs))? + .getattr("leaky_relu")?.call((-1.0,), Some(kwargs))? .extract()?; assert_eq!(lrelu_result, -0.2); # Ok(()) @@ -239,7 +239,7 @@ Use context managers by directly invoking `__enter__` and `__exit__`. use pyo3::prelude::*; use pyo3::types::PyModule; -fn main() { +fn main() { Python::with_gil(|py| { let custom_manager = PyModule::from_code(py, r#" class House(object): @@ -254,14 +254,15 @@ class House(object): print(f"Thank you for visiting {self.address}, come again soon!") "#, "house.py", "house").unwrap(); - - let house = custom_manager.call_function1("House", ("123 Main Street",)).unwrap(); + + let house_class = custom_manager.getattr("House").unwrap(); + let house = house_class.call1(("123 Main Street",)).unwrap(); house.call_method0("__enter__").unwrap(); let result = py.eval("undefined_variable + 1", None, None); - - // If the eval threw an exception we'll pass it through to the context manager. + + // If the eval threw an exception we'll pass it through to the context manager. // Otherwise, __exit__ is called with empty arguments (Python "None"). match result { Ok(_) => { diff --git a/src/exceptions.rs b/src/exceptions.rs index aab9057a..51be8f4e 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -101,7 +101,7 @@ macro_rules! import_exception { let imp = py .import(stringify!($module)) .expect(concat!("Can not import module: ", stringify!($module))); - let cls = imp.get(stringify!($name)).expect(concat!( + let cls = imp.getattr(stringify!($name)).expect(concat!( "Can not load exception class: {}.{}", stringify!($module), ".", diff --git a/src/types/module.rs b/src/types/module.rs index ec9c2e18..4e2c82b6 100644 --- a/src/types/module.rs +++ b/src/types/module.rs @@ -129,65 +129,6 @@ impl PyModule { } } - /// Calls a function in the module. - /// - /// This is equivalent to the Python expression `module.name(*args, **kwargs)`. - pub fn call_function( - &self, - name: &str, - args: impl IntoPy>, - kwargs: Option<&PyDict>, - ) -> PyResult<&PyAny> { - self.getattr(name)?.call(args, kwargs) - } - - /// Calls a function in the module with only positional arguments. - /// - /// This is equivalent to the Python expression `module.name(*args)`. - pub fn call_function1(&self, name: &str, args: impl IntoPy>) -> PyResult<&PyAny> { - self.getattr(name)?.call1(args) - } - - /// Calls a function in the module without arguments. - /// - /// This is equivalent to the Python expression `module.name()`. - pub fn call_function0(&self, name: &str) -> PyResult<&PyAny> { - self.getattr(name)?.call0() - } - - #[deprecated(since = "0.14.0", note = "Renamed to call_function() for consistency.")] - pub fn call( - &self, - name: &str, - args: impl IntoPy>, - kwargs: Option<&PyDict>, - ) -> PyResult<&PyAny> { - self.call_function(name, args, kwargs) - } - - #[deprecated( - since = "0.14.0", - note = "Renamed to call_function1() for consistency." - )] - pub fn call1(&self, name: &str, args: impl IntoPy>) -> PyResult<&PyAny> { - self.call_function1(name, args) - } - - #[deprecated( - since = "0.14.0", - note = "Renamed to call_function0() for consistency." - )] - pub fn call0(&self, name: &str) -> PyResult<&PyAny> { - self.call_function0(name) - } - - /// Gets a member from the module. - /// - /// This is equivalent to the Python expression `module.name`. - pub fn get(&self, name: &str) -> PyResult<&PyAny> { - self.getattr(name) - } - /// Adds a member to the module. /// /// This is a convenience function which can be used from the module's initialization function. @@ -310,4 +251,44 @@ impl PyModule { let name = fun.getattr("__name__")?.extract()?; self.add(name, fun) } + + /// Calls a function in the module. + /// + /// This is equivalent to the Python expression `module.name(*args, **kwargs)`. + #[deprecated( + since = "0.14.0", + note = "use getattr(name)?.call(args, kwargs) instead" + )] + pub fn call( + &self, + name: &str, + args: impl IntoPy>, + kwargs: Option<&PyDict>, + ) -> PyResult<&PyAny> { + self.getattr(name)?.call(args, kwargs) + } + + /// Calls a function in the module with only positional arguments. + /// + /// This is equivalent to the Python expression `module.name(*args)`. + #[deprecated(since = "0.14.0", note = "use getattr(name)?.call1(args) instead")] + pub fn call1(&self, name: &str, args: impl IntoPy>) -> PyResult<&PyAny> { + self.getattr(name)?.call1(args) + } + + /// Calls a function in the module without arguments. + /// + /// This is equivalent to the Python expression `module.name()`. + #[deprecated(since = "0.14.0", note = "use getattr(name)?.call0() instead")] + pub fn call0(&self, name: &str) -> PyResult<&PyAny> { + self.getattr(name)?.call0() + } + + /// Gets a member from the module. + /// + /// This is equivalent to the Python expression `module.name`. + #[deprecated(since = "0.14.0", note = "use getattr(name) instead")] + pub fn get(&self, name: &str) -> PyResult<&PyAny> { + self.getattr(name) + } } diff --git a/src/types/num.rs b/src/types/num.rs index ca48cda1..8f1a163e 100644 --- a/src/types/num.rs +++ b/src/types/num.rs @@ -489,12 +489,12 @@ mod bigint_conversion { .unwrap(); // Checks if Python Long -> Rust BigUint conversion is correct if N is small let py_result: BigUint = - FromPyObject::extract(fib.call_function1("fib", (400,)).unwrap()).unwrap(); + FromPyObject::extract(fib.getattr("fib").unwrap().call1((400,)).unwrap()).unwrap(); assert_eq!(rs_result, py_result); // Checks if Python Long -> Rust BigUint conversion is correct if N is large let rs_result: BigUint = rust_fib(2000); let py_result: BigUint = - FromPyObject::extract(fib.call_function1("fib", (2000,)).unwrap()).unwrap(); + FromPyObject::extract(fib.getattr("fib").unwrap().call1((2000,)).unwrap()).unwrap(); assert_eq!(rs_result, py_result); } @@ -512,12 +512,14 @@ mod bigint_conversion { .unwrap(); // Checks if Python Long -> Rust BigInt conversion is correct if N is small let py_result: BigInt = - FromPyObject::extract(fib.call_function1("fib_neg", (400,)).unwrap()).unwrap(); + FromPyObject::extract(fib.getattr("fib_neg").unwrap().call1((400,)).unwrap()) + .unwrap(); assert_eq!(rs_result, py_result); // Checks if Python Long -> Rust BigInt conversion is correct if N is large let rs_result = rust_fib::(2000) * -1; let py_result: BigInt = - FromPyObject::extract(fib.call_function1("fib_neg", (2000,)).unwrap()).unwrap(); + FromPyObject::extract(fib.getattr("fib_neg").unwrap().call1((2000,)).unwrap()) + .unwrap(); assert_eq!(rs_result, py_result); } @@ -551,7 +553,7 @@ mod bigint_conversion { let py = gil.python(); let fib = python_fib(py); let zero: BigInt = - FromPyObject::extract(fib.call_function1("fib", (0,)).unwrap()).unwrap(); + FromPyObject::extract(fib.getattr("fib").unwrap().call1((0,)).unwrap()).unwrap(); assert_eq!(zero, BigInt::from(0)); } diff --git a/tests/test_datetime.rs b/tests/test_datetime.rs index 412e4958..25412275 100644 --- a/tests/test_datetime.rs +++ b/tests/test_datetime.rs @@ -12,7 +12,7 @@ fn _get_subclasses<'p>( // Import the class from Python and create some subclasses let datetime = py.import("datetime")?; - let locals = [(py_type, datetime.get(py_type)?)].into_py_dict(*py); + let locals = [(py_type, datetime.getattr(py_type)?)].into_py_dict(*py); let make_subclass_py = format!("class Subklass({}):\n pass", py_type); @@ -108,7 +108,7 @@ fn test_datetime_utc() { let gil = Python::acquire_gil(); let py = gil.python(); let datetime = py.import("datetime").map_err(|e| e.print(py)).unwrap(); - let timezone = datetime.get("timezone").unwrap(); + let timezone = datetime.getattr("timezone").unwrap(); let utc = timezone.getattr("utc").unwrap().to_object(py); let dt = PyDateTime::new(py, 2018, 1, 1, 0, 0, 0, 0, Some(&utc)).unwrap(); diff --git a/tests/test_module.rs b/tests/test_module.rs index 68e01af2..2588ea90 100644 --- a/tests/test_module.rs +++ b/tests/test_module.rs @@ -141,7 +141,7 @@ fn test_module_from_code() { .expect("Module code should be loaded"); let add_func = adder_mod - .get("add") + .getattr("add") .expect("Add function should be in the module") .to_object(py);