From 6f1cf1b662d883933b9fe4e08c3b8d06fb3cb7f1 Mon Sep 17 00:00:00 2001 From: mejrs Date: Wed, 23 Mar 2022 08:07:28 +0100 Subject: [PATCH 1/3] Add more lints --- .cargo/config | 3 + README.md | 2 +- benches/bench_call.rs | 4 +- benches/bench_dict.rs | 12 +- benches/bench_err.rs | 4 +- benches/bench_frompyobject.rs | 2 +- benches/bench_gil.rs | 6 +- benches/bench_list.rs | 8 +- benches/bench_pyclass.rs | 2 +- benches/bench_pyobject.rs | 2 +- benches/bench_set.rs | 8 +- benches/bench_tuple.rs | 8 +- examples/decorator/src/lib.rs | 4 +- examples/maturin-starter/src/lib.rs | 2 +- examples/maturin-starter/src/submodule.rs | 2 +- examples/setuptools-rust-starter/src/lib.rs | 2 +- .../setuptools-rust-starter/src/submodule.rs | 2 +- examples/word-count/src/lib.rs | 2 +- guide/src/class.md | 16 +- guide/src/class/numeric.md | 6 +- guide/src/class/object.md | 4 +- guide/src/class/protocols.md | 24 +- guide/src/conversions/traits.md | 16 +- guide/src/ecosystem/async-await.md | 14 +- guide/src/exception.md | 4 +- guide/src/faq.md | 2 +- guide/src/function.md | 12 +- guide/src/migration.md | 16 +- guide/src/module.md | 16 +- guide/src/parallelism.md | 2 +- guide/src/rust_cpython.md | 6 +- guide/src/trait_bounds.md | 4 +- guide/src/types.md | 18 +- pyo3-macros-backend/src/attributes.rs | 8 +- pyo3-macros-backend/src/frompyobject.rs | 4 +- pyo3-macros-backend/src/konst.rs | 4 +- pyo3-macros-backend/src/module.rs | 4 +- pyo3-macros-backend/src/pyclass.rs | 16 +- pyo3-macros-backend/src/pyfunction.rs | 8 +- pyo3-macros-backend/src/pyimpl.rs | 2 +- pyo3-macros-backend/src/pymethod.rs | 37 +- pyo3-macros-backend/src/utils.rs | 2 +- pyo3-macros-backend/src/wrap.rs | 2 +- pytests/src/buf_and_str.rs | 2 +- pytests/src/datetime.rs | 6 +- pytests/src/lib.rs | 2 +- pytests/src/objstore.rs | 2 +- src/buffer.rs | 22 +- src/callback.rs | 32 +- src/class/buffer.rs | 8 +- src/class/gc.rs | 2 +- src/class/iter.rs | 2 +- src/conversion.rs | 42 +- src/conversions/array.rs | 4 +- src/conversions/hashbrown.rs | 8 +- src/conversions/indexmap.rs | 6 +- src/conversions/num_bigint.rs | 10 +- src/conversions/num_complex.rs | 8 +- src/conversions/osstr.rs | 18 +- src/conversions/path.rs | 18 +- src/err/err_state.rs | 16 +- src/err/impls.rs | 6 +- src/err/mod.rs | 58 +- src/exceptions.rs | 6 +- src/gil.rs | 12 +- src/impl_/extract_argument.rs | 2 +- src/impl_/frompyobject.rs | 2 +- src/impl_/pyclass.rs | 28 +- src/impl_/pymodule.rs | 6 +- src/instance.rs | 65 +- src/lib.rs | 14 +- src/marker.rs | 2 +- src/marshal.rs | 2 +- src/once_cell.rs | 8 +- src/pycell.rs | 18 +- src/pyclass.rs | 18 +- src/pyclass_init.rs | 12 +- src/test_hygiene/pymethods.rs | 44 +- src/test_hygiene/pymodule.rs | 4 +- src/type_object.rs | 12 +- src/types/any.rs | 6 +- src/types/boolobject.rs | 6 +- src/types/bytearray.rs | 2 +- src/types/bytes.rs | 4 +- src/types/capsule.rs | 4 +- src/types/cls.rs | 584 ++++++++++++++++++ src/types/complex.rs | 2 +- src/types/datetime.rs | 10 +- src/types/dict.rs | 18 +- src/types/floatob.rs | 8 +- src/types/function.rs | 6 +- src/types/iterator.rs | 5 +- src/types/list.rs | 13 +- src/types/mapping.rs | 2 +- src/types/mod.rs | 12 +- src/types/module.rs | 8 +- src/types/num.rs | 22 +- src/types/sequence.rs | 2 +- src/types/set.rs | 20 +- src/types/slice.rs | 4 +- src/types/string.rs | 26 +- src/types/tuple.rs | 24 +- src/types/typeobject.rs | 4 +- tests/test_arithmetics.rs | 52 +- tests/test_arithmetics_protos.rs | 2 +- tests/test_buffer.rs | 2 +- tests/test_buffer_protocol.rs | 2 +- tests/test_buffer_protocol_pyproto.rs | 2 +- tests/test_bytes.rs | 2 +- tests/test_class_conversion.rs | 12 +- tests/test_datetime.rs | 12 +- tests/test_exceptions.rs | 2 +- tests/test_frompyobject.rs | 5 +- tests/test_gc.rs | 10 +- tests/test_gc_pyproto.rs | 4 +- tests/test_getter_setter.rs | 4 +- tests/test_mapping.rs | 2 +- tests/test_mapping_pyproto.rs | 4 +- tests/test_methods.rs | 25 +- tests/test_module.rs | 24 +- tests/test_proto_methods.rs | 24 +- tests/test_pyfunction.rs | 4 +- tests/test_pyself.rs | 8 +- tests/test_sequence.rs | 6 +- tests/test_sequence_pyproto.rs | 2 +- tests/test_text_signature.rs | 2 +- tests/test_various.rs | 6 +- tests/test_wrap_pyfunction_deduction.rs | 2 +- tests/ui/invalid_macro_args.rs | 12 +- tests/ui/invalid_need_module_arg_position.rs | 2 +- tests/ui/invalid_property_args.rs | 6 +- tests/ui/invalid_property_args.stderr | 14 +- tests/ui/invalid_pymethod_proto_args_py.rs | 2 +- .../ui/invalid_pymethod_proto_args_py.stderr | 2 +- tests/ui/invalid_pymethod_receiver.rs | 2 +- tests/ui/invalid_pymethod_receiver.stderr | 2 +- tests/ui/invalid_pymodule_args.rs | 2 +- tests/ui/invalid_result_conversion.rs | 2 +- tests/ui/not_send.rs | 2 +- tests/ui/not_send_auto_trait.rs | 2 +- 140 files changed, 1275 insertions(+), 636 deletions(-) create mode 100644 src/types/cls.rs diff --git a/.cargo/config b/.cargo/config index 68542cc9..22c67c22 100644 --- a/.cargo/config +++ b/.cargo/config @@ -15,4 +15,7 @@ rustflags = [ "-Dclippy::todo", "-Dclippy::unnecessary_wraps", "-Dclippy::useless_transmute", + "-Delided_lifetimes_in_paths", + "-Dunused_lifetimes", + "-Drust_2021_prelude_collisions" ] \ No newline at end of file diff --git a/README.md b/README.md index 67e4ea31..69b067d3 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ fn sum_as_string(a: usize, b: usize) -> PyResult { /// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to /// import the module. #[pymodule] -fn string_sum(_py: Python, m: &PyModule) -> PyResult<()> { +fn string_sum(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(sum_as_string, m)?)?; Ok(()) } diff --git a/benches/bench_call.rs b/benches/bench_call.rs index 90c1a7ff..dd98c159 100644 --- a/benches/bench_call.rs +++ b/benches/bench_call.rs @@ -8,7 +8,7 @@ macro_rules! test_module { }; } -fn bench_call_0(b: &mut Bencher) { +fn bench_call_0(b: &mut Bencher<'_>) { Python::with_gil(|py| { let module = test_module!(py, "def foo(): pass"); @@ -22,7 +22,7 @@ fn bench_call_0(b: &mut Bencher) { }) } -fn bench_call_method_0(b: &mut Bencher) { +fn bench_call_method_0(b: &mut Bencher<'_>) { Python::with_gil(|py| { let module = test_module!( py, diff --git a/benches/bench_dict.rs b/benches/bench_dict.rs index e8d98939..7fea4272 100644 --- a/benches/bench_dict.rs +++ b/benches/bench_dict.rs @@ -4,7 +4,7 @@ use pyo3::prelude::*; use pyo3::types::IntoPyDict; use std::collections::{BTreeMap, HashMap}; -fn iter_dict(b: &mut Bencher) { +fn iter_dict(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -18,14 +18,14 @@ fn iter_dict(b: &mut Bencher) { }); } -fn dict_new(b: &mut Bencher) { +fn dict_new(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; b.iter(|| (0..LEN as u64).map(|i| (i, i * 2)).into_py_dict(py)); } -fn dict_get_item(b: &mut Bencher) { +fn dict_get_item(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; @@ -38,7 +38,7 @@ fn dict_get_item(b: &mut Bencher) { }); } -fn extract_hashmap(b: &mut Bencher) { +fn extract_hashmap(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -46,7 +46,7 @@ fn extract_hashmap(b: &mut Bencher) { b.iter(|| HashMap::::extract(dict)); } -fn extract_btreemap(b: &mut Bencher) { +fn extract_btreemap(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -55,7 +55,7 @@ fn extract_btreemap(b: &mut Bencher) { } #[cfg(feature = "hashbrown")] -fn extract_hashbrown_map(b: &mut Bencher) { +fn extract_hashbrown_map(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; diff --git a/benches/bench_err.rs b/benches/bench_err.rs index a0318d14..e3194512 100644 --- a/benches/bench_err.rs +++ b/benches/bench_err.rs @@ -2,7 +2,7 @@ use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::{exceptions::PyValueError, prelude::*}; -fn err_new_restore_and_fetch(b: &mut Bencher) { +fn err_new_restore_and_fetch(b: &mut Bencher<'_>) { Python::with_gil(|py| { b.iter(|| { PyValueError::new_err("some exception message").restore(py); @@ -11,7 +11,7 @@ fn err_new_restore_and_fetch(b: &mut Bencher) { }) } -fn err_new_without_gil(b: &mut Bencher) { +fn err_new_without_gil(b: &mut Bencher<'_>) { b.iter(|| PyValueError::new_err("some exception message")) } diff --git a/benches/bench_frompyobject.rs b/benches/bench_frompyobject.rs index 7f1274a8..8cf8a4da 100644 --- a/benches/bench_frompyobject.rs +++ b/benches/bench_frompyobject.rs @@ -9,7 +9,7 @@ enum ManyTypes { String(String), } -fn enum_from_pyobject(b: &mut Bencher) { +fn enum_from_pyobject(b: &mut Bencher<'_>) { Python::with_gil(|py| { let obj = PyString::new(py, "hello world"); b.iter(|| { diff --git a/benches/bench_gil.rs b/benches/bench_gil.rs index 8dfed873..1dc1e625 100644 --- a/benches/bench_gil.rs +++ b/benches/bench_gil.rs @@ -2,7 +2,7 @@ use criterion::{criterion_group, criterion_main, BatchSize, Bencher, Criterion}; use pyo3::{prelude::*, GILPool}; -fn bench_clean_gilpool_new(b: &mut Bencher) { +fn bench_clean_gilpool_new(b: &mut Bencher<'_>) { Python::with_gil(|_py| { b.iter(|| { let _ = unsafe { GILPool::new() }; @@ -10,14 +10,14 @@ fn bench_clean_gilpool_new(b: &mut Bencher) { }); } -fn bench_clean_acquire_gil(b: &mut Bencher) { +fn bench_clean_acquire_gil(b: &mut Bencher<'_>) { // Acquiring first GIL will also create a "clean" GILPool, so this measures the Python overhead. b.iter(|| { let _ = Python::acquire_gil(); }); } -fn bench_dirty_acquire_gil(b: &mut Bencher) { +fn bench_dirty_acquire_gil(b: &mut Bencher<'_>) { let obj = Python::with_gil(|py| py.None()); b.iter_batched( || { diff --git a/benches/bench_list.rs b/benches/bench_list.rs index 12fd4510..b52f9890 100644 --- a/benches/bench_list.rs +++ b/benches/bench_list.rs @@ -3,7 +3,7 @@ use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::prelude::*; use pyo3::types::PyList; -fn iter_list(b: &mut Bencher) { +fn iter_list(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -17,14 +17,14 @@ fn iter_list(b: &mut Bencher) { }); } -fn list_new(b: &mut Bencher) { +fn list_new(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; b.iter(|| PyList::new(py, 0..LEN)); } -fn list_get_item(b: &mut Bencher) { +fn list_get_item(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; @@ -38,7 +38,7 @@ fn list_get_item(b: &mut Bencher) { } #[cfg(not(Py_LIMITED_API))] -fn list_get_item_unchecked(b: &mut Bencher) { +fn list_get_item_unchecked(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; diff --git a/benches/bench_pyclass.rs b/benches/bench_pyclass.rs index b20df3a3..2d6868d4 100644 --- a/benches/bench_pyclass.rs +++ b/benches/bench_pyclass.rs @@ -26,7 +26,7 @@ impl MyClass { } } -pub fn first_time_init(b: &mut criterion::Bencher) { +pub fn first_time_init(b: &mut criterion::Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); b.iter(|| { diff --git a/benches/bench_pyobject.rs b/benches/bench_pyobject.rs index bc507f90..fb17c050 100644 --- a/benches/bench_pyobject.rs +++ b/benches/bench_pyobject.rs @@ -2,7 +2,7 @@ use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::prelude::*; -fn drop_many_objects(b: &mut Bencher) { +fn drop_many_objects(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); b.iter(|| { diff --git a/benches/bench_set.rs b/benches/bench_set.rs index 7615bb84..698f6eb3 100644 --- a/benches/bench_set.rs +++ b/benches/bench_set.rs @@ -4,7 +4,7 @@ use pyo3::prelude::*; use pyo3::types::PySet; use std::collections::{BTreeSet, HashSet}; -fn iter_set(b: &mut Bencher) { +fn iter_set(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -18,7 +18,7 @@ fn iter_set(b: &mut Bencher) { }); } -fn extract_hashset(b: &mut Bencher) { +fn extract_hashset(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -26,7 +26,7 @@ fn extract_hashset(b: &mut Bencher) { b.iter(|| HashSet::::extract(set)); } -fn extract_btreeset(b: &mut Bencher) { +fn extract_btreeset(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -35,7 +35,7 @@ fn extract_btreeset(b: &mut Bencher) { } #[cfg(feature = "hashbrown")] -fn extract_hashbrown_set(b: &mut Bencher) { +fn extract_hashbrown_set(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; diff --git a/benches/bench_tuple.rs b/benches/bench_tuple.rs index 29724318..4a5eb8b5 100644 --- a/benches/bench_tuple.rs +++ b/benches/bench_tuple.rs @@ -3,7 +3,7 @@ use criterion::{criterion_group, criterion_main, Bencher, Criterion}; use pyo3::prelude::*; use pyo3::types::PyTuple; -fn iter_tuple(b: &mut Bencher) { +fn iter_tuple(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 100_000; @@ -17,14 +17,14 @@ fn iter_tuple(b: &mut Bencher) { }); } -fn tuple_new(b: &mut Bencher) { +fn tuple_new(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; b.iter(|| PyTuple::new(py, 0..LEN)); } -fn tuple_get_item(b: &mut Bencher) { +fn tuple_get_item(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; @@ -38,7 +38,7 @@ fn tuple_get_item(b: &mut Bencher) { } #[cfg(not(Py_LIMITED_API))] -fn tuple_get_item_unchecked(b: &mut Bencher) { +fn tuple_get_item_unchecked(b: &mut Bencher<'_>) { let gil = Python::acquire_gil(); let py = gil.python(); const LEN: usize = 50_000; diff --git a/examples/decorator/src/lib.rs b/examples/decorator/src/lib.rs index 35520a17..078b33f0 100644 --- a/examples/decorator/src/lib.rs +++ b/examples/decorator/src/lib.rs @@ -29,7 +29,7 @@ impl PyCounter { #[args(args = "*", kwargs = "**")] fn __call__( &mut self, - py: Python, + py: Python<'_>, args: &PyTuple, kwargs: Option<&PyDict>, ) -> PyResult> { @@ -48,7 +48,7 @@ impl PyCounter { } #[pymodule] -pub fn decorator(_py: Python, module: &PyModule) -> PyResult<()> { +pub fn decorator(_py: Python<'_>, module: &PyModule) -> PyResult<()> { module.add_class::()?; Ok(()) } diff --git a/examples/maturin-starter/src/lib.rs b/examples/maturin-starter/src/lib.rs index 3a79ca51..0b845842 100644 --- a/examples/maturin-starter/src/lib.rs +++ b/examples/maturin-starter/src/lib.rs @@ -21,7 +21,7 @@ impl ExampleClass { /// An example module implemented in Rust using PyO3. #[pymodule] -fn maturin_starter(py: Python, m: &PyModule) -> PyResult<()> { +fn maturin_starter(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_wrapped(wrap_pymodule!(submodule))?; diff --git a/examples/maturin-starter/src/submodule.rs b/examples/maturin-starter/src/submodule.rs index 8096e337..56540b2e 100644 --- a/examples/maturin-starter/src/submodule.rs +++ b/examples/maturin-starter/src/submodule.rs @@ -16,7 +16,7 @@ impl SubmoduleClass { } #[pymodule] -pub fn submodule(_py: Python, m: &PyModule) -> PyResult<()> { +pub fn submodule(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } diff --git a/examples/setuptools-rust-starter/src/lib.rs b/examples/setuptools-rust-starter/src/lib.rs index 6f09f43a..46af25f1 100644 --- a/examples/setuptools-rust-starter/src/lib.rs +++ b/examples/setuptools-rust-starter/src/lib.rs @@ -21,7 +21,7 @@ impl ExampleClass { /// An example module implemented in Rust using PyO3. #[pymodule] -fn _setuptools_rust_starter(py: Python, m: &PyModule) -> PyResult<()> { +fn _setuptools_rust_starter(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_wrapped(wrap_pymodule!(submodule))?; diff --git a/examples/setuptools-rust-starter/src/submodule.rs b/examples/setuptools-rust-starter/src/submodule.rs index 8096e337..56540b2e 100644 --- a/examples/setuptools-rust-starter/src/submodule.rs +++ b/examples/setuptools-rust-starter/src/submodule.rs @@ -16,7 +16,7 @@ impl SubmoduleClass { } #[pymodule] -pub fn submodule(_py: Python, m: &PyModule) -> PyResult<()> { +pub fn submodule(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } diff --git a/examples/word-count/src/lib.rs b/examples/word-count/src/lib.rs index 96f9f9e2..b7d3a803 100644 --- a/examples/word-count/src/lib.rs +++ b/examples/word-count/src/lib.rs @@ -17,7 +17,7 @@ fn search_sequential(contents: &str, needle: &str) -> usize { } #[pyfunction] -fn search_sequential_allow_threads(py: Python, contents: &str, needle: &str) -> usize { +fn search_sequential_allow_threads(py: Python<'_>, contents: &str, needle: &str) -> usize { py.allow_threads(|| search_sequential(contents, needle)) } diff --git a/guide/src/class.md b/guide/src/class.md index e40e4a5f..be1b3e47 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -113,7 +113,7 @@ The next step is to create the module initializer and add our class to it # struct Number(i32); # #[pymodule] -fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } @@ -273,7 +273,7 @@ impl SubClass { (SubClass { val2: 15 }, BaseClass::new()) } - fn method2(self_: PyRef) -> PyResult { + fn method2(self_: PyRef<'_, Self>) -> PyResult { let super_ = self_.as_ref(); // Get &BaseClass super_.method().map(|x| x * self_.val2) } @@ -292,9 +292,9 @@ impl SubSubClass { .add_subclass(SubSubClass{val3: 20}) } - fn method3(self_: PyRef) -> PyResult { + fn method3(self_: PyRef<'_, Self>) -> PyResult { let v = self_.val3; - let super_ = self_.into_super(); // Get PyRef + let super_ = self_.into_super(); // Get PyRef<'_, SubClass> SubClass::method2(super_).map(|x| x * v) } } @@ -329,7 +329,7 @@ impl DictWithCounter { fn new() -> Self { Self::default() } - fn set(mut self_: PyRefMut, key: String, value: &PyAny) -> PyResult<()> { + fn set(mut self_: PyRefMut<'_, Self>, key: String, value: &PyAny) -> PyResult<()> { self_.counter.entry(key.clone()).or_insert(0); let py = self_.py(); let dict: &PyDict = unsafe { py.from_borrowed_ptr_or_err(self_.as_ptr())? }; @@ -524,7 +524,7 @@ gets injected by the method wrapper, e.g. # } #[pymethods] impl MyClass { - fn method2(&self, py: Python) -> PyResult { + fn method2(&self, py: Python<'_>) -> PyResult { Ok(10) } } @@ -960,7 +960,7 @@ unsafe impl pyo3::PyTypeInfo for MyClass { const MODULE: Option<&'static str> = None; #[inline] - fn type_object_raw(py: pyo3::Python) -> *mut pyo3::ffi::PyTypeObject { + fn type_object_raw(py: pyo3::Python<'_>) -> *mut pyo3::ffi::PyTypeObject { use pyo3::type_object::LazyStaticType; static TYPE_OBJECT: LazyStaticType = LazyStaticType::new(); TYPE_OBJECT.get_or_init::(py) @@ -974,7 +974,7 @@ impl pyo3::pyclass::PyClass for MyClass { } impl pyo3::IntoPy for MyClass { - fn into_py(self, py: pyo3::Python) -> pyo3::PyObject { + fn into_py(self, py: pyo3::Python<'_>) -> pyo3::PyObject { pyo3::IntoPy::into_py(pyo3::Py::new(py, self).unwrap(), py) } } diff --git a/guide/src/class/numeric.md b/guide/src/class/numeric.md index 0fc06c4e..a93d2239 100644 --- a/guide/src/class/numeric.md +++ b/guide/src/class/numeric.md @@ -134,7 +134,7 @@ impl Number { # #[pymethods] impl Number { - fn __pos__(slf: PyRef) -> PyRef { + fn __pos__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } @@ -328,7 +328,7 @@ impl Number { } #[pymodule] -fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } @@ -426,7 +426,7 @@ use pyo3::ffi; use pyo3::conversion::AsPyPointer; fn wrap(obj: &PyAny) -> Result { - let py: Python = obj.py(); + let py: Python<'_> = obj.py(); unsafe { let ptr = obj.as_ptr(); diff --git a/guide/src/class/object.md b/guide/src/class/object.md index 7a20d03c..ade91da8 100644 --- a/guide/src/class/object.md +++ b/guide/src/class/object.md @@ -17,7 +17,7 @@ impl Number { } #[pymodule] -fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } @@ -220,7 +220,7 @@ impl Number { } #[pymodule] -fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } diff --git a/guide/src/class/protocols.md b/guide/src/class/protocols.md index cacde232..320307d0 100644 --- a/guide/src/class/protocols.md +++ b/guide/src/class/protocols.md @@ -22,8 +22,8 @@ When PyO3 handles a magic method, a couple of changes apply compared to other `# The following sections list of all magic methods PyO3 currently handles. The given signatures should be interpreted as follows: - All methods take a receiver as first argument, shown as ``. It can be - `&self`, `&mut self` or a `PyCell` reference like `self_: PyRef` and - `self_: PyRefMut`, as described [here](../class.md#inheritance). + `&self`, `&mut self` or a `PyCell` reference like `self_: PyRef<'_, Self>` and + `self_: PyRefMut<'_, Self>`, as described [here](../class.md#inheritance). - An optional `Python<'py>` argument is always allowed as the first argument. - Return values can be optionally wrapped in `PyResult`. - `object` means that any type is allowed that can be extracted from a Python @@ -118,10 +118,10 @@ struct MyIterator { #[pymethods] impl MyIterator { - fn __iter__(slf: PyRef) -> PyRef { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } - fn __next__(mut slf: PyRefMut) -> Option { + fn __next__(mut slf: PyRefMut<'_, Self>) -> Option { slf.iter.next() } } @@ -142,11 +142,11 @@ struct Iter { #[pymethods] impl Iter { - fn __iter__(slf: PyRef) -> PyRef { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } - fn __next__(mut slf: PyRefMut) -> Option { + fn __next__(mut slf: PyRefMut<'_, Self>) -> Option { slf.inner.next() } } @@ -158,7 +158,7 @@ struct Container { #[pymethods] impl Container { - fn __iter__(slf: PyRef) -> PyResult> { + fn __iter__(slf: PyRef<'_, Self>) -> PyResult> { let iter = Iter { inner: slf.iter.clone().into_iter(), }; @@ -355,7 +355,7 @@ object. `__clear__` must clear out any mutable references to other Python objects (thus breaking reference cycles). Immutable references do not have to be cleared, as every cycle must contain at least one mutable reference. - - `__traverse__(, pyo3::class::gc::PyVisit) -> Result<(), pyo3::class::gc::PyTraverseError>` + - `__traverse__(, pyo3::class::gc::PyVisit<'_>) -> Result<(), pyo3::class::gc::PyTraverseError>` - `__clear__() -> ()` Example: @@ -372,7 +372,7 @@ struct ClassWithGCSupport { #[pymethods] impl ClassWithGCSupport { - fn __traverse__(&self, visit: PyVisit) -> Result<(), PyTraverseError> { + fn __traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError> { if let Some(obj) = &self.obj { visit.call(obj)? } @@ -580,10 +580,10 @@ For a mapping, the keys may be Python objects of arbitrary type. Iterators can be defined using the [`PyIterProtocol`] trait. It includes two methods `__iter__` and `__next__`: - * `fn __iter__(slf: PyRefMut) -> PyResult>` - * `fn __next__(slf: PyRefMut) -> PyResult>>` + * `fn __iter__(slf: PyRefMut<'_, Self>) -> PyResult>` + * `fn __next__(slf: PyRefMut<'_, Self>) -> PyResult>>` -These two methods can be take either `PyRef` or `PyRefMut` as their +These two methods can be take either `PyRef<'_, Self>` or `PyRefMut<'_, Self>` as their first argument, so that mutable borrow can be avoided if needed. For details, look at the `#[pymethods]` regarding iterator methods. diff --git a/guide/src/conversions/traits.md b/guide/src/conversions/traits.md index 63fa81d2..2705413d 100644 --- a/guide/src/conversions/traits.md +++ b/guide/src/conversions/traits.md @@ -253,7 +253,7 @@ enum RustyEnum<'a> { # Python::with_gil(|py| -> PyResult<()> { # { # let thing = 42_u8.to_object(py); -# let rust_thing: RustyEnum = thing.extract(py)?; +# let rust_thing: RustyEnum<'_> = thing.extract(py)?; # # assert_eq!( # 42, @@ -265,7 +265,7 @@ enum RustyEnum<'a> { # } # { # let thing = PyString::new(py, "text"); -# let rust_thing: RustyEnum = thing.extract()?; +# let rust_thing: RustyEnum<'_> = thing.extract()?; # # assert_eq!( # "text", @@ -277,7 +277,7 @@ enum RustyEnum<'a> { # } # { # let thing = (32_u8, 73_u8).to_object(py); -# let rust_thing: RustyEnum = thing.extract(py)?; +# let rust_thing: RustyEnum<'_> = thing.extract(py)?; # # assert_eq!( # (32, 73), @@ -289,7 +289,7 @@ enum RustyEnum<'a> { # } # { # let thing = ("foo", 73_u8).to_object(py); -# let rust_thing: RustyEnum = thing.extract(py)?; +# let rust_thing: RustyEnum<'_> = thing.extract(py)?; # # assert_eq!( # (String::from("foo"), 73), @@ -313,7 +313,7 @@ enum RustyEnum<'a> { # # let class = module.getattr("Foo")?; # let instance = class.call0()?; -# let rust_thing: RustyEnum = instance.extract()?; +# let rust_thing: RustyEnum<'_> = instance.extract()?; # # assert_eq!( # (0, 1, 2), @@ -337,7 +337,7 @@ enum RustyEnum<'a> { # # let class = module.getattr("Foo")?; # let instance = class.call0()?; -# let rust_thing: RustyEnum = instance.extract()?; +# let rust_thing: RustyEnum<'_> = instance.extract()?; # # assert_eq!( # (3, 4), @@ -350,7 +350,7 @@ enum RustyEnum<'a> { # # { # let thing = PyBytes::new(py, b"text"); -# let rust_thing: RustyEnum = thing.extract()?; +# let rust_thing: RustyEnum<'_> = thing.extract()?; # # assert_eq!( # b"text", @@ -464,7 +464,7 @@ use pyo3::prelude::*; struct MyPyObjectWrapper(PyObject); impl IntoPy for MyPyObjectWrapper { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.0 } } diff --git a/guide/src/ecosystem/async-await.md b/guide/src/ecosystem/async-await.md index 37e1333f..262b27e6 100644 --- a/guide/src/ecosystem/async-await.md +++ b/guide/src/ecosystem/async-await.md @@ -118,7 +118,7 @@ Export an async function that makes use of `async-std`: use pyo3::{prelude::*, wrap_pyfunction}; #[pyfunction] -fn rust_sleep(py: Python) -> PyResult<&PyAny> { +fn rust_sleep(py: Python<'_>) -> PyResult<&PyAny> { pyo3_asyncio::async_std::future_into_py(py, async { async_std::task::sleep(std::time::Duration::from_secs(1)).await; Ok(Python::with_gil(|py| py.None())) @@ -126,7 +126,7 @@ fn rust_sleep(py: Python) -> PyResult<&PyAny> { } #[pymodule] -fn my_async_module(py: Python, m: &PyModule) -> PyResult<()> { +fn my_async_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(rust_sleep, m)?)?; Ok(()) @@ -142,7 +142,7 @@ If you want to use `tokio` instead, here's what your module should look like: use pyo3::{prelude::*, wrap_pyfunction}; #[pyfunction] -fn rust_sleep(py: Python) -> PyResult<&PyAny> { +fn rust_sleep(py: Python<'_>) -> PyResult<&PyAny> { pyo3_asyncio::tokio::future_into_py(py, async { tokio::time::sleep(std::time::Duration::from_secs(1)).await; Ok(Python::with_gil(|py| py.None())) @@ -150,7 +150,7 @@ fn rust_sleep(py: Python) -> PyResult<&PyAny> { } #[pymodule] -fn my_async_module(py: Python, m: &PyModule) -> PyResult<()> { +fn my_async_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(rust_sleep, m)?)?; Ok(()) } @@ -316,7 +316,7 @@ async fn rust_sleep() { } #[pyfunction] -fn call_rust_sleep(py: Python) -> PyResult<&PyAny> { +fn call_rust_sleep(py: Python<'_>) -> PyResult<&PyAny> { pyo3_asyncio::async_std::future_into_py(py, async move { rust_sleep().await; Ok(Python::with_gil(|py| py.None())) @@ -466,7 +466,7 @@ tokio = "1.4" use pyo3::{prelude::*, wrap_pyfunction}; #[pyfunction] -fn rust_sleep(py: Python) -> PyResult<&PyAny> { +fn rust_sleep(py: Python<'_>) -> PyResult<&PyAny> { pyo3_asyncio::tokio::future_into_py(py, async { tokio::time::sleep(std::time::Duration::from_secs(1)).await; Ok(Python::with_gil(|py| py.None())) @@ -474,7 +474,7 @@ fn rust_sleep(py: Python) -> PyResult<&PyAny> { } #[pymodule] -fn my_async_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn my_async_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(rust_sleep, m)?)?; Ok(()) diff --git a/guide/src/exception.md b/guide/src/exception.md index 251d7f85..f205e035 100644 --- a/guide/src/exception.md +++ b/guide/src/exception.md @@ -38,7 +38,7 @@ the module like this, so that it is importable from Python: create_exception!(mymodule, CustomError, PyException); #[pymodule] -fn mymodule(py: Python, m: &PyModule) -> PyResult<()> { +fn mymodule(py: Python<'_>, m: &PyModule) -> PyResult<()> { // ... other elements added to module ... m.add("CustomError", py.get_type::())?; @@ -151,7 +151,7 @@ struct CustomIOError; impl std::error::Error for CustomIOError {} impl fmt::Display for CustomIOError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Oh no!") } } diff --git a/guide/src/faq.md b/guide/src/faq.md index 42cb5b27..6ef7fd67 100644 --- a/guide/src/faq.md +++ b/guide/src/faq.md @@ -116,7 +116,7 @@ struct Outer { #[pymethods] impl Outer { #[new] - fn __new__(py: Python) -> PyResult { + fn __new__(py: Python<'_>) -> PyResult { Ok(Self { inner: Py::new(py, Inner {})?, }) diff --git a/guide/src/function.md b/guide/src/function.md index e027b99c..1fa6c9ca 100644 --- a/guide/src/function.md +++ b/guide/src/function.md @@ -13,7 +13,7 @@ fn double(x: usize) -> usize { } #[pymodule] -fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { +fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(double, m)?)?; Ok(()) } @@ -49,7 +49,7 @@ The `#[pyo3]` attribute can be used to modify properties of the generated Python fn no_args_py() -> usize { 42 } #[pymodule] - fn module_with_functions(py: Python, m: &PyModule) -> PyResult<()> { + fn module_with_functions(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(no_args_py, m)?)?; Ok(()) } @@ -113,7 +113,7 @@ The `#[pyo3]` attribute can be used to modify properties of the generated Python } #[pymodule] - fn module_with_fn(py: Python, m: &PyModule) -> PyResult<()> { + fn module_with_fn(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(pyfunction_with_module, m)?) } ``` @@ -132,7 +132,7 @@ fn num_kwds(kwds: Option<&PyDict>) -> usize { } #[pymodule] -fn module_with_functions(py: Python, m: &PyModule) -> PyResult<()> { +fn module_with_functions(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(num_kwds, m)?).unwrap(); Ok(()) } @@ -273,7 +273,7 @@ An example of `#[pyfn]` is below: use pyo3::prelude::*; #[pymodule] -fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { +fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pyfn(m)] fn double(x: usize) -> usize { @@ -291,7 +291,7 @@ documented in the rest of this chapter. The code above is expanded to the follow use pyo3::prelude::*; #[pymodule] -fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { +fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pyfunction] fn double(x: usize) -> usize { diff --git a/guide/src/migration.md b/guide/src/migration.md index 6996f9a9..ada829af 100644 --- a/guide/src/migration.md +++ b/guide/src/migration.md @@ -117,7 +117,7 @@ mod foo { use pyo3::prelude::*; #[pymodule] - fn private_submodule(_py: Python, m: &PyModule) -> PyResult<()> { + fn private_submodule(_py: Python<'_>, m: &PyModule) -> PyResult<()> { Ok(()) } } @@ -126,7 +126,7 @@ use pyo3::prelude::*; use foo::*; #[pymodule] -fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_wrapped(wrap_pymodule!(private_submodule))?; Ok(()) } @@ -139,7 +139,7 @@ mod foo { use pyo3::prelude::*; #[pymodule] - pub(crate) fn private_submodule(_py: Python, m: &PyModule) -> PyResult<()> { + pub(crate) fn private_submodule(_py: Python<'_>, m: &PyModule) -> PyResult<()> { Ok(()) } } @@ -149,7 +149,7 @@ use pyo3::wrap_pymodule; use foo::*; #[pymodule] -fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_wrapped(wrap_pymodule!(private_submodule))?; Ok(()) } @@ -346,7 +346,7 @@ Before: struct MyPyObjectWrapper(PyObject); impl FromPy for PyObject { - fn from_py(other: MyPyObjectWrapper, _py: Python) -> Self { + fn from_py(other: MyPyObjectWrapper, _py: Python<'_>) -> Self { other.0 } } @@ -358,7 +358,7 @@ After struct MyPyObjectWrapper(PyObject); impl IntoPy for MyPyObjectWrapper { - fn into_py(self, _py: Python) -> PyObject { + fn into_py(self, _py: Python<'_>) -> PyObject { self.0 } } @@ -676,10 +676,10 @@ let obj: &PyAny = create_obj(); let obj_cell: &PyCell = obj.extract().unwrap(); let obj_cloned: MyClass = obj.extract().unwrap(); // extracted by cloning the object { - let obj_ref: PyRef = obj.extract().unwrap(); + let obj_ref: PyRef<'_, MyClass> = obj.extract().unwrap(); // we need to drop obj_ref before we can extract a PyRefMut due to Rust's rules of references } -let obj_ref_mut: PyRefMut = obj.extract().unwrap(); +let obj_ref_mut: PyRefMut<'_, MyClass> = obj.extract().unwrap(); # }) ``` diff --git a/guide/src/module.md b/guide/src/module.md index c85ecc48..6b80b71c 100644 --- a/guide/src/module.md +++ b/guide/src/module.md @@ -12,7 +12,7 @@ fn double(x: usize) -> usize { /// This module is implemented in Rust. #[pymodule] -fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { +fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(double, m)?)?; Ok(()) } @@ -34,7 +34,7 @@ fn double(x: usize) -> usize { #[pymodule] #[pyo3(name = "custom_name")] -fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { +fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(double, m)?)?; Ok(()) } @@ -76,7 +76,7 @@ references to the `PyModule` so that each module registers its own FFI code. For use pyo3::prelude::*; #[pymodule] -fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { +fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { dirutil::register(py, m)?; osutil::register(py, m)?; Ok(()) @@ -86,7 +86,7 @@ fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { # mod dirutil { use pyo3::prelude::*; -pub(crate) fn register(py: Python, m: &PyModule) -> PyResult<()> { +pub(crate) fn register(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } @@ -99,7 +99,7 @@ struct SomeClass {/* ... */} # mod osutil { use pyo3::prelude::*; -pub(crate) fn register(py: Python, m: &PyModule) -> PyResult<()> { +pub(crate) fn register(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(determine_current_os, m)?)?; Ok(()) } @@ -120,7 +120,7 @@ use pyo3::prelude::*; use osutil::*; #[pymodule] -fn my_extension(py: Python, m: &PyModule) -> PyResult<()> { +fn my_extension(py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(determine_current_os, m)?)?; Ok(()) } @@ -146,12 +146,12 @@ For example, you could define the modules `parent_module` and `parent_module.chi use pyo3::prelude::*; #[pymodule] -fn parent_module(py: Python, m: &PyModule) -> PyResult<()> { +fn parent_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { register_child_module(py, m)?; Ok(()) } -fn register_child_module(py: Python, parent_module: &PyModule) -> PyResult<()> { +fn register_child_module(py: Python<'_>, parent_module: &PyModule) -> PyResult<()> { let child_module = PyModule::new(py, "child_module")?; child_module.add_function(wrap_pyfunction!(func, child_module)?)?; parent_module.add_submodule(child_module)?; diff --git a/guide/src/parallelism.md b/guide/src/parallelism.md index cdf2f9bd..f35f1da5 100644 --- a/guide/src/parallelism.md +++ b/guide/src/parallelism.md @@ -23,7 +23,7 @@ fn search_sequential(contents: &str, needle: &str) -> usize { To enable parallel execution of this function, the [`Python::allow_threads`] method can be used to temporarily release the GIL, thus allowing other Python threads to run. We then have a function exposed to the Python runtime which calls `search_sequential` inside a closure passed to [`Python::allow_threads`] to enable true parallelism: ```rust, ignore #[pyfunction] -fn search_sequential_allow_threads(py: Python, contents: &str, needle: &str) -> usize { +fn search_sequential_allow_threads(py: Python<'_>, contents: &str, needle: &str) -> usize { py.allow_threads(|| search_sequential(contents, needle)) } ``` diff --git a/guide/src/rust_cpython.md b/guide/src/rust_cpython.md index 91f33933..fd3a878b 100644 --- a/guide/src/rust_cpython.md +++ b/guide/src/rust_cpython.md @@ -55,9 +55,9 @@ Here is an example of the PyList API: ```rust,ignore impl PyList { - fn new(py: Python) -> PyList {...} + fn new(py: Python<'_>) -> PyList {...} - fn get_item(&self, py: Python, index: isize) -> PyObject {...} + fn get_item(&self, py: Python<'_>, index: isize) -> PyObject {...} } ``` @@ -66,7 +66,7 @@ impl PyList { ```rust,ignore impl PyList { - fn new(py: Python) -> &PyList {...} + fn new(py: Python<'_>) -> &PyList {...} fn get_item(&self, index: isize) -> &PyAny {...} } diff --git a/guide/src/trait_bounds.md b/guide/src/trait_bounds.md index a57a7580..f08749e0 100644 --- a/guide/src/trait_bounds.md +++ b/guide/src/trait_bounds.md @@ -133,7 +133,7 @@ struct UserModel { } #[pymodule] -fn trait_exposure(_py: Python, m: &PyModule) -> PyResult<()> { +fn trait_exposure(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } @@ -487,7 +487,7 @@ pub struct UserModel { } #[pymodule] -fn trait_exposure(_py: Python, m: &PyModule) -> PyResult<()> { +fn trait_exposure(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; m.add_function(wrap_pyfunction!(solve_wrapper, m)?)?; Ok(()) diff --git a/guide/src/types.md b/guide/src/types.md index ed2fda6c..f75ac554 100644 --- a/guide/src/types.md +++ b/guide/src/types.md @@ -103,9 +103,9 @@ let _: Py = obj.extract()?; // To MyClass with PyAny::extract, if MyClass: Clone let _: MyClass = obj.extract()?; -// To PyRef or PyRefMut with PyAny::extract -let _: PyRef = obj.extract()?; -let _: PyRefMut = obj.extract()?; +// To PyRef<'_, MyClass> or PyRefMut<'_, MyClass> with PyAny::extract +let _: PyRef<'_, MyClass> = obj.extract()?; +let _: PyRefMut<'_, MyClass> = obj.extract()?; # Ok(()) # }).unwrap(); ``` @@ -207,11 +207,11 @@ let _: &PyCell = my_class.into_ref(py); let _: Py = my_class.into_py(py); # let my_class = my_class_clone; -// To PyRef with Py::borrow or Py::try_borrow -let _: PyRef = my_class.try_borrow(py)?; +// To PyRef<'_, MyClass> with Py::borrow or Py::try_borrow +let _: PyRef<'_, MyClass> = my_class.try_borrow(py)?; -// To PyRefMut with Py::borrow_mut or Py::try_borrow_mut -let _: PyRefMut = my_class.try_borrow_mut(py)?; +// To PyRefMut<'_, MyClass> with Py::borrow_mut or Py::try_borrow_mut +let _: PyRefMut<'_, MyClass> = my_class.try_borrow_mut(py)?; # Ok(()) # }).unwrap(); # }); @@ -241,12 +241,12 @@ so it also exposes all of the methods on `PyAny`. let cell: &PyCell = PyCell::new(py, MyClass { })?; // To PyRef with .borrow() or .try_borrow() -let py_ref: PyRef = cell.try_borrow()?; +let py_ref: PyRef<'_, MyClass> = cell.try_borrow()?; let _: &MyClass = &*py_ref; # drop(py_ref); // To PyRefMut with .borrow_mut() or .try_borrow_mut() -let mut py_ref_mut: PyRefMut = cell.try_borrow_mut()?; +let mut py_ref_mut: PyRefMut<'_, MyClass> = cell.try_borrow_mut()?; let _: &mut MyClass = &mut *py_ref_mut; # Ok(()) # }).unwrap(); diff --git a/pyo3-macros-backend/src/attributes.rs b/pyo3-macros-backend/src/attributes.rs index e0566076..128c8f9e 100644 --- a/pyo3-macros-backend/src/attributes.rs +++ b/pyo3-macros-backend/src/attributes.rs @@ -23,7 +23,7 @@ pub mod kw { pub struct FromPyWithAttribute(pub ExprPath); impl Parse for FromPyWithAttribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let _: kw::from_py_with = input.parse()?; let _: Token![=] = input.parse()?; let string_literal: LitStr = input.parse()?; @@ -35,7 +35,7 @@ impl Parse for FromPyWithAttribute { pub struct NameAttribute(pub Ident); impl Parse for NameAttribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let _: kw::name = input.parse()?; let _: Token![=] = input.parse()?; let string_literal: LitStr = input.parse()?; @@ -48,7 +48,7 @@ impl Parse for NameAttribute { pub struct CrateAttribute(pub Path); impl Parse for CrateAttribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let _: Token![crate] = input.parse()?; let _: Token![=] = input.parse()?; let string_literal: LitStr = input.parse()?; @@ -64,7 +64,7 @@ pub struct TextSignatureAttribute { } impl Parse for TextSignatureAttribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { Ok(TextSignatureAttribute { kw: input.parse()?, eq_token: input.parse()?, diff --git a/pyo3-macros-backend/src/frompyobject.rs b/pyo3-macros-backend/src/frompyobject.rs index f262df3e..f26193b8 100644 --- a/pyo3-macros-backend/src/frompyobject.rs +++ b/pyo3-macros-backend/src/frompyobject.rs @@ -346,7 +346,7 @@ enum ContainerPyO3Attribute { } impl Parse for ContainerPyO3Attribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::transparent) { let kw: attributes::kw::transparent = input.parse()?; @@ -419,7 +419,7 @@ enum FieldPyO3Attribute { } impl Parse for FieldPyO3Attribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::attribute) { let _: attributes::kw::attribute = input.parse()?; diff --git a/pyo3-macros-backend/src/konst.rs b/pyo3-macros-backend/src/konst.rs index c11c828d..7bf2043a 100644 --- a/pyo3-macros-backend/src/konst.rs +++ b/pyo3-macros-backend/src/konst.rs @@ -19,7 +19,7 @@ pub struct ConstSpec { } impl ConstSpec { - pub fn python_name(&self) -> Cow { + pub fn python_name(&self) -> Cow<'_, Ident> { if let Some(name) = &self.attributes.name { Cow::Borrowed(&name.0) } else { @@ -45,7 +45,7 @@ pub enum PyO3ConstAttribute { } impl Parse for PyO3ConstAttribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::name) { input.parse().map(PyO3ConstAttribute::Name) diff --git a/pyo3-macros-backend/src/module.rs b/pyo3-macros-backend/src/module.rs index 738b69fb..a28550eb 100644 --- a/pyo3-macros-backend/src/module.rs +++ b/pyo3-macros-backend/src/module.rs @@ -120,7 +120,7 @@ pub struct PyFnArgs { } impl Parse for PyFnArgs { - fn parse(input: syn::parse::ParseStream) -> syn::Result { + fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { let modname = input.parse().map_err( |e| err_spanned!(e.span() => "expected module as first argument to #[pyfn()]"), )?; @@ -173,7 +173,7 @@ enum PyModulePyO3Option { } impl Parse for PyModulePyO3Option { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::name) { input.parse().map(PyModulePyO3Option::Name) diff --git a/pyo3-macros-backend/src/pyclass.rs b/pyo3-macros-backend/src/pyclass.rs index e827f8a0..27d90e56 100644 --- a/pyo3-macros-backend/src/pyclass.rs +++ b/pyo3-macros-backend/src/pyclass.rs @@ -38,7 +38,7 @@ pub struct PyClassArgs { } impl PyClassArgs { - fn parse(input: ParseStream, kind: PyClassKind) -> Result { + fn parse(input: ParseStream<'_>, kind: PyClassKind) -> Result { let mut slf = PyClassArgs::new(kind); let vars = Punctuated::::parse_terminated(input)?; for expr in vars { @@ -47,11 +47,11 @@ impl PyClassArgs { Ok(slf) } - pub fn parse_stuct_args(input: ParseStream) -> syn::Result { + pub fn parse_stuct_args(input: ParseStream<'_>) -> syn::Result { Self::parse(input, PyClassKind::Struct) } - pub fn parse_enum_args(input: ParseStream) -> syn::Result { + pub fn parse_enum_args(input: ParseStream<'_>) -> syn::Result { Self::parse(input, PyClassKind::Enum) } @@ -197,7 +197,7 @@ enum PyClassPyO3Option { } impl Parse for PyClassPyO3Option { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::text_signature) { input.parse().map(PyClassPyO3Option::TextSignature) @@ -315,7 +315,7 @@ enum FieldPyO3Option { } impl Parse for FieldPyO3Option { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::get) { input.parse().map(FieldPyO3Option::Get) @@ -478,7 +478,7 @@ pub fn build_py_enum( } fn impl_enum( - enum_: PyClassEnum, + enum_: PyClassEnum<'_>, args: &PyClassArgs, doc: PythonDoc, methods_type: PyClassMethodsType, @@ -489,7 +489,7 @@ fn impl_enum( } fn impl_enum_class( - enum_: PyClassEnum, + enum_: PyClassEnum<'_>, args: &PyClassArgs, doc: PythonDoc, methods_type: PyClassMethodsType, @@ -630,7 +630,7 @@ fn enum_default_slots( gen_default_items(cls, default_items).collect() } -fn extract_variant_data(variant: &syn::Variant) -> syn::Result { +fn extract_variant_data(variant: &syn::Variant) -> syn::Result> { use syn::Fields; let ident = match variant.fields { Fields::Unit => &variant.ident, diff --git a/pyo3-macros-backend/src/pyfunction.rs b/pyo3-macros-backend/src/pyfunction.rs index a45c6a9a..60f7c96f 100644 --- a/pyo3-macros-backend/src/pyfunction.rs +++ b/pyo3-macros-backend/src/pyfunction.rs @@ -50,7 +50,7 @@ enum PyFunctionArgPyO3Attribute { } impl Parse for PyFunctionArgPyO3Attribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::from_py_with) { input.parse().map(PyFunctionArgPyO3Attribute::FromPyWith) @@ -87,7 +87,7 @@ impl PyFunctionArgPyO3Attributes { } impl syn::parse::Parse for PyFunctionSignature { - fn parse(input: &ParseBuffer) -> syn::Result { + fn parse(input: &ParseBuffer<'_>) -> syn::Result { let attr = Punctuated::::parse_terminated(input)?; Self::from_meta(&attr) } @@ -243,7 +243,7 @@ pub struct PyFunctionOptions { } impl Parse for PyFunctionOptions { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let mut options = PyFunctionOptions::default(); while !input.is_empty() { @@ -282,7 +282,7 @@ pub enum PyFunctionOption { } impl Parse for PyFunctionOption { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::name) { input.parse().map(PyFunctionOption::Name) diff --git a/pyo3-macros-backend/src/pyimpl.rs b/pyo3-macros-backend/src/pyimpl.rs index e8f23819..11191db9 100644 --- a/pyo3-macros-backend/src/pyimpl.rs +++ b/pyo3-macros-backend/src/pyimpl.rs @@ -30,7 +30,7 @@ enum PyImplPyO3Option { } impl Parse for PyImplPyO3Option { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(syn::Token![crate]) { input.parse().map(PyImplPyO3Option::Crate) diff --git a/pyo3-macros-backend/src/pymethod.rs b/pyo3-macros-backend/src/pymethod.rs index ef43419e..231e9bec 100644 --- a/pyo3-macros-backend/src/pymethod.rs +++ b/pyo3-macros-backend/src/pymethod.rs @@ -249,7 +249,10 @@ fn ensure_function_options_valid(options: &PyFunctionOptions) -> syn::Result<()> Ok(()) } -fn ensure_no_forbidden_protocol_attributes(spec: &FnSpec, method_name: &str) -> syn::Result<()> { +fn ensure_no_forbidden_protocol_attributes( + spec: &FnSpec<'_>, + method_name: &str, +) -> syn::Result<()> { if let Some(text_signature) = &spec.text_signature { bail_spanned!(text_signature.kw.span() => format!("`text_signature` cannot be used with `{}`", method_name)); } @@ -259,7 +262,7 @@ fn ensure_no_forbidden_protocol_attributes(spec: &FnSpec, method_name: &str) -> /// Also used by pyfunction. pub fn impl_py_method_def( cls: &syn::Type, - spec: &FnSpec, + spec: &FnSpec<'_>, flags: Option, ) -> Result { let wrapper_ident = syn::Ident::new("__wrap", Span::call_site()); @@ -276,7 +279,7 @@ pub fn impl_py_method_def( }) } -fn impl_py_method_def_new(cls: &syn::Type, spec: &FnSpec) -> Result { +fn impl_py_method_def_new(cls: &syn::Type, spec: &FnSpec<'_>) -> Result { let wrapper_ident = syn::Ident::new("__pymethod__new__", Span::call_site()); let wrapper = spec.get_wrapper_function(&wrapper_ident, Some(cls))?; Ok(quote! {{ @@ -291,7 +294,7 @@ fn impl_py_method_def_new(cls: &syn::Type, spec: &FnSpec) -> Result }}) } -fn impl_call_slot(cls: &syn::Type, mut spec: FnSpec) -> Result { +fn impl_call_slot(cls: &syn::Type, mut spec: FnSpec<'_>) -> Result { // HACK: __call__ proto slot must always use varargs calling convention, so change the spec. // Probably indicates there's a refactoring opportunity somewhere. spec.convention = CallingConvention::Varargs; @@ -307,7 +310,7 @@ fn impl_call_slot(cls: &syn::Type, mut spec: FnSpec) -> Result { }}) } -fn impl_traverse_slot(cls: &syn::Type, spec: FnSpec) -> TokenStream { +fn impl_traverse_slot(cls: &syn::Type, spec: FnSpec<'_>) -> TokenStream { let ident = spec.name; quote! {{ pub unsafe extern "C" fn __wrap_( @@ -337,7 +340,7 @@ fn impl_traverse_slot(cls: &syn::Type, spec: FnSpec) -> TokenStream { }} } -fn impl_py_class_attribute(cls: &syn::Type, spec: &FnSpec) -> TokenStream { +fn impl_py_class_attribute(cls: &syn::Type, spec: &FnSpec<'_>) -> TokenStream { let name = &spec.name; let deprecations = &spec.deprecations; let python_name = spec.null_terminated_python_name(); @@ -357,7 +360,7 @@ fn impl_py_class_attribute(cls: &syn::Type, spec: &FnSpec) -> TokenStream { } } -fn impl_call_setter(cls: &syn::Type, spec: &FnSpec) -> syn::Result { +fn impl_call_setter(cls: &syn::Type, spec: &FnSpec<'_>) -> syn::Result { let (py_arg, args) = split_off_python_arg(&spec.args); if args.is_empty() { @@ -380,7 +383,7 @@ fn impl_call_setter(cls: &syn::Type, spec: &FnSpec) -> syn::Result } // Used here for PropertyType::Function, used in pyclass for descriptors. -pub fn impl_py_setter_def(cls: &syn::Type, property_type: PropertyType) -> Result { +pub fn impl_py_setter_def(cls: &syn::Type, property_type: PropertyType<'_>) -> Result { let python_name = property_type.null_terminated_python_name()?; let deprecations = property_type.deprecations(); let doc = property_type.doc(); @@ -443,7 +446,7 @@ pub fn impl_py_setter_def(cls: &syn::Type, property_type: PropertyType) -> Resul }) } -fn impl_call_getter(cls: &syn::Type, spec: &FnSpec) -> syn::Result { +fn impl_call_getter(cls: &syn::Type, spec: &FnSpec<'_>) -> syn::Result { let (py_arg, args) = split_off_python_arg(&spec.args); ensure_spanned!( args.is_empty(), @@ -461,7 +464,7 @@ fn impl_call_getter(cls: &syn::Type, spec: &FnSpec) -> syn::Result } // Used here for PropertyType::Function, used in pyclass for descriptors. -pub fn impl_py_getter_def(cls: &syn::Type, property_type: PropertyType) -> Result { +pub fn impl_py_getter_def(cls: &syn::Type, property_type: PropertyType<'_>) -> Result { let python_name = property_type.null_terminated_python_name()?; let deprecations = property_type.deprecations(); let doc = property_type.doc(); @@ -518,7 +521,7 @@ pub fn impl_py_getter_def(cls: &syn::Type, property_type: PropertyType) -> Resul } /// Split an argument of pyo3::Python from the front of the arg list, if present -fn split_off_python_arg<'a>(args: &'a [FnArg<'a>]) -> (Option<&FnArg>, &[FnArg]) { +fn split_off_python_arg<'a>(args: &'a [FnArg<'a>]) -> (Option<&FnArg<'_>>, &[FnArg<'_>]) { match args { [py, args @ ..] if utils::is_python(py.ty) => (Some(py), args), args => (None, args), @@ -563,7 +566,7 @@ impl PropertyType<'_> { } } - fn doc(&self) -> Cow { + fn doc(&self) -> Cow<'_, PythonDoc> { match self { PropertyType::Descriptor { field, .. } => { Cow::Owned(utils::get_doc(&field.attrs, None)) @@ -712,7 +715,7 @@ impl Ty { cls: &syn::Type, py: &syn::Ident, ident: &syn::Ident, - arg: &FnArg, + arg: &FnArg<'_>, extract_error_mode: ExtractErrorMode, ) -> TokenStream { match self { @@ -911,7 +914,7 @@ impl SlotDef { fn generate_type_slot( &self, cls: &syn::Type, - spec: &FnSpec, + spec: &FnSpec<'_>, method_name: &str, ) -> Result { let SlotDef { @@ -969,7 +972,7 @@ fn generate_method_arguments(arguments: &[Ty]) -> impl Iterator, py: &syn::Ident, arguments: &[Ty], extract_error_mode: ExtractErrorMode, @@ -1022,7 +1025,7 @@ impl SlotFragmentDef { self } - fn generate_pyproto_fragment(&self, cls: &syn::Type, spec: &FnSpec) -> Result { + fn generate_pyproto_fragment(&self, cls: &syn::Type, spec: &FnSpec<'_>) -> Result { let SlotFragmentDef { fragment, arguments, @@ -1111,7 +1114,7 @@ const __RPOW__: SlotFragmentDef = SlotFragmentDef::new("__rpow__", &[Ty::Object, fn extract_proto_arguments( cls: &syn::Type, py: &syn::Ident, - method_args: &[FnArg], + method_args: &[FnArg<'_>], proto_args: &[Ty], extract_error_mode: ExtractErrorMode, ) -> Result<(Vec, usize, TokenStream)> { diff --git a/pyo3-macros-backend/src/utils.rs b/pyo3-macros-backend/src/utils.rs index 9c75239e..86972936 100644 --- a/pyo3-macros-backend/src/utils.rs +++ b/pyo3-macros-backend/src/utils.rs @@ -133,7 +133,7 @@ struct DocArgs { } impl syn::parse::Parse for DocArgs { - fn parse(input: syn::parse::ParseStream) -> syn::Result { + fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { let this = Self { _eq_token: input.parse()?, token_stream: input.parse()?, diff --git a/pyo3-macros-backend/src/wrap.rs b/pyo3-macros-backend/src/wrap.rs index 881d65be..99168a2b 100644 --- a/pyo3-macros-backend/src/wrap.rs +++ b/pyo3-macros-backend/src/wrap.rs @@ -8,7 +8,7 @@ pub struct WrapPyFunctionArgs { } impl Parse for WrapPyFunctionArgs { - fn parse(input: syn::parse::ParseStream) -> syn::Result { + fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result { let function = input.parse()?; let comma_and_arg = if !input.is_empty() { Some((input.parse()?, input.parse()?)) diff --git a/pytests/src/buf_and_str.rs b/pytests/src/buf_and_str.rs index a3721462..b28a24a2 100644 --- a/pytests/src/buf_and_str.rs +++ b/pytests/src/buf_and_str.rs @@ -38,7 +38,7 @@ impl BytesExtractor { } #[pymodule] -pub fn buf_and_str(_py: Python, m: &PyModule) -> PyResult<()> { +pub fn buf_and_str(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_class::()?; Ok(()) } diff --git a/pytests/src/datetime.rs b/pytests/src/datetime.rs index e833e57a..f526ae0a 100644 --- a/pytests/src/datetime.rs +++ b/pytests/src/datetime.rs @@ -7,7 +7,7 @@ use pyo3::types::{ }; #[pyfunction] -fn make_date(py: Python, year: i32, month: u8, day: u8) -> PyResult<&PyDate> { +fn make_date(py: Python<'_>, year: i32, month: u8, day: u8) -> PyResult<&PyDate> { PyDate::new(py, year, month, day) } @@ -20,7 +20,7 @@ fn get_date_tuple<'p>(py: Python<'p>, d: &PyDate) -> &'p PyTuple { } #[pyfunction] -fn date_from_timestamp(py: Python, timestamp: i64) -> PyResult<&PyDate> { +fn date_from_timestamp(py: Python<'_>, timestamp: i64) -> PyResult<&PyDate> { PyDate::from_timestamp(py, timestamp) } @@ -94,7 +94,7 @@ fn get_time_tuple_fold<'p>(py: Python<'p>, dt: &PyTime) -> &'p PyTuple { } #[pyfunction] -fn make_delta(py: Python, days: i32, seconds: i32, microseconds: i32) -> PyResult<&PyDelta> { +fn make_delta(py: Python<'_>, days: i32, seconds: i32, microseconds: i32) -> PyResult<&PyDelta> { PyDelta::new(py, days, seconds, microseconds, true) } diff --git a/pytests/src/lib.rs b/pytests/src/lib.rs index 09549142..7847f0c5 100644 --- a/pytests/src/lib.rs +++ b/pytests/src/lib.rs @@ -14,7 +14,7 @@ pub mod pyfunctions; pub mod subclassing; #[pymodule] -fn pyo3_pytests(py: Python, m: &PyModule) -> PyResult<()> { +fn pyo3_pytests(py: Python<'_>, m: &PyModule) -> PyResult<()> { #[cfg(not(Py_LIMITED_API))] m.add_wrapped(wrap_pymodule!(buf_and_str::buf_and_str))?; #[cfg(not(Py_LIMITED_API))] diff --git a/pytests/src/objstore.rs b/pytests/src/objstore.rs index d68149c7..f7fc66ed 100644 --- a/pytests/src/objstore.rs +++ b/pytests/src/objstore.rs @@ -13,7 +13,7 @@ impl ObjStore { ObjStore::default() } - fn push(&mut self, py: Python, obj: &PyAny) { + fn push(&mut self, py: Python<'_>, obj: &PyAny) { self.obj.push(obj.to_object(py)); } } diff --git a/src/buffer.rs b/src/buffer.rs index dbbf27dc..2835713e 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -38,7 +38,7 @@ unsafe impl Send for PyBuffer {} unsafe impl Sync for PyBuffer {} impl Debug for PyBuffer { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("PyBuffer") .field("buf", &self.0.buf) .field("obj", &self.0.obj) @@ -459,7 +459,7 @@ impl PyBuffer { /// To check whether the buffer format is compatible before calling this method, /// you can use `::is_compatible_format(buf.format())`. /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. - pub fn copy_to_slice(&self, py: Python, target: &mut [T]) -> PyResult<()> { + pub fn copy_to_slice(&self, py: Python<'_>, target: &mut [T]) -> PyResult<()> { self.copy_to_slice_impl(py, target, b'C') } @@ -472,11 +472,11 @@ impl PyBuffer { /// To check whether the buffer format is compatible before calling this method, /// you can use `::is_compatible_format(buf.format())`. /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. - pub fn copy_to_fortran_slice(&self, py: Python, target: &mut [T]) -> PyResult<()> { + pub fn copy_to_fortran_slice(&self, py: Python<'_>, target: &mut [T]) -> PyResult<()> { self.copy_to_slice_impl(py, target, b'F') } - fn copy_to_slice_impl(&self, py: Python, target: &mut [T], fort: u8) -> PyResult<()> { + fn copy_to_slice_impl(&self, py: Python<'_>, target: &mut [T], fort: u8) -> PyResult<()> { if mem::size_of_val(target) != self.len_bytes() { return Err(PyBufferError::new_err(format!( "slice to copy to (of length {}) does not match buffer length of {}", @@ -506,7 +506,7 @@ impl PyBuffer { /// If the buffer is multi-dimensional, the elements are written in C-style order. /// /// Fails if the buffer format is not compatible with type `T`. - pub fn to_vec(&self, py: Python) -> PyResult> { + pub fn to_vec(&self, py: Python<'_>) -> PyResult> { self.to_vec_impl(py, b'C') } @@ -514,11 +514,11 @@ impl PyBuffer { /// If the buffer is multi-dimensional, the elements are written in Fortran-style order. /// /// Fails if the buffer format is not compatible with type `T`. - pub fn to_fortran_vec(&self, py: Python) -> PyResult> { + pub fn to_fortran_vec(&self, py: Python<'_>) -> PyResult> { self.to_vec_impl(py, b'F') } - fn to_vec_impl(&self, py: Python, fort: u8) -> PyResult> { + fn to_vec_impl(&self, py: Python<'_>, fort: u8) -> PyResult> { let item_count = self.item_count(); let mut vec: Vec = Vec::with_capacity(item_count); unsafe { @@ -554,7 +554,7 @@ impl PyBuffer { /// To check whether the buffer format is compatible before calling this method, /// use `::is_compatible_format(buf.format())`. /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. - pub fn copy_from_slice(&self, py: Python, source: &[T]) -> PyResult<()> { + pub fn copy_from_slice(&self, py: Python<'_>, source: &[T]) -> PyResult<()> { self.copy_from_slice_impl(py, source, b'C') } @@ -568,11 +568,11 @@ impl PyBuffer { /// To check whether the buffer format is compatible before calling this method, /// use `::is_compatible_format(buf.format())`. /// Alternatively, `match buffer::ElementType::from_format(buf.format())`. - pub fn copy_from_fortran_slice(&self, py: Python, source: &[T]) -> PyResult<()> { + pub fn copy_from_fortran_slice(&self, py: Python<'_>, source: &[T]) -> PyResult<()> { self.copy_from_slice_impl(py, source, b'F') } - fn copy_from_slice_impl(&self, py: Python, source: &[T], fort: u8) -> PyResult<()> { + fn copy_from_slice_impl(&self, py: Python<'_>, source: &[T], fort: u8) -> PyResult<()> { if self.readonly() { return Err(PyBufferError::new_err("cannot write to read-only buffer")); } else if mem::size_of_val(source) != self.len_bytes() { @@ -607,7 +607,7 @@ impl PyBuffer { } } - pub fn release(self, _py: Python) { + pub fn release(self, _py: Python<'_>) { // First move self into a ManuallyDrop, so that PyBuffer::drop will // never be called. (It would acquire the GIL and call PyBuffer_Release // again.) diff --git a/src/callback.rs b/src/callback.rs index e32def03..3794b9e5 100644 --- a/src/callback.rs +++ b/src/callback.rs @@ -37,7 +37,7 @@ impl PyCallbackOutput for () { /// Convert the result of callback function into the appropriate return value. pub trait IntoPyCallbackOutput { - fn convert(self, py: Python) -> PyResult; + fn convert(self, py: Python<'_>) -> PyResult; } impl IntoPyCallbackOutput for Result @@ -46,7 +46,7 @@ where E: Into, { #[inline] - fn convert(self, py: Python) -> PyResult { + fn convert(self, py: Python<'_>) -> PyResult { self.map_err(Into::into).and_then(|t| t.convert(py)) } } @@ -56,42 +56,42 @@ where T: IntoPy, { #[inline] - fn convert(self, py: Python) -> PyResult<*mut ffi::PyObject> { + fn convert(self, py: Python<'_>) -> PyResult<*mut ffi::PyObject> { Ok(self.into_py(py).into_ptr()) } } impl IntoPyCallbackOutput for *mut ffi::PyObject { #[inline] - fn convert(self, _: Python) -> PyResult { + fn convert(self, _: Python<'_>) -> PyResult { Ok(self) } } impl IntoPyCallbackOutput for () { #[inline] - fn convert(self, _: Python) -> PyResult { + fn convert(self, _: Python<'_>) -> PyResult { Ok(0) } } impl IntoPyCallbackOutput for bool { #[inline] - fn convert(self, _: Python) -> PyResult { + fn convert(self, _: Python<'_>) -> PyResult { Ok(self as c_int) } } impl IntoPyCallbackOutput<()> for () { #[inline] - fn convert(self, _: Python) -> PyResult<()> { + fn convert(self, _: Python<'_>) -> PyResult<()> { Ok(()) } } impl IntoPyCallbackOutput for usize { #[inline] - fn convert(self, _py: Python) -> PyResult { + fn convert(self, _py: Python<'_>) -> PyResult { if self <= (isize::MAX as usize) { Ok(self as isize) } else { @@ -104,14 +104,14 @@ impl IntoPyCallbackOutput for usize { impl IntoPyCallbackOutput for bool { #[inline] - fn convert(self, _: Python) -> PyResult { + fn convert(self, _: Python<'_>) -> PyResult { Ok(self) } } impl IntoPyCallbackOutput for usize { #[inline] - fn convert(self, _: Python) -> PyResult { + fn convert(self, _: Python<'_>) -> PyResult { Ok(self) } } @@ -121,7 +121,7 @@ where T: IntoPy, { #[inline] - fn convert(self, py: Python) -> PyResult { + fn convert(self, py: Python<'_>) -> PyResult { Ok(self.into_py(py)) } } @@ -155,7 +155,7 @@ pub struct HashCallbackOutput(Py_hash_t); impl IntoPyCallbackOutput for HashCallbackOutput { #[inline] - fn convert(self, _py: Python) -> PyResult { + fn convert(self, _py: Python<'_>) -> PyResult { let hash = self.0; if hash == -1 { Ok(-2) @@ -170,14 +170,14 @@ where T: WrappingCastTo, { #[inline] - fn convert(self, _py: Python) -> PyResult { + fn convert(self, _py: Python<'_>) -> PyResult { Ok(HashCallbackOutput(self.wrapping_cast())) } } #[doc(hidden)] #[inline] -pub fn convert(py: Python, value: T) -> PyResult +pub fn convert(py: Python<'_>, value: T) -> PyResult where T: IntoPyCallbackOutput, { @@ -237,7 +237,7 @@ macro_rules! callback_body { #[inline] pub unsafe fn handle_panic(body: F) -> R where - F: FnOnce(Python) -> PyResult + UnwindSafe, + F: for<'py> FnOnce(Python<'py>) -> PyResult + UnwindSafe, R: PyCallbackOutput, { let pool = GILPool::new(); @@ -250,7 +250,7 @@ where #[doc(hidden)] #[inline] pub fn panic_result_into_callback_output( - py: Python, + py: Python<'_>, panic_result: Result, Box>, ) -> R where diff --git a/src/class/buffer.rs b/src/class/buffer.rs index 4cf11d0b..4338b5f6 100644 --- a/src/class/buffer.rs +++ b/src/class/buffer.rs @@ -18,11 +18,15 @@ use std::os::raw::c_int; pub trait PyBufferProtocol<'p>: PyClass { // No default implementations so that implementors of this trait provide both methods. - fn bf_getbuffer(slf: PyRefMut, view: *mut ffi::Py_buffer, flags: c_int) -> Self::Result + fn bf_getbuffer( + slf: PyRefMut<'_, Self>, + view: *mut ffi::Py_buffer, + flags: c_int, + ) -> Self::Result where Self: PyBufferGetBufferProtocol<'p>; - fn bf_releasebuffer(slf: PyRefMut, view: *mut ffi::Py_buffer) -> Self::Result + fn bf_releasebuffer(slf: PyRefMut<'_, Self>, view: *mut ffi::Py_buffer) -> Self::Result where Self: PyBufferReleaseBufferProtocol<'p>; } diff --git a/src/class/gc.rs b/src/class/gc.rs index 34d9fbdd..e9e6ae4f 100644 --- a/src/class/gc.rs +++ b/src/class/gc.rs @@ -11,7 +11,7 @@ pub use crate::impl_::pymethods::{PyTraverseError, PyVisit}; /// GC support #[deprecated(since = "0.16.0", note = "prefer `#[pymethods]` to `#[pyproto]`")] pub trait PyGCProtocol<'p>: PyClass { - fn __traverse__(&'p self, visit: PyVisit) -> Result<(), PyTraverseError>; + fn __traverse__(&'p self, visit: PyVisit<'_>) -> Result<(), PyTraverseError>; fn __clear__(&'p mut self); } diff --git a/src/class/iter.rs b/src/class/iter.rs index 7830db8a..f2562ca6 100644 --- a/src/class/iter.rs +++ b/src/class/iter.rs @@ -17,7 +17,7 @@ use crate::{PyClass, PyObject}; /// the integers 1 to 5, before raising `StopIteration("Ended")`. /// /// ```rust -/// # #![allow(deprecated)] +/// # #![allow(deprecated, elided_lifetimes_in_paths)] /// use pyo3::class::iter::IterNextOutput; /// use pyo3::prelude::*; /// use pyo3::PyIterProtocol; diff --git a/src/conversion.rs b/src/conversion.rs index 276f52d1..6dffae77 100644 --- a/src/conversion.rs +++ b/src/conversion.rs @@ -71,7 +71,7 @@ where /// Conversion trait that allows various objects to be converted into `PyObject`. pub trait ToPyObject { /// Converts self into a Python object. - fn to_object(&self, py: Python) -> PyObject; + fn to_object(&self, py: Python<'_>) -> PyObject; } /// This trait has two implementations: The slow one is implemented for @@ -84,7 +84,7 @@ pub trait ToBorrowedObject: ToPyObject { /// /// May be more efficient than `to_object` because it does not need /// to touch any reference counts when the input object already is a Python object. - fn with_borrowed_ptr(&self, py: Python, f: F) -> R + fn with_borrowed_ptr(&self, py: Python<'_>, f: F) -> R where F: FnOnce(*mut ffi::PyObject) -> R, { @@ -134,7 +134,7 @@ impl ToBorrowedObject for T where T: ToPyObject {} /// } /// /// impl IntoPy for Number { -/// fn into_py(self, py: Python) -> PyObject { +/// fn into_py(self, py: Python<'_>) -> PyObject { /// // delegates to i32's IntoPy implementation. /// self.value.into_py(py) /// } @@ -156,7 +156,7 @@ impl ToBorrowedObject for T where T: ToPyObject {} /// } /// /// impl IntoPy for Value { -/// fn into_py(self, py: Python) -> PyObject { +/// fn into_py(self, py: Python<'_>) -> PyObject { /// match self { /// Self::Integer(val) => val.into_py(py), /// Self::String(val) => val.into_py(py), @@ -181,7 +181,7 @@ impl ToBorrowedObject for T where T: ToPyObject {} #[cfg_attr(docsrs, doc(alias = "IntoPyCallbackOutput"))] pub trait IntoPy: Sized { /// Performs the conversion. - fn into_py(self, py: Python) -> T; + fn into_py(self, py: Python<'_>) -> T; } /// `FromPyObject` is implemented by various types that can be extracted from @@ -218,7 +218,7 @@ pub trait FromPyObject<'source>: Sized { /// `T: ToPyObject` is expected. impl ToPyObject for &'_ T { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { ::to_object(*self, py) } } @@ -229,7 +229,7 @@ impl ToPyObject for Option where T: ToPyObject, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { self.as_ref() .map_or_else(|| py.None(), |val| val.to_object(py)) } @@ -239,20 +239,20 @@ impl IntoPy for Option where T: IntoPy, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.map_or_else(|| py.None(), |val| val.into_py(py)) } } /// `()` is converted to Python `None`. impl ToPyObject for () { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { py.None() } } impl IntoPy for () { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { py.None() } } @@ -262,7 +262,7 @@ where T: AsPyPointer, { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } @@ -343,10 +343,10 @@ pub trait PyTryFrom<'v>: Sized + PyNativeType { /// This trait is similar to `std::convert::TryInto` pub trait PyTryInto: Sized { /// Cast from PyObject to a concrete Python object type. - fn try_into(&self) -> Result<&T, PyDowncastError>; + fn try_into(&self) -> Result<&T, PyDowncastError<'_>>; /// Cast from PyObject to a concrete Python object type. With exact type check. - fn try_into_exact(&self) -> Result<&T, PyDowncastError>; + fn try_into_exact(&self) -> Result<&T, PyDowncastError<'_>>; } // TryFrom implies TryInto @@ -354,10 +354,10 @@ impl PyTryInto for PyAny where U: for<'v> PyTryFrom<'v>, { - fn try_into(&self) -> Result<&U, PyDowncastError> { - U::try_from(self) + fn try_into(&self) -> Result<&U, PyDowncastError<'_>> { + >::try_from(self) } - fn try_into_exact(&self) -> Result<&U, PyDowncastError> { + fn try_into_exact(&self) -> Result<&U, PyDowncastError<'_>> { U::try_from_exact(self) } } @@ -426,7 +426,7 @@ where /// Converts `()` to an empty Python tuple. impl IntoPy> for () { - fn into_py(self, py: Python) -> Py { + fn into_py(self, py: Python<'_>) -> Py { PyTuple::empty(py).into() } } @@ -534,11 +534,11 @@ mod tests { let list: &PyAny = vec![3, 6, 5, 4, 7].to_object(py).into_ref(py); let dict: &PyAny = vec![("reverse", true)].into_py_dict(py).as_ref(); - assert!(PyList::try_from(list).is_ok()); - assert!(PyDict::try_from(dict).is_ok()); + assert!(>::try_from(list).is_ok()); + assert!(>::try_from(dict).is_ok()); - assert!(PyAny::try_from(list).is_ok()); - assert!(PyAny::try_from(dict).is_ok()); + assert!(>::try_from(list).is_ok()); + assert!(>::try_from(dict).is_ok()); }); } diff --git a/src/conversions/array.rs b/src/conversions/array.rs index 7ad5ca39..1b630a8a 100644 --- a/src/conversions/array.rs +++ b/src/conversions/array.rs @@ -9,7 +9,7 @@ mod min_const_generics { where T: ToPyObject, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.as_ref().to_object(py) } } @@ -149,7 +149,7 @@ mod array_impls { where T: ToPyObject { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.as_ref().to_object(py) } } diff --git a/src/conversions/hashbrown.rs b/src/conversions/hashbrown.rs index 31b8b142..da08e6ad 100644 --- a/src/conversions/hashbrown.rs +++ b/src/conversions/hashbrown.rs @@ -33,7 +33,7 @@ where V: ToPyObject, H: hash::BuildHasher, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { IntoPyDict::into_py_dict(self, py).into() } } @@ -44,7 +44,7 @@ where V: IntoPy, H: hash::BuildHasher, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); @@ -72,7 +72,7 @@ impl ToPyObject for hashbrown::HashSet where T: hash::Hash + Eq + ToPyObject, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { let set = PySet::new::(py, &[]).expect("Failed to construct empty set"); { for val in self { @@ -88,7 +88,7 @@ where K: IntoPy + Eq + hash::Hash, S: hash::BuildHasher + Default, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let set = PySet::empty(py).expect("Failed to construct empty set"); { for val in self { diff --git a/src/conversions/indexmap.rs b/src/conversions/indexmap.rs index c7e20e4c..0e18cad7 100644 --- a/src/conversions/indexmap.rs +++ b/src/conversions/indexmap.rs @@ -76,7 +76,7 @@ //! } //! //! #[pymodule] -//! fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +//! fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { //! m.add_function(wrap_pyfunction!(calculate_statistics, m)?)?; //! Ok(()) //! } @@ -102,7 +102,7 @@ where V: ToPyObject, H: hash::BuildHasher, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { IntoPyDict::into_py_dict(self, py).into() } } @@ -113,7 +113,7 @@ where V: IntoPy, H: hash::BuildHasher, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); diff --git a/src/conversions/num_bigint.rs b/src/conversions/num_bigint.rs index f55dc385..b041bc9d 100644 --- a/src/conversions/num_bigint.rs +++ b/src/conversions/num_bigint.rs @@ -40,7 +40,7 @@ //! } //! //! #[pymodule] -//! fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +//! fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { //! m.add_function(wrap_pyfunction!(add_one, m)?)?; //! Ok(()) //! } @@ -82,7 +82,7 @@ macro_rules! bigint_conversion { ($rust_ty: ty, $is_signed: expr, $to_bytes: path, $from_bytes: path) => { #[cfg_attr(docsrs, doc(cfg(feature = "num-bigint")))] impl ToPyObject for $rust_ty { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { let bytes = $to_bytes(self); let obj = ffi::_PyLong_FromByteArray( @@ -98,7 +98,7 @@ macro_rules! bigint_conversion { #[cfg_attr(docsrs, doc(cfg(feature = "num-bigint")))] impl IntoPy for $rust_ty { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) } } @@ -146,7 +146,7 @@ mod tests { use crate::types::{PyDict, PyModule}; use indoc::indoc; - fn python_fib(py: Python) -> &PyModule { + fn python_fib(py: Python<'_>) -> &PyModule { let fib_code = indoc!( r#" def fib(n): @@ -224,7 +224,7 @@ mod tests { }) } - fn python_index_class(py: Python) -> &PyModule { + fn python_index_class(py: Python<'_>) -> &PyModule { let index_code = indoc!( r#" class C: diff --git a/src/conversions/num_complex.rs b/src/conversions/num_complex.rs index 5ad88b65..217d862a 100644 --- a/src/conversions/num_complex.rs +++ b/src/conversions/num_complex.rs @@ -49,7 +49,7 @@ //! } //! //! #[pymodule] -//! fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { +//! fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { //! m.add_function(wrap_pyfunction!(get_eigenvalues, m)?)?; //! Ok(()) //! } @@ -107,7 +107,7 @@ use std::os::raw::c_double; impl PyComplex { /// Creates a new Python `PyComplex` object from `num_complex`'s [`Complex`]. - pub fn from_complex>(py: Python, complex: Complex) -> &PyComplex { + pub fn from_complex>(py: Python<'_>, complex: Complex) -> &PyComplex { unsafe { let ptr = ffi::PyComplex_FromDoubles(complex.re.into(), complex.im.into()); py.from_owned_ptr(ptr) @@ -120,14 +120,14 @@ macro_rules! complex_conversion { #[cfg_attr(docsrs, doc(cfg(feature = "num-complex")))] impl ToPyObject for Complex<$float> { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { crate::IntoPy::::into_py(self.to_owned(), py) } } #[cfg_attr(docsrs, doc(cfg(feature = "num-complex")))] impl crate::IntoPy for Complex<$float> { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { unsafe { let raw_obj = ffi::PyComplex_FromDoubles(self.re as c_double, self.im as c_double); diff --git a/src/conversions/osstr.rs b/src/conversions/osstr.rs index b6282f37..21ad0cab 100644 --- a/src/conversions/osstr.rs +++ b/src/conversions/osstr.rs @@ -11,7 +11,7 @@ use std::ffi::{OsStr, OsString}; use std::os::raw::c_char; impl ToPyObject for OsStr { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { // If the string is UTF-8, take the quick and easy shortcut if let Some(valid_utf8_path) = self.to_str() { return valid_utf8_path.to_object(py); @@ -112,40 +112,40 @@ impl FromPyObject<'_> for OsString { impl IntoPy for &'_ OsStr { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) } } impl ToPyObject for Cow<'_, OsStr> { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { (self as &OsStr).to_object(py) } } impl IntoPy for Cow<'_, OsStr> { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) } } impl ToPyObject for OsString { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { (self as &OsStr).to_object(py) } } impl IntoPy for OsString { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) } } impl<'a> IntoPy for &'a OsString { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) } } @@ -182,7 +182,7 @@ mod tests { #[test] fn test_topyobject_roundtrip() { Python::with_gil(|py| { - fn test_roundtrip + Debug>(py: Python, obj: T) { + fn test_roundtrip + Debug>(py: Python<'_>, obj: T) { let pyobject = obj.to_object(py); let pystring: &PyString = pyobject.extract(py).unwrap(); assert_eq!(pystring.to_string_lossy(), obj.as_ref().to_string_lossy()); @@ -201,7 +201,7 @@ mod tests { fn test_intopy_roundtrip() { Python::with_gil(|py| { fn test_roundtrip + AsRef + Debug + Clone>( - py: Python, + py: Python<'_>, obj: T, ) { let pyobject = obj.clone().into_py(py); diff --git a/src/conversions/path.rs b/src/conversions/path.rs index bd0eca69..a5f04a5d 100644 --- a/src/conversions/path.rs +++ b/src/conversions/path.rs @@ -5,7 +5,7 @@ use std::ffi::OsString; use std::path::{Path, PathBuf}; impl ToPyObject for Path { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { self.as_os_str().to_object(py) } } @@ -34,40 +34,40 @@ impl FromPyObject<'_> for PathBuf { impl<'a> IntoPy for &'a Path { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.as_os_str().to_object(py) } } impl<'a> ToPyObject for Cow<'a, Path> { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { self.as_os_str().to_object(py) } } impl<'a> IntoPy for Cow<'a, Path> { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) } } impl ToPyObject for PathBuf { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { self.as_os_str().to_object(py) } } impl IntoPy for PathBuf { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.into_os_string().to_object(py) } } impl<'a> IntoPy for &'a PathBuf { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.as_os_str().to_object(py) } } @@ -103,7 +103,7 @@ mod tests { #[test] fn test_topyobject_roundtrip() { Python::with_gil(|py| { - fn test_roundtrip + Debug>(py: Python, obj: T) { + fn test_roundtrip + Debug>(py: Python<'_>, obj: T) { let pyobject = obj.to_object(py); let pystring: &PyString = pyobject.extract(py).unwrap(); assert_eq!(pystring.to_string_lossy(), obj.as_ref().to_string_lossy()); @@ -122,7 +122,7 @@ mod tests { fn test_intopy_roundtrip() { Python::with_gil(|py| { fn test_roundtrip + AsRef + Debug + Clone>( - py: Python, + py: Python<'_>, obj: T, ) { let pyobject = obj.clone().into_py(py); diff --git a/src/err/err_state.rs b/src/err/err_state.rs index 97a55ec5..ecebeb5a 100644 --- a/src/err/err_state.rs +++ b/src/err/err_state.rs @@ -15,12 +15,12 @@ pub(crate) struct PyErrStateNormalized { pub(crate) enum PyErrState { LazyTypeAndValue { - ptype: fn(Python) -> &PyType, - pvalue: Box PyObject + Send + Sync>, + ptype: for<'py> fn(Python<'py>) -> &PyType, + pvalue: Box FnOnce(Python<'py>) -> PyObject + Send + Sync>, }, LazyValue { ptype: Py, - pvalue: Box PyObject + Send + Sync>, + pvalue: Box FnOnce(Python<'py>) -> PyObject + Send + Sync>, }, FfiTuple { ptype: PyObject, @@ -33,28 +33,28 @@ pub(crate) enum PyErrState { /// Helper conversion trait that allows to use custom arguments for lazy exception construction. pub trait PyErrArguments: Send + Sync { /// Arguments for exception - fn arguments(self, py: Python) -> PyObject; + fn arguments(self, py: Python<'_>) -> PyObject; } impl PyErrArguments for T where T: IntoPy + Send + Sync, { - fn arguments(self, py: Python) -> PyObject { + fn arguments(self, py: Python<'_>) -> PyObject { self.into_py(py) } } pub(crate) fn boxed_args( args: impl PyErrArguments + 'static, -) -> Box PyObject + Send + Sync> { +) -> Box FnOnce(Python<'py>) -> PyObject + Send + Sync> { Box::new(|py| args.arguments(py)) } impl PyErrState { pub(crate) fn into_ffi_tuple( self, - py: Python, + py: Python<'_>, ) -> (*mut ffi::PyObject, *mut ffi::PyObject, *mut ffi::PyObject) { match self { PyErrState::LazyTypeAndValue { ptype, pvalue } => { @@ -88,7 +88,7 @@ impl PyErrState { } #[inline] - pub(crate) fn exceptions_must_derive_from_base_exception(py: Python) -> Self { + pub(crate) fn exceptions_must_derive_from_base_exception(py: Python<'_>) -> Self { PyErrState::LazyValue { ptype: PyTypeError::type_object(py).into(), pvalue: boxed_args("exceptions must derive from BaseException"), diff --git a/src/err/impls.rs b/src/err/impls.rs index 8731b5ce..4d1b740d 100644 --- a/src/err/impls.rs +++ b/src/err/impls.rs @@ -28,7 +28,7 @@ impl std::convert::From for PyErr { } impl PyErrArguments for io::Error { - fn arguments(self, py: Python) -> PyObject { + fn arguments(self, py: Python<'_>) -> PyObject { self.to_string().into_py(py) } } @@ -42,7 +42,7 @@ impl std::convert::From PyErrArguments for std::io::IntoInnerError { - fn arguments(self, py: Python) -> PyObject { + fn arguments(self, py: Python<'_>) -> PyObject { self.to_string().into_py(py) } } @@ -56,7 +56,7 @@ impl std::convert::From for PyErr { macro_rules! impl_to_pyerr { ($err: ty, $pyexc: ty) => { impl PyErrArguments for $err { - fn arguments(self, py: Python) -> PyObject { + fn arguments(self, py: Python<'_>) -> PyObject { self.to_string().into_py(py) } } diff --git a/src/err/mod.rs b/src/err/mod.rs index 286c02e0..869ff20a 100644 --- a/src/err/mod.rs +++ b/src/err/mod.rs @@ -214,7 +214,7 @@ impl PyErr { } /// Consumes self to take ownership of the exception value contained in this error. - pub fn into_value(self, py: Python) -> Py { + pub fn into_value(self, py: Python<'_>) -> Py { // NB technically this causes one reference count increase and decrease in quick succession // on pvalue, but it's probably not worth optimizing this right now for the additional code // complexity. @@ -243,7 +243,7 @@ impl PyErr { /// Gets whether an error is present in the Python interpreter's global state. #[inline] - pub fn occurred(_: Python) -> bool { + pub fn occurred(_: Python<'_>) -> bool { unsafe { !ffi::PyErr_Occurred().is_null() } } @@ -256,7 +256,7 @@ impl PyErr { /// Use this function when it is not known if an error should be present. If the error is /// expected to have been set, for example from [`PyErr::occurred`] or by an error return value /// from a C FFI function, use [`PyErr::fetch`]. - pub fn take(py: Python) -> Option { + pub fn take(py: Python<'_>) -> Option { let (ptype, pvalue, ptraceback) = unsafe { let mut ptype: *mut ffi::PyObject = std::ptr::null_mut(); let mut pvalue: *mut ffi::PyObject = std::ptr::null_mut(); @@ -327,7 +327,7 @@ impl PyErr { /// [PyErr::occurred] or by an error return value from a C FFI function. #[cfg_attr(all(debug_assertions, track_caller), track_caller)] #[inline] - pub fn fetch(py: Python) -> PyErr { + pub fn fetch(py: Python<'_>) -> PyErr { const FAILED_TO_FETCH: &str = "attempted to fetch exception but none was set"; match PyErr::take(py) { Some(err) => err, @@ -353,7 +353,7 @@ impl PyErr { /// /// This function will panic if `name` or `doc` cannot be converted to [`CString`]s. pub fn new_type( - py: Python, + py: Python<'_>, name: &str, doc: Option<&str>, base: Option<&PyType>, @@ -393,14 +393,14 @@ impl PyErr { } /// Prints a standard traceback to `sys.stderr`. - pub fn print(&self, py: Python) { + pub fn print(&self, py: Python<'_>) { self.clone_ref(py).restore(py); unsafe { ffi::PyErr_PrintEx(0) } } /// Prints a standard traceback to `sys.stderr`, and sets /// `sys.last_{type,value,traceback}` attributes to this exception's data. - pub fn print_and_set_sys_last_vars(&self, py: Python) { + pub fn print_and_set_sys_last_vars(&self, py: Python<'_>) { self.clone_ref(py).restore(py); unsafe { ffi::PyErr_PrintEx(1) } } @@ -409,7 +409,7 @@ impl PyErr { /// /// If `exc` is a class object, this also returns `true` when `self` is an instance of a subclass. /// If `exc` is a tuple, all exceptions in the tuple (and recursively in subtuples) are searched for a match. - pub fn matches(&self, py: Python, exc: T) -> bool + pub fn matches(&self, py: Python<'_>, exc: T) -> bool where T: ToBorrowedObject, { @@ -420,13 +420,13 @@ impl PyErr { /// Returns true if the current exception is instance of `T`. #[inline] - pub fn is_instance(&self, py: Python, typ: &PyType) -> bool { + pub fn is_instance(&self, py: Python<'_>, typ: &PyType) -> bool { unsafe { ffi::PyErr_GivenExceptionMatches(self.type_ptr(py), typ.as_ptr()) != 0 } } /// Returns true if the current exception is instance of `T`. #[inline] - pub fn is_instance_of(&self, py: Python) -> bool + pub fn is_instance_of(&self, py: Python<'_>) -> bool where T: PyTypeObject, { @@ -436,7 +436,7 @@ impl PyErr { /// Writes the error back to the Python interpreter's global state. /// This is the opposite of `PyErr::fetch()`. #[inline] - pub fn restore(self, py: Python) { + pub fn restore(self, py: Python<'_>) { let (ptype, pvalue, ptraceback) = self .state .into_inner() @@ -447,7 +447,7 @@ impl PyErr { /// Issues a warning message. /// May return a `PyErr` if warnings-as-errors is enabled. - pub fn warn(py: Python, category: &PyAny, message: &str, stacklevel: i32) -> PyResult<()> { + pub fn warn(py: Python<'_>, category: &PyAny, message: &str, stacklevel: i32) -> PyResult<()> { let message = CString::new(message)?; unsafe { error_on_minusone( @@ -478,20 +478,20 @@ impl PyErr { /// }); /// ``` #[inline] - pub fn clone_ref(&self, py: Python) -> PyErr { + pub fn clone_ref(&self, py: Python<'_>) -> PyErr { PyErr::from_state(PyErrState::Normalized(self.normalized(py).clone())) } /// Return the cause (either an exception instance, or None, set by `raise ... from ...`) /// associated with the exception, as accessible from Python through `__cause__`. - pub fn cause(&self, py: Python) -> Option { + pub fn cause(&self, py: Python<'_>) -> Option { let ptr = unsafe { ffi::PyException_GetCause(self.value(py).as_ptr()) }; let obj = unsafe { py.from_owned_ptr_or_opt::(ptr) }; obj.map(Self::from_value) } /// Set the cause associated with the exception, pass `None` to clear it. - pub fn set_cause(&self, py: Python, cause: Option) { + pub fn set_cause(&self, py: Python<'_>, cause: Option) { unsafe { // PyException_SetCause _steals_ a reference to cause, so must use .into_ptr() ffi::PyException_SetCause( @@ -509,7 +509,7 @@ impl PyErr { } /// Returns borrowed reference to this Err's type - fn type_ptr(&self, py: Python) -> *mut ffi::PyObject { + fn type_ptr(&self, py: Python<'_>) -> *mut ffi::PyObject { match unsafe { &*self.state.get() } { // In lazy type case, normalize before returning ptype in case the type is not a valid // exception type. @@ -522,7 +522,7 @@ impl PyErr { } #[inline] - fn normalized(&self, py: Python) -> &PyErrStateNormalized { + fn normalized(&self, py: Python<'_>) -> &PyErrStateNormalized { if let Some(PyErrState::Normalized(n)) = unsafe { // Safety: self.state will never be written again once normalized. &*self.state.get() @@ -534,7 +534,7 @@ impl PyErr { } #[cold] - fn make_normalized(&self, py: Python) -> &PyErrStateNormalized { + fn make_normalized(&self, py: Python<'_>) -> &PyErrStateNormalized { // This process is safe because: // - Access is guaranteed not to be concurrent thanks to `Python` GIL token // - Write happens only once, and then never will change again. @@ -611,13 +611,13 @@ impl PyErr { since = "0.16.0", note = "Use err.into_value(py) instead of err.into_instance(py)" )] - pub fn into_instance(self, py: Python) -> Py { + pub fn into_instance(self, py: Python<'_>) -> Py { self.into_value(py) } } impl std::fmt::Debug for PyErr { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { Python::with_gil(|py| { f.debug_struct("PyErr") .field("type", self.get_type(py)) @@ -629,7 +629,7 @@ impl std::fmt::Debug for PyErr { } impl std::fmt::Display for PyErr { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Python::with_gil(|py| { let value = self.value(py); let type_name = value.get_type().name().map_err(|_| std::fmt::Error)?; @@ -646,26 +646,26 @@ impl std::fmt::Display for PyErr { impl std::error::Error for PyErr {} impl IntoPy for PyErr { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.into_value(py).into() } } impl ToPyObject for PyErr { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { self.clone_ref(py).into_py(py) } } impl<'a> IntoPy for &'a PyErr { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.clone_ref(py).into_py(py) } } /// Convert `PyDowncastError` to Python `TypeError`. impl<'a> std::convert::From> for PyErr { - fn from(err: PyDowncastError) -> PyErr { + fn from(err: PyDowncastError<'_>) -> PyErr { exceptions::PyTypeError::new_err(err.to_string()) } } @@ -673,7 +673,7 @@ impl<'a> std::convert::From> for PyErr { impl<'a> std::error::Error for PyDowncastError<'a> {} impl<'a> std::fmt::Display for PyDowncastError<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { write!( f, "'{}' object cannot be converted to '{}'", @@ -683,7 +683,7 @@ impl<'a> std::fmt::Display for PyDowncastError<'a> { } } -pub fn panic_after_error(_py: Python) -> ! { +pub fn panic_after_error(_py: Python<'_>) -> ! { unsafe { ffi::PyErr_Print(); } @@ -692,7 +692,7 @@ pub fn panic_after_error(_py: Python) -> ! { /// Returns Ok if the error code is not -1. #[inline] -pub fn error_on_minusone(py: Python, result: c_int) -> PyResult<()> { +pub fn error_on_minusone(py: Python<'_>, result: c_int) -> PyResult<()> { if result != -1 { Ok(()) } else { @@ -701,7 +701,7 @@ pub fn error_on_minusone(py: Python, result: c_int) -> PyResult<()> { } #[inline] -fn exceptions_must_derive_from_base_exception(py: Python) -> PyErr { +fn exceptions_must_derive_from_base_exception(py: Python<'_>) -> PyErr { PyErr::from_state(PyErrState::exceptions_must_derive_from_base_exception(py)) } diff --git a/src/exceptions.rs b/src/exceptions.rs index e7335f81..d8d65de5 100644 --- a/src/exceptions.rs +++ b/src/exceptions.rs @@ -98,7 +98,7 @@ macro_rules! import_exception { ); impl $name { - fn type_object_raw(py: $crate::Python) -> *mut $crate::ffi::PyTypeObject { + fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { use $crate::once_cell::GILOnceCell; use $crate::AsPyPointer; static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> = @@ -151,7 +151,7 @@ macro_rules! import_exception { /// } /// /// #[pymodule] -/// fn my_module(py: Python, m: &PyModule) -> PyResult<()> { +/// fn my_module(py: Python<'_>, m: &PyModule) -> PyResult<()> { /// m.add("MyError", py.get_type::())?; /// m.add_function(wrap_pyfunction!(raise_myerror, py)?)?; /// Ok(()) @@ -231,7 +231,7 @@ macro_rules! create_exception_type_object { ); impl $name { - fn type_object_raw(py: $crate::Python) -> *mut $crate::ffi::PyTypeObject { + fn type_object_raw(py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { use $crate::once_cell::GILOnceCell; use $crate::AsPyPointer; static TYPE_OBJECT: GILOnceCell<$crate::Py<$crate::types::PyType>> = diff --git a/src/gil.rs b/src/gil.rs index ebc75a50..111e8215 100644 --- a/src/gil.rs +++ b/src/gil.rs @@ -164,7 +164,7 @@ pub struct GILGuard { impl GILGuard { /// Retrieves the marker type that proves that the GIL was acquired. #[inline] - pub fn python(&self) -> Python { + pub fn python(&self) -> Python<'_> { unsafe { Python::assume_gil_acquired() } } @@ -298,7 +298,7 @@ impl ReferencePool { self.dirty.store(true, atomic::Ordering::Release); } - fn update_counts(&self, _py: Python) { + fn update_counts(&self, _py: Python<'_>) { let prev = self.dirty.swap(false, atomic::Ordering::Acquire); if !prev { return; @@ -360,7 +360,7 @@ impl GILPool { /// Gets the Python token associated with this [`GILPool`]. #[inline] - pub fn python(&self) -> Python { + pub fn python(&self) -> Python<'_> { unsafe { Python::assume_gil_acquired() } } } @@ -424,7 +424,7 @@ pub unsafe fn register_decref(obj: NonNull) { /// /// # Safety /// The object must be an owned Python reference. -pub unsafe fn register_owned(_py: Python, obj: NonNull) { +pub unsafe fn register_owned(_py: Python<'_>, obj: NonNull) { debug_assert!(gil_is_acquired()); // Ignores the error in case this function called from `atexit`. let _ = OWNED_OBJECTS.try_with(|holder| holder.borrow_mut().push(obj)); @@ -483,7 +483,7 @@ impl EnsureGIL { /// Thus this method could be used to get access to a GIL token while the GIL is not held. /// Care should be taken to only use the returned Python in contexts where it is certain the /// GIL continues to be held. - pub unsafe fn python(&self) -> Python { + pub unsafe fn python(&self) -> Python<'_> { match &self.0 { Some(gil) => gil.python(), None => Python::assume_gil_acquired(), @@ -497,7 +497,7 @@ mod tests { use crate::{ffi, gil, AsPyPointer, IntoPyPointer, PyObject, Python, ToPyObject}; use std::ptr::NonNull; - fn get_object(py: Python) -> PyObject { + fn get_object(py: Python<'_>) -> PyObject { // Convenience function for getting a single unique object, using `new_pool` so as to leave // the original pool state unchanged. let pool = unsafe { py.new_pool() }; diff --git a/src/impl_/extract_argument.rs b/src/impl_/extract_argument.rs index 481003a6..b793deef 100644 --- a/src/impl_/extract_argument.rs +++ b/src/impl_/extract_argument.rs @@ -101,7 +101,7 @@ pub fn from_py_with_with_default<'py, T>( /// single string.) #[doc(hidden)] #[cold] -pub fn argument_extraction_error(py: Python, arg_name: &str, error: PyErr) -> PyErr { +pub fn argument_extraction_error(py: Python<'_>, arg_name: &str, error: PyErr) -> PyErr { if error.get_type(py).is(PyTypeError::type_object(py)) { let remapped_error = PyTypeError::new_err(format!("argument '{}': {}", arg_name, error.value(py))); diff --git a/src/impl_/frompyobject.rs b/src/impl_/frompyobject.rs index 9d859de9..8c0db798 100644 --- a/src/impl_/frompyobject.rs +++ b/src/impl_/frompyobject.rs @@ -2,7 +2,7 @@ use crate::{exceptions::PyTypeError, PyErr, Python}; #[cold] pub fn failed_to_extract_enum( - py: Python, + py: Python<'_>, type_name: &str, variant_names: &[&str], error_names: &[&str], diff --git a/src/impl_/pyclass.rs b/src/impl_/pyclass.rs index 8f3f8942..d06db820 100644 --- a/src/impl_/pyclass.rs +++ b/src/impl_/pyclass.rs @@ -32,7 +32,7 @@ pub trait PyClassDict { fn new() -> Self; /// Empties the dictionary of its key-value pairs. #[inline] - fn clear_dict(&mut self, _py: Python) {} + fn clear_dict(&mut self, _py: Python<'_>) {} private_decl! {} } @@ -46,7 +46,7 @@ pub trait PyClassWeakRef { /// - `_obj` must be a pointer to the pyclass instance which contains `self`. /// - The GIL must be held. #[inline] - unsafe fn clear_weakrefs(&mut self, _obj: *mut ffi::PyObject, _py: Python) {} + unsafe fn clear_weakrefs(&mut self, _obj: *mut ffi::PyObject, _py: Python<'_>) {} private_decl! {} } @@ -82,7 +82,7 @@ impl PyClassDict for PyClassDictSlot { Self(std::ptr::null_mut()) } #[inline] - fn clear_dict(&mut self, _py: Python) { + fn clear_dict(&mut self, _py: Python<'_>) { if !self.0.is_null() { unsafe { ffi::PyDict_Clear(self.0) } } @@ -102,7 +102,7 @@ impl PyClassWeakRef for PyClassWeakRefSlot { Self(std::ptr::null_mut()) } #[inline] - unsafe fn clear_weakrefs(&mut self, obj: *mut ffi::PyObject, _py: Python) { + unsafe fn clear_weakrefs(&mut self, obj: *mut ffi::PyObject, _py: Python<'_>) { if !self.0.is_null() { ffi::PyObject_ClearWeakRefs(obj) } @@ -205,7 +205,7 @@ slot_fragment_trait! { #[inline] unsafe fn __getattribute__( self, - py: Python, + py: Python<'_>, slf: *mut ffi::PyObject, attr: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { @@ -225,7 +225,7 @@ slot_fragment_trait! { #[inline] unsafe fn __getattr__( self, - py: Python, + py: Python<'_>, _slf: *mut ffi::PyObject, attr: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { @@ -299,7 +299,7 @@ macro_rules! define_pyclass_setattr_slot { #[inline] unsafe fn $set( self, - _py: Python, + _py: Python<'_>, _slf: *mut ffi::PyObject, _attr: *mut ffi::PyObject, _value: NonNull, @@ -315,7 +315,7 @@ macro_rules! define_pyclass_setattr_slot { #[inline] unsafe fn $del( self, - _py: Python, + _py: Python<'_>, _slf: *mut ffi::PyObject, _attr: *mut ffi::PyObject, ) -> PyResult<()> { @@ -416,7 +416,7 @@ macro_rules! define_pyclass_binary_operator_slot { #[inline] unsafe fn $lhs( self, - _py: Python, + _py: Python<'_>, _slf: *mut ffi::PyObject, _other: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { @@ -431,7 +431,7 @@ macro_rules! define_pyclass_binary_operator_slot { #[inline] unsafe fn $rhs( self, - _py: Python, + _py: Python<'_>, _slf: *mut ffi::PyObject, _other: *mut ffi::PyObject, ) -> PyResult<*mut ffi::PyObject> { @@ -611,7 +611,7 @@ slot_fragment_trait! { #[inline] unsafe fn __pow__( self, - _py: Python, + _py: Python<'_>, _slf: *mut ffi::PyObject, _other: *mut ffi::PyObject, _mod: *mut ffi::PyObject, @@ -627,7 +627,7 @@ slot_fragment_trait! { #[inline] unsafe fn __rpow__( self, - _py: Python, + _py: Python<'_>, _slf: *mut ffi::PyObject, _other: *mut ffi::PyObject, _mod: *mut ffi::PyObject, @@ -675,7 +675,7 @@ pub use generate_pyclass_pow_slot; /// Do not implement this trait manually. Instead, use `#[pyclass(freelist = N)]` /// on a Rust struct to implement it. pub trait PyClassWithFreeList: PyClass { - fn get_free_list(py: Python) -> &mut FreeList<*mut ffi::PyObject>; + fn get_free_list(py: Python<'_>) -> &mut FreeList<*mut ffi::PyObject>; } /// Implementation of tp_alloc for `freelist` classes. @@ -737,7 +737,7 @@ pub unsafe extern "C" fn free_with_freelist(obj: *mut c_ /// Workaround for Python issue 35810; no longer necessary in Python 3.8 #[inline] #[cfg(not(Py_3_8))] -unsafe fn bpo_35810_workaround(_py: Python, ty: *mut ffi::PyTypeObject) { +unsafe fn bpo_35810_workaround(_py: Python<'_>, ty: *mut ffi::PyTypeObject) { #[cfg(Py_LIMITED_API)] { // Must check version at runtime for abi3 wheels - they could run against a higher version diff --git a/src/impl_/pymodule.rs b/src/impl_/pymodule.rs index c88f313c..41f89294 100644 --- a/src/impl_/pymodule.rs +++ b/src/impl_/pymodule.rs @@ -15,7 +15,7 @@ pub struct ModuleDef { } /// Wrapper to enable initializer to be used in const fns. -pub struct ModuleInitializer(pub fn(Python, &PyModule) -> PyResult<()>); +pub struct ModuleInitializer(pub for<'py> fn(Python<'py>, &PyModule) -> PyResult<()>); unsafe impl Sync for ModuleDef {} @@ -53,7 +53,7 @@ impl ModuleDef { } } /// Builds a module using user given initializer. Used for [`#[pymodule]`][crate::pymodule]. - pub fn make_module(&'static self, py: Python) -> PyResult { + pub fn make_module(&'static self, py: Python<'_>) -> PyResult { let module = unsafe { Py::::from_owned_ptr_or_err(py, ffi::PyModule_Create(self.ffi_def.get()))? }; @@ -154,7 +154,7 @@ mod tests { static INIT_CALLED: AtomicBool = AtomicBool::new(false); #[allow(clippy::unnecessary_wraps)] - fn init(_: Python, _: &PyModule) -> PyResult<()> { + fn init(_: Python<'_>, _: &PyModule) -> PyResult<()> { INIT_CALLED.store(true, Ordering::SeqCst); Ok(()) } diff --git a/src/instance.rs b/src/instance.rs index 773d6251..a1ec8a9f 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -24,7 +24,7 @@ use std::ptr::NonNull; pub unsafe trait PyNativeType: Sized { /// Returns a GIL marker constrained to the lifetime of this type. #[inline] - fn py(&self) -> Python { + fn py(&self) -> Python<'_> { unsafe { Python::assume_gil_acquired() } } /// Cast `&PyAny` to `&Self` without no type checking. @@ -251,7 +251,7 @@ where /// # Ok(()) /// # } /// ``` - pub fn new(py: Python, value: impl Into>) -> PyResult> { + pub fn new(py: Python<'_>, value: impl Into>) -> PyResult> { let initializer = value.into(); let obj = initializer.create_cell(py)?; let ob = unsafe { Py::from_owned_ptr(py, obj as _) }; @@ -351,7 +351,7 @@ where /// obj.into_ref(py) /// } /// ``` - pub fn into_ref(self, py: Python) -> &T::AsRefTarget { + pub fn into_ref(self, py: Python<'_>) -> &T::AsRefTarget { unsafe { py.from_owned_ptr(self.into_ptr()) } } } @@ -474,7 +474,7 @@ impl Py { /// Gets the reference count of the `ffi::PyObject` pointer. #[inline] - pub fn get_refcnt(&self, _py: Python) -> isize { + pub fn get_refcnt(&self, _py: Python<'_>) -> isize { unsafe { ffi::Py_REFCNT(self.0.as_ptr()) } } @@ -502,21 +502,21 @@ impl Py { /// # } /// ``` #[inline] - pub fn clone_ref(&self, py: Python) -> Py { + pub fn clone_ref(&self, py: Python<'_>) -> Py { unsafe { Py::from_borrowed_ptr(py, self.0.as_ptr()) } } /// Returns whether the object is considered to be None. /// /// This is equivalent to the Python expression `self is None`. - pub fn is_none(&self, _py: Python) -> bool { + pub fn is_none(&self, _py: Python<'_>) -> bool { unsafe { ffi::Py_None() == self.as_ptr() } } /// Returns whether the object is considered to be true. /// /// This is equivalent to the Python expression `bool(self)`. - pub fn is_true(&self, py: Python) -> PyResult { + pub fn is_true(&self, py: Python<'_>) -> PyResult { let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) }; err::error_on_minusone(py, v)?; Ok(v != 0) @@ -535,7 +535,7 @@ impl Py { /// Retrieves an attribute value. /// /// This is equivalent to the Python expression `self.attr_name`. - pub fn getattr(&self, py: Python, attr_name: N) -> PyResult + pub fn getattr(&self, py: Python<'_>, attr_name: N) -> PyResult where N: ToPyObject, { @@ -547,7 +547,7 @@ impl Py { /// Sets an attribute value. /// /// This is equivalent to the Python expression `self.attr_name = value`. - pub fn setattr(&self, py: Python, attr_name: N, value: V) -> PyResult<()> + pub fn setattr(&self, py: Python<'_>, attr_name: N, value: V) -> PyResult<()> where N: ToPyObject, V: ToPyObject, @@ -564,7 +564,7 @@ impl Py { /// This is equivalent to the Python expression `self(*args, **kwargs)`. pub fn call( &self, - py: Python, + py: Python<'_>, args: impl IntoPy>, kwargs: Option<&PyDict>, ) -> PyResult { @@ -583,14 +583,14 @@ impl Py { /// Calls the object with only positional arguments. /// /// This is equivalent to the Python expression `self(*args)`. - pub fn call1(&self, py: Python, args: impl IntoPy>) -> PyResult { + pub fn call1(&self, py: Python<'_>, args: impl IntoPy>) -> PyResult { self.call(py, args, None) } /// Calls the object without arguments. /// /// This is equivalent to the Python expression `self()`. - pub fn call0(&self, py: Python) -> PyResult { + pub fn call0(&self, py: Python<'_>) -> PyResult { cfg_if::cfg_if! { if #[cfg(all(Py_3_9, not(PyPy)))] { // Optimized path on python 3.9+ @@ -608,7 +608,7 @@ impl Py { /// This is equivalent to the Python expression `self.name(*args, **kwargs)`. pub fn call_method( &self, - py: Python, + py: Python<'_>, name: &str, args: impl IntoPy>, kwargs: Option<&PyDict>, @@ -633,7 +633,7 @@ impl Py { /// This is equivalent to the Python expression `self.name(*args)`. pub fn call_method1( &self, - py: Python, + py: Python<'_>, name: &str, args: impl IntoPy>, ) -> PyResult { @@ -643,7 +643,7 @@ impl Py { /// Calls a method on the object with no arguments. /// /// This is equivalent to the Python expression `self.name()`. - pub fn call_method0(&self, py: Python, name: &str) -> PyResult { + pub fn call_method0(&self, py: Python<'_>, name: &str) -> PyResult { cfg_if::cfg_if! { if #[cfg(all(Py_3_9, not(any(Py_LIMITED_API, PyPy))))] { // Optimized path on python 3.9+ @@ -668,7 +668,7 @@ impl Py { /// # Panics /// Panics if `ptr` is null. #[inline] - pub unsafe fn from_owned_ptr(py: Python, ptr: *mut ffi::PyObject) -> Py { + pub unsafe fn from_owned_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> Py { match NonNull::new(ptr) { Some(nonnull_ptr) => Py(nonnull_ptr, PhantomData), None => crate::err::panic_after_error(py), @@ -682,7 +682,10 @@ impl Py { /// # Safety /// If non-null, `ptr` must be a pointer to a Python object of type T. #[inline] - pub unsafe fn from_owned_ptr_or_err(py: Python, ptr: *mut ffi::PyObject) -> PyResult> { + pub unsafe fn from_owned_ptr_or_err( + py: Python<'_>, + ptr: *mut ffi::PyObject, + ) -> PyResult> { match NonNull::new(ptr) { Some(nonnull_ptr) => Ok(Py(nonnull_ptr, PhantomData)), None => Err(PyErr::fetch(py)), @@ -696,7 +699,7 @@ impl Py { /// # Safety /// If non-null, `ptr` must be a pointer to a Python object of type T. #[inline] - pub unsafe fn from_owned_ptr_or_opt(_py: Python, ptr: *mut ffi::PyObject) -> Option { + pub unsafe fn from_owned_ptr_or_opt(_py: Python<'_>, ptr: *mut ffi::PyObject) -> Option { NonNull::new(ptr).map(|nonnull_ptr| Py(nonnull_ptr, PhantomData)) } @@ -708,7 +711,7 @@ impl Py { /// # Panics /// Panics if `ptr` is null. #[inline] - pub unsafe fn from_borrowed_ptr(py: Python, ptr: *mut ffi::PyObject) -> Py { + pub unsafe fn from_borrowed_ptr(py: Python<'_>, ptr: *mut ffi::PyObject) -> Py { match Self::from_borrowed_ptr_or_opt(py, ptr) { Some(slf) => slf, None => crate::err::panic_after_error(py), @@ -722,7 +725,10 @@ impl Py { /// # Safety /// `ptr` must be a pointer to a Python object of type T. #[inline] - pub unsafe fn from_borrowed_ptr_or_err(py: Python, ptr: *mut ffi::PyObject) -> PyResult { + pub unsafe fn from_borrowed_ptr_or_err( + py: Python<'_>, + ptr: *mut ffi::PyObject, + ) -> PyResult { Self::from_borrowed_ptr_or_opt(py, ptr).ok_or_else(|| PyErr::fetch(py)) } @@ -733,7 +739,10 @@ impl Py { /// # Safety /// `ptr` must be a pointer to a Python object of type T. #[inline] - pub unsafe fn from_borrowed_ptr_or_opt(_py: Python, ptr: *mut ffi::PyObject) -> Option { + pub unsafe fn from_borrowed_ptr_or_opt( + _py: Python<'_>, + ptr: *mut ffi::PyObject, + ) -> Option { NonNull::new(ptr).map(|nonnull_ptr| { ffi::Py_INCREF(ptr); Py(nonnull_ptr, PhantomData) @@ -760,7 +769,7 @@ impl Py { impl ToPyObject for Py { /// Converts `Py` instance -> PyObject. - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } @@ -769,7 +778,7 @@ impl IntoPy for Py { /// Converts a `Py` instance to `PyObject`. /// Consumes `self` without calling `Py_DECREF()`. #[inline] - fn into_py(self, _py: Python) -> PyObject { + fn into_py(self, _py: Python<'_>) -> PyObject { unsafe { PyObject::from_non_null(self.into_non_null()) } } } @@ -811,7 +820,7 @@ where } // `&PyCell` can be converted to `Py` -impl<'a, T> std::convert::From<&PyCell> for Py +impl std::convert::From<&PyCell> for Py where T: PyClass, { @@ -890,13 +899,13 @@ where T: PyTypeInfo, T::AsRefTarget: std::fmt::Display, { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { Python::with_gil(|py| std::fmt::Display::fmt(self.as_ref(py), f)) } } impl std::fmt::Debug for Py { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_tuple("Py").field(&self.0.as_ptr()).finish() } } @@ -914,11 +923,11 @@ impl PyObject { /// /// This can cast only to native Python types, not types implemented in Rust. For a more /// flexible alternative, see [`Py::extract`](struct.Py.html#method.extract). - pub fn cast_as<'p, D>(&'p self, py: Python<'p>) -> Result<&'p D, PyDowncastError> + pub fn cast_as<'p, D>(&'p self, py: Python<'p>) -> Result<&'p D, PyDowncastError<'_>> where D: PyTryFrom<'p>, { - D::try_from(unsafe { py.from_borrowed_ptr::(self.as_ptr()) }) + >::try_from(unsafe { py.from_borrowed_ptr::(self.as_ptr()) }) } } diff --git a/src/lib.rs b/src/lib.rs index aabe363c..0c166ace 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,15 @@ )] // Deny some lints in doctests. // Use `#[allow(...)]` locally to override. -#![doc(test(attr(deny(warnings), allow(unused_variables, unused_assignments))))] +#![doc(test(attr( + deny( + elided_lifetimes_in_paths, + unused_lifetimes, + rust_2021_prelude_collisions, + warnings + ), + allow(unused_variables, unused_assignments) +)))] #![cfg_attr(coverage, feature(no_coverage))] // used in src/test_hygiene.rs //! Rust bindings to the Python interpreter. @@ -160,7 +168,7 @@ //! //! /// A Python module implemented in Rust. //! #[pymodule] -//! fn string_sum(py: Python, m: &PyModule) -> PyResult<()> { +//! fn string_sum(py: Python<'_>, m: &PyModule) -> PyResult<()> { //! m.add_function(wrap_pyfunction!(sum_as_string, m)?)?; //! //! Ok(()) @@ -226,7 +234,7 @@ //! let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'"; //! let user: String = py.eval(code, None, Some(&locals))?.extract()?; //! -//! println!("Hello {}, I'm Python {}", user, version); +//! println!("Hello {}, I'm Python<'_> {}", user, version); //! Ok(()) //! }) //! } diff --git a/src/marker.rs b/src/marker.rs index 583dfdec..5a610264 100644 --- a/src/marker.rs +++ b/src/marker.rs @@ -779,7 +779,7 @@ impl<'py> Python<'py> { /// /// # fn main(){ /// #[pyfunction] - /// fn loop_forever(py: Python) -> PyResult<()> { + /// fn loop_forever(py: Python<'_>) -> PyResult<()> { /// loop { /// // As this loop is infinite it should check for signals every once in a while. /// // Using `?` causes any `PyErr` (potentially containing `KeyboardInterrupt`) diff --git a/src/marshal.rs b/src/marshal.rs index 1f089dfb..343b861d 100644 --- a/src/marshal.rs +++ b/src/marshal.rs @@ -72,7 +72,7 @@ mod tests { }); } - fn equal(_py: Python, a: &impl AsPyPointer, b: &impl AsPyPointer) -> bool { + fn equal(_py: Python<'_>, a: &impl AsPyPointer, b: &impl AsPyPointer) -> bool { unsafe { ffi::PyObject_RichCompareBool(a.as_ptr(), b.as_ptr(), ffi::Py_EQ) != 0 } } } diff --git a/src/once_cell.rs b/src/once_cell.rs index e28a2227..739864c5 100644 --- a/src/once_cell.rs +++ b/src/once_cell.rs @@ -21,7 +21,7 @@ use std::cell::UnsafeCell; /// /// static LIST_CELL: GILOnceCell> = GILOnceCell::new(); /// -/// pub fn get_shared_list(py: Python) -> &PyList { +/// pub fn get_shared_list(py: Python<'_>) -> &PyList { /// LIST_CELL /// .get_or_init(py, || PyList::empty(py).into()) /// .as_ref(py) @@ -42,7 +42,7 @@ impl GILOnceCell { } /// Get a reference to the contained value, or `None` if the cell has not yet been written. - pub fn get(&self, _py: Python) -> Option<&T> { + pub fn get(&self, _py: Python<'_>) -> Option<&T> { // Safe because if the cell has not yet been written, None is returned. unsafe { &*self.0.get() }.as_ref() } @@ -61,7 +61,7 @@ impl GILOnceCell { /// exactly once, even if multiple threads attempt to call `get_or_init` /// 4) if f() can panic but still does not release the GIL, it may be called multiple times, /// but it is guaranteed that f() will never be called concurrently - pub fn get_or_init(&self, py: Python, f: F) -> &T + pub fn get_or_init(&self, py: Python<'_>, f: F) -> &T where F: FnOnce() -> T, { @@ -90,7 +90,7 @@ impl GILOnceCell { /// /// If the cell has already been written, `Err(value)` will be returned containing the new /// value which was not written. - pub fn set(&self, _py: Python, value: T) -> Result<(), T> { + pub fn set(&self, _py: Python<'_>, value: T) -> Result<(), T> { // Safe because GIL is held, so no other thread can be writing to this cell concurrently. let inner = unsafe { &mut *self.0.get() }; if inner.is_some() { diff --git a/src/pycell.rs b/src/pycell.rs index b8b2e395..4a6e2753 100644 --- a/src/pycell.rs +++ b/src/pycell.rs @@ -259,7 +259,7 @@ impl PyCell { /// /// In cases where the value in the cell does not need to be accessed immediately after /// creation, consider [`Py::new`](crate::Py::new) as a more efficient alternative. - pub fn new(py: Python, value: impl Into>) -> PyResult<&Self> { + pub fn new(py: Python<'_>, value: impl Into>) -> PyResult<&Self> { unsafe { let initializer = value.into(); let self_ = initializer.create_cell(py)?; @@ -567,7 +567,7 @@ impl fmt::Debug for PyCell { /// (Child { name: "Caterpillar" }, Parent { basename: "Butterfly" }) /// } /// -/// fn format(slf: PyRef) -> String { +/// fn format(slf: PyRef<'_, Self>) -> String { /// // We can get *mut ffi::PyObject from PyRef /// use pyo3::AsPyPointer; /// let refcnt = unsafe { pyo3::ffi::Py_REFCNT(slf.as_ptr()) }; @@ -589,7 +589,7 @@ pub struct PyRef<'p, T: PyClass> { impl<'p, T: PyClass> PyRef<'p, T> { /// Returns a `Python` token that is bound to the lifetime of the `PyRef`. - pub fn py(&self) -> Python { + pub fn py(&self) -> Python<'_> { unsafe { Python::assume_gil_acquired() } } } @@ -643,7 +643,7 @@ where /// .add_subclass(Base2 { name2: "base2" }) /// .add_subclass(Self { name3: "sub" }) /// } - /// fn name(slf: PyRef) -> String { + /// fn name(slf: PyRef<'_, Self>) -> String { /// let subname = slf.name3; /// let super_ = slf.into_super(); /// format!("{} {} {}", super_.as_ref().name1, super_.name2, subname) @@ -713,7 +713,7 @@ pub struct PyRefMut<'p, T: PyClass> { impl<'p, T: PyClass> PyRefMut<'p, T> { /// Returns a `Python` token that is bound to the lifetime of the `PyRefMut`. - pub fn py(&self) -> Python { + pub fn py(&self) -> Python<'_> { unsafe { Python::assume_gil_acquired() } } } @@ -778,7 +778,7 @@ impl<'p, T: PyClass> Drop for PyRefMut<'p, T> { } impl IntoPy for PyRefMut<'_, T> { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_borrowed_ptr(py, self.inner.as_ptr()) } } } @@ -875,7 +875,7 @@ pub trait PyCellLayout: PyLayout { /// # Safety /// - slf must be a valid pointer to an instance of a T or a subclass. /// - slf must not be used after this call (as it will be freed). - unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python); + unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python<'_>); } impl PyCellLayout for PyCellBase @@ -889,7 +889,7 @@ where fn set_borrow_flag(&self, flag: BorrowFlag) { self.borrow_flag.set(flag) } - unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python) { + unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python<'_>) { // For `#[pyclass]` types which inherit from PyAny, we can just call tp_free if T::type_object_raw(py) == &mut PyBaseObject_Type { return get_tp_free(ffi::Py_TYPE(slf))(slf as _); @@ -921,7 +921,7 @@ where fn set_borrow_flag(&self, flag: BorrowFlag) { self.ob_base.set_borrow_flag(flag) } - unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python) { + unsafe fn tp_dealloc(slf: *mut ffi::PyObject, py: Python<'_>) { // Safety: Python only calls tp_dealloc when no references to the object remain. let cell = &mut *(slf as *mut PyCell); ManuallyDrop::drop(&mut cell.contents.value); diff --git a/src/pyclass.rs b/src/pyclass.rs index c4dfbf9b..083223cd 100644 --- a/src/pyclass.rs +++ b/src/pyclass.rs @@ -38,7 +38,7 @@ fn into_raw(vec: Vec) -> *mut c_void { Box::into_raw(vec.into_boxed_slice()) as _ } -pub(crate) fn create_type_object(py: Python) -> *mut ffi::PyTypeObject +pub(crate) fn create_type_object(py: Python<'_>) -> *mut ffi::PyTypeObject where T: PyClass, { @@ -64,7 +64,7 @@ where #[allow(clippy::too_many_arguments)] unsafe fn create_type_object_impl( - py: Python, + py: Python<'_>, tp_doc: &str, module_name: Option<&str>, name: &str, @@ -210,7 +210,7 @@ unsafe fn create_type_object_impl( } #[cold] -fn type_object_creation_failed(py: Python, e: PyErr, name: &'static str) -> ! { +fn type_object_creation_failed(py: Python<'_>, e: PyErr, name: &'static str) -> ! { e.print(py); panic!("An error occurred while initializing class {}", name) } @@ -479,7 +479,7 @@ pub enum IterNextOutput { pub type PyIterNextOutput = IterNextOutput; impl IntoPyCallbackOutput<*mut ffi::PyObject> for PyIterNextOutput { - fn convert(self, _py: Python) -> PyResult<*mut ffi::PyObject> { + fn convert(self, _py: Python<'_>) -> PyResult<*mut ffi::PyObject> { match self { IterNextOutput::Yield(o) => Ok(o.into_ptr()), IterNextOutput::Return(opt) => Err(crate::exceptions::PyStopIteration::new_err((opt,))), @@ -492,7 +492,7 @@ where T: IntoPy, U: IntoPy, { - fn convert(self, py: Python) -> PyResult { + fn convert(self, py: Python<'_>) -> PyResult { match self { IterNextOutput::Yield(o) => Ok(IterNextOutput::Yield(o.into_py(py))), IterNextOutput::Return(o) => Ok(IterNextOutput::Return(o.into_py(py))), @@ -504,7 +504,7 @@ impl IntoPyCallbackOutput for Option where T: IntoPy, { - fn convert(self, py: Python) -> PyResult { + fn convert(self, py: Python<'_>) -> PyResult { match self { Some(o) => Ok(PyIterNextOutput::Yield(o.into_py(py))), None => Ok(PyIterNextOutput::Return(py.None())), @@ -526,7 +526,7 @@ pub enum IterANextOutput { pub type PyIterANextOutput = IterANextOutput; impl IntoPyCallbackOutput<*mut ffi::PyObject> for PyIterANextOutput { - fn convert(self, _py: Python) -> PyResult<*mut ffi::PyObject> { + fn convert(self, _py: Python<'_>) -> PyResult<*mut ffi::PyObject> { match self { IterANextOutput::Yield(o) => Ok(o.into_ptr()), IterANextOutput::Return(opt) => { @@ -541,7 +541,7 @@ where T: IntoPy, U: IntoPy, { - fn convert(self, py: Python) -> PyResult { + fn convert(self, py: Python<'_>) -> PyResult { match self { IterANextOutput::Yield(o) => Ok(IterANextOutput::Yield(o.into_py(py))), IterANextOutput::Return(o) => Ok(IterANextOutput::Return(o.into_py(py))), @@ -553,7 +553,7 @@ impl IntoPyCallbackOutput for Option where T: IntoPy, { - fn convert(self, py: Python) -> PyResult { + fn convert(self, py: Python<'_>) -> PyResult { match self { Some(o) => Ok(PyIterANextOutput::Yield(o.into_py(py))), None => Ok(PyIterANextOutput::Return(py.None())), diff --git a/src/pyclass_init.rs b/src/pyclass_init.rs index b8b2025b..f7b63fe5 100644 --- a/src/pyclass_init.rs +++ b/src/pyclass_init.rs @@ -22,7 +22,7 @@ pub trait PyObjectInit: Sized { /// - `subtype` must be a valid pointer to a type object of T or a subclass. unsafe fn into_new_object( self, - py: Python, + py: Python<'_>, subtype: *mut PyTypeObject, ) -> PyResult<*mut ffi::PyObject>; private_decl! {} @@ -34,7 +34,7 @@ pub struct PyNativeTypeInitializer(PhantomData); impl PyObjectInit for PyNativeTypeInitializer { unsafe fn into_new_object( self, - py: Python, + py: Python<'_>, subtype: *mut PyTypeObject, ) -> PyResult<*mut ffi::PyObject> { let type_object = T::type_object_raw(py); @@ -197,7 +197,7 @@ impl PyClassInitializer { /// Creates a new PyCell and initializes it. #[doc(hidden)] - pub fn create_cell(self, py: Python) -> PyResult<*mut PyCell> + pub fn create_cell(self, py: Python<'_>) -> PyResult<*mut PyCell> where T: PyClass, { @@ -212,7 +212,7 @@ impl PyClassInitializer { #[doc(hidden)] pub unsafe fn create_cell_from_subtype( self, - py: Python, + py: Python<'_>, subtype: *mut crate::ffi::PyTypeObject, ) -> PyResult<*mut PyCell> where @@ -225,7 +225,7 @@ impl PyClassInitializer { impl PyObjectInit for PyClassInitializer { unsafe fn into_new_object( self, - py: Python, + py: Python<'_>, subtype: *mut PyTypeObject, ) -> PyResult<*mut ffi::PyObject> { /// Layout of a PyCellBase after base new has been called, but the borrow flag has not @@ -302,7 +302,7 @@ where U: Into>, { #[inline] - fn convert(self, _py: Python) -> PyResult> { + fn convert(self, _py: Python<'_>) -> PyResult> { Ok(self.into()) } } diff --git a/src/test_hygiene/pymethods.rs b/src/test_hygiene/pymethods.rs index 2085d3bc..79fd5a3d 100644 --- a/src/test_hygiene/pymethods.rs +++ b/src/test_hygiene/pymethods.rs @@ -114,7 +114,7 @@ impl Dummy { fn __delitem__(&self, key: u32) {} - fn __iter__(_: crate::pycell::PyRef, py: crate::Python) -> crate::Py { + fn __iter__(_: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>) -> crate::Py { crate::Py::new(py, DummyIter {}).unwrap() } @@ -122,7 +122,10 @@ impl Dummy { ::std::option::Option::None } - fn __reversed__(slf: crate::pycell::PyRef, py: crate::Python) -> crate::Py { + fn __reversed__( + slf: crate::pycell::PyRef<'_, Self>, + py: crate::Python<'_>, + ) -> crate::Py { crate::Py::new(py, DummyIter {}).unwrap() } @@ -262,19 +265,19 @@ impl Dummy { fn __ior__(&mut self, other: &Self) {} - fn __neg__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __neg__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } - fn __pos__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __pos__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } - fn __abs__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __abs__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } - fn __invert__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __invert__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } @@ -328,7 +331,7 @@ impl Dummy { // Awaitable Objects ////////////////////// - fn __await__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __await__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } @@ -337,7 +340,10 @@ impl Dummy { // Asynchronous Iterators ////////////////////// - fn __aiter__(slf: crate::pycell::PyRef, py: crate::Python) -> crate::Py { + fn __aiter__( + slf: crate::pycell::PyRef<'_, Self>, + py: crate::Python<'_>, + ) -> crate::Py { crate::Py::new(py, DummyIter {}).unwrap() } @@ -508,7 +514,7 @@ impl Dummy { fn __delitem__(&self, key: u32) {} - fn __iter__(_: crate::pycell::PyRef, py: crate::Python) -> crate::Py { + fn __iter__(_: crate::pycell::PyRef<'_, Self>, py: crate::Python<'_>) -> crate::Py { crate::Py::new(py, DummyIter {}).unwrap() } @@ -516,7 +522,10 @@ impl Dummy { ::std::option::Option::None } - fn __reversed__(slf: crate::pycell::PyRef, py: crate::Python) -> crate::Py { + fn __reversed__( + slf: crate::pycell::PyRef<'_, Self>, + py: crate::Python<'_>, + ) -> crate::Py { crate::Py::new(py, DummyIter {}).unwrap() } @@ -655,19 +664,19 @@ impl Dummy { fn __ior__(&mut self, other: &Self) {} - fn __neg__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __neg__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } - fn __pos__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __pos__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } - fn __abs__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __abs__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } - fn __invert__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __invert__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } @@ -721,7 +730,7 @@ impl Dummy { // Awaitable Objects ////////////////////// - fn __await__(slf: crate::pycell::PyRef) -> crate::pycell::PyRef { + fn __await__(slf: crate::pycell::PyRef<'_, Self>) -> crate::pycell::PyRef<'_, Self> { slf } @@ -730,7 +739,10 @@ impl Dummy { // Asynchronous Iterators ////////////////////// - fn __aiter__(slf: crate::pycell::PyRef, py: crate::Python) -> crate::Py { + fn __aiter__( + slf: crate::pycell::PyRef<'_, Self>, + py: crate::Python<'_>, + ) -> crate::Py { crate::Py::new(py, DummyIter {}).unwrap() } diff --git a/src/test_hygiene/pymodule.rs b/src/test_hygiene/pymodule.rs index ba7718b2..0b37c440 100644 --- a/src/test_hygiene/pymodule.rs +++ b/src/test_hygiene/pymodule.rs @@ -9,13 +9,13 @@ fn do_something(x: i32) -> crate::PyResult { #[crate::pymodule] #[pyo3(crate = "crate")] -fn foo(_py: crate::Python, _m: &crate::types::PyModule) -> crate::PyResult<()> { +fn foo(_py: crate::Python<'_>, _m: &crate::types::PyModule) -> crate::PyResult<()> { ::std::result::Result::Ok(()) } #[crate::pymodule] #[pyo3(crate = "crate")] -fn my_module(_py: crate::Python, m: &crate::types::PyModule) -> crate::PyResult<()> { +fn my_module(_py: crate::Python<'_>, m: &crate::types::PyModule) -> crate::PyResult<()> { m.add_function(crate::wrap_pyfunction!(do_something, m)?)?; m.add_wrapped(crate::wrap_pymodule!(foo))?; diff --git a/src/type_object.rs b/src/type_object.rs index 1022a9d8..b8c2d654 100644 --- a/src/type_object.rs +++ b/src/type_object.rs @@ -52,7 +52,7 @@ pub unsafe trait PyTypeInfo: Sized { type AsRefTarget: PyNativeType; /// PyTypeObject instance for this type. - fn type_object_raw(py: Python) -> *mut ffi::PyTypeObject; + fn type_object_raw(py: Python<'_>) -> *mut ffi::PyTypeObject; /// Checks if `object` is an instance of this type or a subclass of this type. fn is_type_of(object: &PyAny) -> bool { @@ -75,14 +75,14 @@ pub unsafe trait PyTypeInfo: Sized { /// See also [PyTypeInfo::type_object_raw](trait.PyTypeInfo.html#tymethod.type_object_raw). pub unsafe trait PyTypeObject { /// Returns the safe abstraction over the type object. - fn type_object(py: Python) -> &PyType; + fn type_object(py: Python<'_>) -> &PyType; } unsafe impl PyTypeObject for T where T: PyTypeInfo, { - fn type_object(py: Python) -> &PyType { + fn type_object(py: Python<'_>) -> &PyType { unsafe { py.from_borrowed_ptr(Self::type_object_raw(py) as _) } } } @@ -107,7 +107,7 @@ impl LazyStaticType { } } - pub fn get_or_init(&self, py: Python) -> *mut ffi::PyTypeObject { + pub fn get_or_init(&self, py: Python<'_>) -> *mut ffi::PyTypeObject { let type_object = *self.value.get_or_init(py, || create_type_object::(py)); self.ensure_init(py, type_object, T::NAME, &T::for_all_items); type_object @@ -115,7 +115,7 @@ impl LazyStaticType { fn ensure_init( &self, - py: Python, + py: Python<'_>, type_object: *mut ffi::PyTypeObject, name: &str, for_all_items: &dyn Fn(&mut dyn FnMut(&PyClassItems)), @@ -188,7 +188,7 @@ impl LazyStaticType { } fn initialize_tp_dict( - py: Python, + py: Python<'_>, type_object: *mut ffi::PyObject, items: Vec<(&'static std::ffi::CStr, PyObject)>, ) -> PyResult<()> { diff --git a/src/types/any.rs b/src/types/any.rs index 4c217c25..4e13b3e9 100644 --- a/src/types/any.rs +++ b/src/types/any.rs @@ -80,7 +80,7 @@ impl PyAny { /// assert!(any.downcast::().is_err()); /// }); /// ``` - pub fn downcast(&self) -> Result<&T, PyDowncastError> + pub fn downcast(&self) -> Result<&T, PyDowncastError<'_>> where for<'py> T: PyTryFrom<'py>, { @@ -658,11 +658,11 @@ impl PyAny { /// Casts the PyObject to a concrete Python object type. /// /// This can cast only to native Python types, not types implemented in Rust. - pub fn cast_as<'a, D>(&'a self) -> Result<&'a D, PyDowncastError> + pub fn cast_as<'a, D>(&'a self) -> Result<&'a D, PyDowncastError<'_>> where D: PyTryFrom<'a>, { - D::try_from(self) + >::try_from(self) } /// Extracts some type from the Python object. diff --git a/src/types/boolobject.rs b/src/types/boolobject.rs index 4e17e2a5..b7126bc0 100644 --- a/src/types/boolobject.rs +++ b/src/types/boolobject.rs @@ -13,7 +13,7 @@ pyobject_native_type!(PyBool, ffi::PyObject, ffi::PyBool_Type, #checkfunction=ff impl PyBool { /// Depending on `val`, returns `true` or `false`. #[inline] - pub fn new(py: Python, val: bool) -> &PyBool { + pub fn new(py: Python<'_>, val: bool) -> &PyBool { unsafe { py.from_borrowed_ptr(if val { ffi::Py_True() } else { ffi::Py_False() }) } } @@ -27,7 +27,7 @@ impl PyBool { /// Converts a Rust `bool` to a Python `bool`. impl ToPyObject for bool { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_borrowed_ptr( py, @@ -43,7 +43,7 @@ impl ToPyObject for bool { impl IntoPy for bool { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { PyBool::new(py, self).into() } } diff --git a/src/types/bytearray.rs b/src/types/bytearray.rs index a63dd4db..2b713776 100644 --- a/src/types/bytearray.rs +++ b/src/types/bytearray.rs @@ -44,7 +44,7 @@ impl PyByteArray { /// }) /// # } /// ``` - pub fn new_with(py: Python, len: usize, init: F) -> PyResult<&PyByteArray> + pub fn new_with(py: Python<'_>, len: usize, init: F) -> PyResult<&PyByteArray> where F: FnOnce(&mut [u8]) -> PyResult<()>, { diff --git a/src/types/bytes.rs b/src/types/bytes.rs index 96a49960..44bb2fd9 100644 --- a/src/types/bytes.rs +++ b/src/types/bytes.rs @@ -50,7 +50,7 @@ impl PyBytes { /// }) /// # } /// ``` - pub fn new_with(py: Python, len: usize, init: F) -> PyResult<&PyBytes> + pub fn new_with(py: Python<'_>, len: usize, init: F) -> PyResult<&PyBytes> where F: FnOnce(&mut [u8]) -> PyResult<()>, { @@ -125,7 +125,7 @@ impl> Index for PyBytes { } impl<'a> IntoPy for &'a [u8] { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { PyBytes::new(py, self).to_object(py) } } diff --git a/src/types/capsule.rs b/src/types/capsule.rs index 931a5355..8add77b4 100644 --- a/src/types/capsule.rs +++ b/src/types/capsule.rs @@ -167,7 +167,7 @@ impl PyCapsule { /// assert_eq!(rx.recv(), Ok("Destructor called!".to_string())); /// ``` #[allow(clippy::not_unsafe_ptr_arg_deref)] - pub fn set_context(&self, py: Python, context: *mut c_void) -> PyResult<()> { + pub fn set_context(&self, py: Python<'_>, context: *mut c_void) -> PyResult<()> { let result = unsafe { ffi::PyCapsule_SetContext(self.as_ptr(), context) as u8 }; if result != 0 { Err(PyErr::fetch(py)) @@ -178,7 +178,7 @@ impl PyCapsule { /// Gets the current context stored in the capsule. If there is no context, the pointer /// will be null. - pub fn get_context(&self, py: Python) -> PyResult<*mut c_void> { + pub fn get_context(&self, py: Python<'_>) -> PyResult<*mut c_void> { let ctx = unsafe { ffi::PyCapsule_GetContext(self.as_ptr()) }; if ctx.is_null() && self.is_valid() && PyErr::occurred(py) { Err(PyErr::fetch(py)) diff --git a/src/types/cls.rs b/src/types/cls.rs new file mode 100644 index 00000000..7b153428 --- /dev/null +++ b/src/types/cls.rs @@ -0,0 +1,584 @@ +// Copyright (c) 2017-present PyO3 Project and Contributors + +//! Defines conversions between Rust and Python types. +use crate::err::{self, PyDowncastError, PyResult}; +use crate::type_object::PyTypeInfo; +use crate::types::PyTuple; +use crate::{ + ffi, gil, Py, PyAny, PyCell, PyClass, PyNativeType, PyObject, PyRef, PyRefMut, Python, +}; +use std::ptr::NonNull; + +/// This trait represents that **we can do zero-cost conversion from the object +/// to a FFI pointer**. +/// +/// This trait is implemented for types that internally wrap a pointer to a Python object. +/// +/// # Examples +/// +/// ``` +/// use pyo3::{prelude::*, AsPyPointer}; +/// Python::with_gil(|py| { +/// let dict = pyo3::types::PyDict::new(py); +/// // All native object wrappers implement AsPyPointer!!! +/// assert_ne!(dict.as_ptr(), std::ptr::null_mut()); +/// }); +/// ``` +pub trait AsPyPointer { + /// Retrieves the underlying FFI pointer (as a borrowed pointer). + fn as_ptr(&self) -> *mut ffi::PyObject; +} + +/// This trait allows retrieving the underlying FFI pointer from Python objects. +pub trait IntoPyPointer { + /// Retrieves the underlying FFI pointer. Whether pointer owned or borrowed + /// depends on implementation. + fn into_ptr(self) -> *mut ffi::PyObject; +} + +/// Convert `None` into a null pointer. +impl AsPyPointer for Option +where + T: AsPyPointer, +{ + #[inline] + fn as_ptr(&self) -> *mut ffi::PyObject { + self.as_ref() + .map_or_else(std::ptr::null_mut, |t| t.as_ptr()) + } +} + +/// Convert `None` into a null pointer. +impl IntoPyPointer for Option +where + T: IntoPyPointer, +{ + #[inline] + fn into_ptr(self) -> *mut ffi::PyObject { + self.map_or_else(std::ptr::null_mut, |t| t.into_ptr()) + } +} + +impl<'a, T> IntoPyPointer for &'a T +where + T: AsPyPointer, +{ + fn into_ptr(self) -> *mut ffi::PyObject { + unsafe { ffi::_Py_XNewRef(self.as_ptr()) } + } +} + +/// Conversion trait that allows various objects to be converted into `PyObject`. +pub trait ToPyObject { + /// Converts self into a Python object. + fn to_object(&self, py: Python<'_>) -> PyObject; +} + +/// This trait has two implementations: The slow one is implemented for +/// all [ToPyObject] and creates a new object using [ToPyObject::to_object], +/// while the fast one is only implemented for AsPyPointer (we know +/// that every AsPyPointer is also ToPyObject) and uses [AsPyPointer::as_ptr()] +pub trait ToBorrowedObject: ToPyObject { + /// Converts self into a Python object and calls the specified closure + /// on the native FFI pointer underlying the Python object. + /// + /// May be more efficient than `to_object` because it does not need + /// to touch any reference counts when the input object already is a Python object. + fn with_borrowed_ptr(&self, py: Python<'_>, f: F) -> R + where + F: FnOnce(*mut ffi::PyObject) -> R, + { + let ptr = self.to_object(py).into_ptr(); + let result = f(ptr); + unsafe { + ffi::Py_XDECREF(ptr); + } + result + } +} + +impl ToBorrowedObject for T where T: ToPyObject {} + +/// Defines a conversion from a Rust type to a Python object. +/// +/// It functions similarly to std's [`Into`](std::convert::Into) trait, +/// but requires a [GIL token](Python) as an argument. +/// Many functions and traits internal to PyO3 require this trait as a bound, +/// so a lack of this trait can manifest itself in different error messages. +/// +/// # Examples +/// ## With `#[pyclass]` +/// The easiest way to implement `IntoPy` is by exposing a struct as a native Python object +/// by annotating it with [`#[pyclass]`](crate::prelude::pyclass). +/// +/// ```rust +/// use pyo3::prelude::*; +/// +/// #[pyclass] +/// struct Number { +/// #[pyo3(get, set)] +/// value: i32, +/// } +/// ``` +/// Python code will see this as an instance of the `Number` class with a `value` attribute. +/// +/// ## Conversion to a Python object +/// +/// However, it may not be desirable to expose the existence of `Number` to Python code. +/// `IntoPy` allows us to define a conversion to an appropriate Python object. +/// ```rust +/// use pyo3::prelude::*; +/// +/// struct Number { +/// value: i32, +/// } +/// +/// impl IntoPy for Number { +/// fn into_py(self, py: Python<'_>) -> PyObject { +/// // delegates to i32's IntoPy implementation. +/// self.value.into_py(py) +/// } +/// } +/// ``` +/// Python code will see this as an `int` object. +/// +/// ## Dynamic conversion into Python objects. +/// It is also possible to return a different Python object depending on some condition. +/// This is useful for types like enums that can carry different types. +/// +/// ```rust +/// use pyo3::prelude::*; +/// +/// enum Value { +/// Integer(i32), +/// String(String), +/// None, +/// } +/// +/// impl IntoPy for Value { +/// fn into_py(self, py: Python<'_>) -> PyObject { +/// match self { +/// Self::Integer(val) => val.into_py(py), +/// Self::String(val) => val.into_py(py), +/// Self::None => py.None(), +/// } +/// } +/// } +/// # fn main() { +/// # Python::with_gil(|py| { +/// # let v = Value::Integer(73).into_py(py); +/// # let v = v.extract::(py).unwrap(); +/// # +/// # let v = Value::String("foo".into()).into_py(py); +/// # let v = v.extract::(py).unwrap(); +/// # +/// # let v = Value::None.into_py(py); +/// # let v = v.extract::>>(py).unwrap(); +/// # }); +/// # } +/// ``` +/// Python code will see this as any of the `int`, `string` or `None` objects. +#[cfg_attr(docsrs, doc(alias = "IntoPyCallbackOutput"))] +pub trait IntoPy: Sized { + /// Performs the conversion. + fn into_py(self, py: Python<'_>) -> T; +} + +/// `FromPyObject` is implemented by various types that can be extracted from +/// a Python object reference. +/// +/// Normal usage is through the helper methods `Py::extract` or `PyAny::extract`: +/// +/// ```rust,ignore +/// let obj: Py = ...; +/// let value: &TargetType = obj.extract(py)?; +/// +/// let any: &PyAny = ...; +/// let value: &TargetType = any.extract()?; +/// ``` +/// +/// Note: depending on the implementation, the lifetime of the extracted result may +/// depend on the lifetime of the `obj` or the `prepared` variable. +/// +/// For example, when extracting `&str` from a Python byte string, the resulting string slice will +/// point to the existing string data (lifetime: `'source`). +/// On the other hand, when extracting `&str` from a Python Unicode string, the preparation step +/// will convert the string to UTF-8, and the resulting string slice will have lifetime `'prepared`. +/// Since which case applies depends on the runtime type of the Python object, +/// both the `obj` and `prepared` variables must outlive the resulting string slice. +/// +/// The trait's conversion method takes a `&PyAny` argument but is called +/// `FromPyObject` for historical reasons. +pub trait FromPyObject<'source>: Sized { + /// Extracts `Self` from the source `PyObject`. + fn extract(ob: &'source PyAny) -> PyResult; +} + +/// Identity conversion: allows using existing `PyObject` instances where +/// `T: ToPyObject` is expected. +impl ToPyObject for &'_ T { + #[inline] + fn to_object(&self, py: Python<'_>) -> PyObject { + ::to_object(*self, py) + } +} + +/// `Option::Some` is converted like `T`. +/// `Option::None` is converted to Python `None`. +impl ToPyObject for Option +where + T: ToPyObject, +{ + fn to_object(&self, py: Python<'_>) -> PyObject { + self.as_ref() + .map_or_else(|| py.None(), |val| val.to_object(py)) + } +} + +impl IntoPy for Option +where + T: IntoPy, +{ + fn into_py(self, py: Python<'_>) -> PyObject { + self.map_or_else(|| py.None(), |val| val.into_py(py)) + } +} + +/// `()` is converted to Python `None`. +impl ToPyObject for () { + fn to_object(&self, py: Python<'_>) -> PyObject { + py.None() + } +} + +impl IntoPy for () { + fn into_py(self, py: Python<'_>) -> PyObject { + py.None() + } +} + +impl IntoPy for &'_ T +where + T: AsPyPointer, +{ + #[inline] + fn into_py(self, py: Python<'_>) -> PyObject { + unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) } + } +} + +impl<'a, T> FromPyObject<'a> for &'a PyCell +where + T: PyClass, +{ + fn extract(obj: &'a PyAny) -> PyResult { + PyTryFrom::try_from(obj).map_err(Into::into) + } +} + +impl<'a, T> FromPyObject<'a> for T +where + T: PyClass + Clone, +{ + fn extract(obj: &'a PyAny) -> PyResult { + let cell: &PyCell = PyTryFrom::try_from(obj)?; + Ok(unsafe { cell.try_borrow_unguarded()?.clone() }) + } +} + +impl<'a, T> FromPyObject<'a> for PyRef<'a, T> +where + T: PyClass, +{ + fn extract(obj: &'a PyAny) -> PyResult { + let cell: &PyCell = PyTryFrom::try_from(obj)?; + cell.try_borrow().map_err(Into::into) + } +} + +impl<'a, T> FromPyObject<'a> for PyRefMut<'a, T> +where + T: PyClass, +{ + fn extract(obj: &'a PyAny) -> PyResult { + let cell: &PyCell = PyTryFrom::try_from(obj)?; + cell.try_borrow_mut().map_err(Into::into) + } +} + +impl<'a, T> FromPyObject<'a> for Option +where + T: FromPyObject<'a>, +{ + fn extract(obj: &'a PyAny) -> PyResult { + if obj.as_ptr() == unsafe { ffi::Py_None() } { + Ok(None) + } else { + T::extract(obj).map(Some) + } + } +} + +/// Trait implemented by Python object types that allow a checked downcast. +/// If `T` implements `PyTryFrom`, we can convert `&PyAny` to `&T`. +/// +/// This trait is similar to `std::convert::TryFrom` +pub trait PyTryFrom<'v>: Sized + PyNativeType { + /// Cast from a concrete Python object type to PyObject. + fn try_from>(value: V) -> Result<&'v Self, PyDowncastError<'v>>; + + /// Cast from a concrete Python object type to PyObject. With exact type check. + fn try_from_exact>(value: V) -> Result<&'v Self, PyDowncastError<'v>>; + + /// Cast a PyAny to a specific type of PyObject. The caller must + /// have already verified the reference is for this type. + /// + /// # Safety + /// + /// Callers must ensure that the type is valid or risk type confusion. + unsafe fn try_from_unchecked>(value: V) -> &'v Self; +} + +/// Trait implemented by Python object types that allow a checked downcast. +/// This trait is similar to `std::convert::TryInto` +pub trait PyTryInto: Sized { + /// Cast from PyObject to a concrete Python object type. + fn try_into(&self) -> Result<&T, PyDowncastError<'_>>; + + /// Cast from PyObject to a concrete Python object type. With exact type check. + fn try_into_exact(&self) -> Result<&T, PyDowncastError<'_>>; +} + +// TryFrom implies TryInto +impl PyTryInto for PyAny +where + U: for<'v> PyTryFrom<'v>, +{ + fn try_into(&self) -> Result<&U, PyDowncastError<'_>> { + >::try_from(self) + } + fn try_into_exact(&self) -> Result<&U, PyDowncastError<'_>> { + U::try_from_exact(self) + } +} + +impl<'v, T> PyTryFrom<'v> for T +where + T: PyTypeInfo + PyNativeType, +{ + fn try_from>(value: V) -> Result<&'v Self, PyDowncastError<'v>> { + let value = value.into(); + unsafe { + if T::is_type_of(value) { + Ok(Self::try_from_unchecked(value)) + } else { + Err(PyDowncastError::new(value, T::NAME)) + } + } + } + + fn try_from_exact>(value: V) -> Result<&'v Self, PyDowncastError<'v>> { + let value = value.into(); + unsafe { + if T::is_exact_type_of(value) { + Ok(Self::try_from_unchecked(value)) + } else { + Err(PyDowncastError::new(value, T::NAME)) + } + } + } + + #[inline] + unsafe fn try_from_unchecked>(value: V) -> &'v Self { + Self::unchecked_downcast(value.into()) + } +} + +impl<'v, T> PyTryFrom<'v> for PyCell +where + T: 'v + PyClass, +{ + fn try_from>(value: V) -> Result<&'v Self, PyDowncastError<'v>> { + let value = value.into(); + unsafe { + if T::is_type_of(value) { + Ok(Self::try_from_unchecked(value)) + } else { + Err(PyDowncastError::new(value, T::NAME)) + } + } + } + fn try_from_exact>(value: V) -> Result<&'v Self, PyDowncastError<'v>> { + let value = value.into(); + unsafe { + if T::is_exact_type_of(value) { + Ok(Self::try_from_unchecked(value)) + } else { + Err(PyDowncastError::new(value, T::NAME)) + } + } + } + #[inline] + unsafe fn try_from_unchecked>(value: V) -> &'v Self { + Self::unchecked_downcast(value.into()) + } +} + +/// Converts `()` to an empty Python tuple. +impl IntoPy> for () { + fn into_py(self, py: Python<'_>) -> Py { + PyTuple::empty(py).into() + } +} + +/// Raw level conversion between `*mut ffi::PyObject` and PyO3 types. +/// +/// # Safety +/// +/// See safety notes on individual functions. +pub unsafe trait FromPyPointer<'p>: Sized { + /// Convert from an arbitrary `PyObject`. + /// + /// # Safety + /// + /// Implementations must ensure the object does not get freed during `'p` + /// and ensure that `ptr` is of the correct type. + /// Note that it must be safe to decrement the reference count of `ptr`. + unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self>; + /// Convert from an arbitrary `PyObject` or panic. + /// + /// # Safety + /// + /// Relies on [`from_owned_ptr_or_opt`](#method.from_owned_ptr_or_opt). + unsafe fn from_owned_ptr_or_panic(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self { + Self::from_owned_ptr_or_opt(py, ptr).unwrap_or_else(|| err::panic_after_error(py)) + } + /// Convert from an arbitrary `PyObject` or panic. + /// + /// # Safety + /// + /// Relies on [`from_owned_ptr_or_opt`](#method.from_owned_ptr_or_opt). + unsafe fn from_owned_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self { + Self::from_owned_ptr_or_panic(py, ptr) + } + /// Convert from an arbitrary `PyObject`. + /// + /// # Safety + /// + /// Relies on [`from_owned_ptr_or_opt`](#method.from_owned_ptr_or_opt). + unsafe fn from_owned_ptr_or_err(py: Python<'p>, ptr: *mut ffi::PyObject) -> PyResult<&'p Self> { + Self::from_owned_ptr_or_opt(py, ptr).ok_or_else(|| err::PyErr::fetch(py)) + } + /// Convert from an arbitrary borrowed `PyObject`. + /// + /// # Safety + /// + /// Implementations must ensure the object does not get freed during `'p` and avoid type confusion. + unsafe fn from_borrowed_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) + -> Option<&'p Self>; + /// Convert from an arbitrary borrowed `PyObject`. + /// + /// # Safety + /// + /// Relies on unsafe fn [`from_borrowed_ptr_or_opt`](#method.from_borrowed_ptr_or_opt). + unsafe fn from_borrowed_ptr_or_panic(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self { + Self::from_borrowed_ptr_or_opt(py, ptr).unwrap_or_else(|| err::panic_after_error(py)) + } + /// Convert from an arbitrary borrowed `PyObject`. + /// + /// # Safety + /// + /// Relies on unsafe fn [`from_borrowed_ptr_or_opt`](#method.from_borrowed_ptr_or_opt). + unsafe fn from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> &'p Self { + Self::from_borrowed_ptr_or_panic(py, ptr) + } + /// Convert from an arbitrary borrowed `PyObject`. + /// + /// # Safety + /// + /// Relies on unsafe fn [`from_borrowed_ptr_or_opt`](#method.from_borrowed_ptr_or_opt). + unsafe fn from_borrowed_ptr_or_err( + py: Python<'p>, + ptr: *mut ffi::PyObject, + ) -> PyResult<&'p Self> { + Self::from_borrowed_ptr_or_opt(py, ptr).ok_or_else(|| err::PyErr::fetch(py)) + } +} + +unsafe impl<'p, T> FromPyPointer<'p> for T +where + T: 'p + crate::PyNativeType, +{ + unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self> { + gil::register_owned(py, NonNull::new(ptr)?); + Some(&*(ptr as *mut Self)) + } + unsafe fn from_borrowed_ptr_or_opt( + _py: Python<'p>, + ptr: *mut ffi::PyObject, + ) -> Option<&'p Self> { + NonNull::new(ptr as *mut Self).map(|p| &*p.as_ptr()) + } +} + +#[cfg(test)] +mod tests { + use crate::types::{IntoPyDict, PyAny, PyDict, PyList}; + use crate::{AsPyPointer, PyObject, Python, ToPyObject}; + + use super::PyTryFrom; + + #[test] + fn test_try_from() { + Python::with_gil(|py| { + let list: &PyAny = vec![3, 6, 5, 4, 7].to_object(py).into_ref(py); + let dict: &PyAny = vec![("reverse", true)].into_py_dict(py).as_ref(); + + assert!(>::try_from(list).is_ok()); + assert!(>::try_from(dict).is_ok()); + + assert!(>::try_from(list).is_ok()); + assert!(>::try_from(dict).is_ok()); + }); + } + + #[test] + fn test_try_from_exact() { + Python::with_gil(|py| { + let list: &PyAny = vec![3, 6, 5, 4, 7].to_object(py).into_ref(py); + let dict: &PyAny = vec![("reverse", true)].into_py_dict(py).as_ref(); + + assert!(PyList::try_from_exact(list).is_ok()); + assert!(PyDict::try_from_exact(dict).is_ok()); + + assert!(PyAny::try_from_exact(list).is_err()); + assert!(PyAny::try_from_exact(dict).is_err()); + }); + } + + #[test] + fn test_try_from_unchecked() { + Python::with_gil(|py| { + let list = PyList::new(py, &[1, 2, 3]); + let val = unsafe { ::try_from_unchecked(list.as_ref()) }; + assert!(list.is(val)); + }); + } + + #[test] + fn test_option_as_ptr() { + Python::with_gil(|py| { + let mut option: Option = None; + assert_eq!(option.as_ptr(), std::ptr::null_mut()); + + let none = py.None(); + option = Some(none.clone()); + + let ref_cnt = none.get_refcnt(py); + assert_eq!(option.as_ptr(), none.as_ptr()); + + // Ensure ref count not changed by as_ptr call + assert_eq!(none.get_refcnt(py), ref_cnt); + }); + } +} diff --git a/src/types/complex.rs b/src/types/complex.rs index 73313471..415cc5d2 100644 --- a/src/types/complex.rs +++ b/src/types/complex.rs @@ -20,7 +20,7 @@ pyobject_native_type!( impl PyComplex { /// Creates a new `PyComplex` from the given real and imaginary values. - pub fn from_doubles(py: Python, real: c_double, imag: c_double) -> &PyComplex { + pub fn from_doubles(py: Python<'_>, real: c_double, imag: c_double) -> &PyComplex { unsafe { let ptr = ffi::PyComplex_FromDoubles(real, imag); py.from_owned_ptr(ptr) diff --git a/src/types/datetime.rs b/src/types/datetime.rs index f6ca1fda..c4053011 100644 --- a/src/types/datetime.rs +++ b/src/types/datetime.rs @@ -26,7 +26,7 @@ use crate::types::PyTuple; use crate::{AsPyPointer, PyAny, PyObject, Python, ToPyObject}; use std::os::raw::c_int; -fn ensure_datetime_api(_py: Python) -> &'static PyDateTime_CAPI { +fn ensure_datetime_api(_py: Python<'_>) -> &'static PyDateTime_CAPI { unsafe { if pyo3_ffi::PyDateTimeAPI().is_null() { PyDateTime_IMPORT() @@ -173,7 +173,7 @@ pyobject_native_type!( impl PyDate { /// Creates a new `datetime.date`. - pub fn new(py: Python, year: i32, month: u8, day: u8) -> PyResult<&PyDate> { + pub fn new(py: Python<'_>, year: i32, month: u8, day: u8) -> PyResult<&PyDate> { unsafe { let ptr = (ensure_datetime_api(py).Date_FromDate)( year, @@ -188,7 +188,7 @@ impl PyDate { /// Construct a `datetime.date` from a POSIX timestamp /// /// This is equivalent to `datetime.date.fromtimestamp` - pub fn from_timestamp(py: Python, timestamp: i64) -> PyResult<&PyDate> { + pub fn from_timestamp(py: Python<'_>, timestamp: i64) -> PyResult<&PyDate> { let time_tuple = PyTuple::new(py, &[timestamp]); // safety ensure that the API is loaded @@ -466,7 +466,7 @@ pyobject_native_type!( impl PyDelta { /// Creates a new `timedelta`. pub fn new( - py: Python, + py: Python<'_>, days: i32, seconds: i32, microseconds: i32, @@ -501,7 +501,7 @@ impl PyDeltaAccess for PyDelta { } // Utility function -fn opt_to_pyobj(py: Python, opt: Option<&PyObject>) -> *mut ffi::PyObject { +fn opt_to_pyobj(py: Python<'_>, opt: Option<&PyObject>) -> *mut ffi::PyObject { // Convenience function for unpacking Options to either an Object or None match opt { Some(tzi) => tzi.as_ptr(), diff --git a/src/types/dict.rs b/src/types/dict.rs index 4e2877de..794fbea7 100644 --- a/src/types/dict.rs +++ b/src/types/dict.rs @@ -27,7 +27,7 @@ pyobject_native_type!( impl PyDict { /// Creates a new empty dictionary. - pub fn new(py: Python) -> &PyDict { + pub fn new(py: Python<'_>) -> &PyDict { unsafe { py.from_owned_ptr::(ffi::PyDict_New()) } } @@ -39,7 +39,7 @@ impl PyDict { /// Returns an error on invalid input. In the case of key collisions, /// this keeps the last entry seen. #[cfg(not(PyPy))] - pub fn from_sequence(py: Python, seq: PyObject) -> PyResult<&PyDict> { + pub fn from_sequence(py: Python<'_>, seq: PyObject) -> PyResult<&PyDict> { unsafe { let dict = py.from_owned_ptr::(ffi::PyDict_New()); err::error_on_minusone( @@ -172,7 +172,7 @@ impl PyDict { /// /// Note that it's unsafe to use when the dictionary might be changed by /// other code. - pub fn iter(&self) -> PyDictIterator { + pub fn iter(&self) -> PyDictIterator<'_> { PyDictIterator { dict: self.as_ref(), pos: 0, @@ -236,7 +236,7 @@ where V: ToPyObject, H: hash::BuildHasher, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { IntoPyDict::into_py_dict(self, py).into() } } @@ -246,7 +246,7 @@ where K: cmp::Eq + ToPyObject, V: ToPyObject, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { IntoPyDict::into_py_dict(self, py).into() } } @@ -257,7 +257,7 @@ where V: IntoPy, H: hash::BuildHasher, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); @@ -270,7 +270,7 @@ where K: cmp::Eq + IntoPy, V: IntoPy, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let iter = self .into_iter() .map(|(k, v)| (k.into_py(py), v.into_py(py))); @@ -283,7 +283,7 @@ where pub trait IntoPyDict { /// Converts self into a `PyDict` object pointer. Whether pointer owned or borrowed /// depends on implementation. - fn into_py_dict(self, py: Python) -> &PyDict; + fn into_py_dict(self, py: Python<'_>) -> &PyDict; } impl IntoPyDict for I @@ -291,7 +291,7 @@ where T: PyDictItem, I: IntoIterator, { - fn into_py_dict(self, py: Python) -> &PyDict { + fn into_py_dict(self, py: Python<'_>) -> &PyDict { let dict = PyDict::new(py); for item in self { dict.set_item(item.key(), item.value()) diff --git a/src/types/floatob.rs b/src/types/floatob.rs index 01c33a2d..3079c61b 100644 --- a/src/types/floatob.rs +++ b/src/types/floatob.rs @@ -35,13 +35,13 @@ impl PyFloat { } impl ToPyObject for f64 { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { PyFloat::new(py, *self).into() } } impl IntoPy for f64 { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { PyFloat::new(py, self).into() } } @@ -63,13 +63,13 @@ impl<'source> FromPyObject<'source> for f64 { } impl ToPyObject for f32 { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { PyFloat::new(py, f64::from(*self)).into() } } impl IntoPy for f32 { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { PyFloat::new(py, f64::from(self)).into() } } diff --git a/src/types/function.rs b/src/types/function.rs index 4e72eefe..297b23c9 100644 --- a/src/types/function.rs +++ b/src/types/function.rs @@ -104,7 +104,7 @@ impl PyCFunction { /// py_run!(py, add_one, "assert add_one(42) == 43"); /// }); /// ``` - pub fn new_closure(f: F, py: Python) -> PyResult<&PyCFunction> + pub fn new_closure(f: F, py: Python<'_>) -> PyResult<&PyCFunction> where F: Fn(&types::PyTuple, Option<&types::PyDict>) -> R + Send + 'static, R: crate::callback::IntoPyCallbackOutput<*mut ffi::PyObject>, @@ -131,7 +131,7 @@ impl PyCFunction { #[doc(hidden)] fn internal_new_from_pointers( method_def: PyMethodDef, - py: Python, + py: Python<'_>, mod_ptr: *mut ffi::PyObject, module_name: *mut ffi::PyObject, ) -> PyResult<&Self> { @@ -150,7 +150,7 @@ impl PyCFunction { #[doc(hidden)] pub fn internal_new( method_def: PyMethodDef, - py_or_module: PyFunctionArguments, + py_or_module: PyFunctionArguments<'_>, ) -> PyResult<&Self> { let (py, module) = py_or_module.into_py_and_maybe_module(); let (mod_ptr, module_name) = if let Some(m) = module { diff --git a/src/types/iterator.rs b/src/types/iterator.rs index 97faf61a..924ccea8 100644 --- a/src/types/iterator.rs +++ b/src/types/iterator.rs @@ -99,7 +99,7 @@ impl Py { /// Similar to [`as_ref`](#method.as_ref), and also consumes this `Py` and registers the /// Python object reference in PyO3's object storage. The reference count for the Python /// object will not be decreased until the GIL lifetime ends. - pub fn into_ref(self, py: Python) -> &PyIterator { + pub fn into_ref(self, py: Python<'_>) -> &PyIterator { unsafe { py.from_owned_ptr(self.into_ptr()) } } } @@ -212,7 +212,8 @@ def fibonacci(target): fn iterator_try_from() { Python::with_gil(|py| { let obj: Py = vec![10, 20].to_object(py).as_ref(py).iter().unwrap().into(); - let iter: &PyIterator = PyIterator::try_from(obj.as_ref(py)).unwrap(); + let iter: &PyIterator = + >::try_from(obj.as_ref(py)).unwrap(); assert!(obj.is(iter)); }); } diff --git a/src/types/list.rs b/src/types/list.rs index bfd5f8b2..ab69859e 100644 --- a/src/types/list.rs +++ b/src/types/list.rs @@ -21,7 +21,10 @@ pyobject_native_type_core!(PyList, ffi::PyList_Type, #checkfunction=ffi::PyList_ #[inline] #[track_caller] -fn new_from_iter(py: Python, elements: &mut dyn ExactSizeIterator) -> Py { +fn new_from_iter( + py: Python<'_>, + elements: &mut dyn ExactSizeIterator, +) -> Py { unsafe { // PyList_New checks for overflow but has a bad error message, so we check ourselves let len: Py_ssize_t = elements @@ -90,7 +93,7 @@ impl PyList { } /// Constructs a new empty list. - pub fn empty(py: Python) -> &PyList { + pub fn empty(py: Python<'_>) -> &PyList { unsafe { py.from_owned_ptr::(ffi::PyList_New(0)) } } @@ -264,7 +267,7 @@ impl PyList { } /// Returns an iterator over this list's items. - pub fn iter(&self) -> PyListIterator { + pub fn iter(&self) -> PyListIterator<'_> { PyListIterator { list: self, index: 0, @@ -351,7 +354,7 @@ impl IntoPy for Vec where T: IntoPy, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let mut iter = self.into_iter().map(|e| e.into_py(py)); let list = new_from_iter(py, &mut iter); list.into() @@ -853,7 +856,7 @@ mod tests { } impl ToPyObject for Bad { - fn to_object(&self, py: Python) -> Py { + fn to_object(&self, py: Python<'_>) -> Py { self.to_owned().into_py(py) } } diff --git a/src/types/mapping.rs b/src/types/mapping.rs index 6cb6ff66..8c861ca0 100644 --- a/src/types/mapping.rs +++ b/src/types/mapping.rs @@ -142,7 +142,7 @@ impl Py { /// Similar to [`as_ref`](#method.as_ref), and also consumes this `Py` and registers the /// Python object reference in PyO3's object storage. The reference count for the Python /// object will not be decreased until the GIL lifetime ends. - pub fn into_ref(self, py: Python) -> &PyMapping { + pub fn into_ref(self, py: Python<'_>) -> &PyMapping { unsafe { py.from_owned_ptr(self.into_ptr()) } } } diff --git a/src/types/mod.rs b/src/types/mod.rs index fa3ca231..192fa80a 100644 --- a/src/types/mod.rs +++ b/src/types/mod.rs @@ -39,7 +39,7 @@ macro_rules! pyobject_native_type_base( unsafe impl<$($generics,)*> $crate::PyNativeType for $name {} impl<$($generics,)*> ::std::fmt::Debug for $name { - fn fmt(&self, f: &mut ::std::fmt::Formatter) + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::result::Result<(), ::std::fmt::Error> { let s = self.repr().or(::std::result::Result::Err(::std::fmt::Error))?; @@ -48,7 +48,7 @@ macro_rules! pyobject_native_type_base( } impl<$($generics,)*> ::std::fmt::Display for $name { - fn fmt(&self, f: &mut ::std::fmt::Formatter) + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::result::Result<(), ::std::fmt::Error> { let s = self.str().or(::std::result::Result::Err(::std::fmt::Error))?; @@ -59,7 +59,7 @@ macro_rules! pyobject_native_type_base( impl<$($generics,)*> $crate::ToPyObject for $name { #[inline] - fn to_object(&self, py: $crate::Python) -> $crate::PyObject { + fn to_object(&self, py: $crate::Python<'_>) -> $crate::PyObject { use $crate::AsPyPointer; unsafe { $crate::PyObject::from_borrowed_ptr(py, self.as_ptr()) } } @@ -101,7 +101,7 @@ macro_rules! pyobject_native_type_named ( impl<$($generics,)*> $crate::IntoPy<$crate::Py<$name>> for &'_ $name { #[inline] - fn into_py(self, py: $crate::Python) -> $crate::Py<$name> { + fn into_py(self, py: $crate::Python<'_>) -> $crate::Py<$name> { use $crate::AsPyPointer; unsafe { $crate::Py::from_borrowed_ptr(py, self.as_ptr()) } } @@ -135,7 +135,7 @@ macro_rules! pyobject_native_type_info( const MODULE: ::std::option::Option<&'static str> = $module; #[inline] - fn type_object_raw(_py: $crate::Python) -> *mut $crate::ffi::PyTypeObject { + fn type_object_raw(_py: $crate::Python<'_>) -> *mut $crate::ffi::PyTypeObject { // Create a very short lived mutable reference and directly // cast it to a pointer: no mutable references can be aliasing // because we hold the GIL. @@ -191,7 +191,7 @@ macro_rules! pyobject_native_type_sized { ($name:ty, $layout:path $(;$generics:ident)*) => { unsafe impl $crate::type_object::PyLayout<$name> for $layout {} impl $crate::type_object::PySizedLayout<$name> for $layout {} - impl<'a, $($generics,)*> $crate::impl_::pyclass::PyClassBaseType for $name { + impl<$($generics,)*> $crate::impl_::pyclass::PyClassBaseType for $name { type LayoutAsBase = $crate::pycell::PyCellBase<$layout>; type BaseNativeType = $name; type ThreadChecker = $crate::impl_::pyclass::ThreadCheckerStub<$crate::PyObject>; diff --git a/src/types/module.rs b/src/types/module.rs index ca6c2534..facb4524 100644 --- a/src/types/module.rs +++ b/src/types/module.rs @@ -221,7 +221,7 @@ impl PyModule { /// use pyo3::prelude::*; /// /// #[pymodule] - /// fn my_module(_py: Python, module: &PyModule) -> PyResult<()> { + /// fn my_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> { /// module.add("c", 299_792_458)?; /// Ok(()) /// } @@ -265,7 +265,7 @@ impl PyModule { /// struct Foo { /* fields omitted */ } /// /// #[pymodule] - /// fn my_module(_py: Python, module: &PyModule) -> PyResult<()> { + /// fn my_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> { /// module.add_class::()?; /// Ok(()) /// } @@ -324,7 +324,7 @@ impl PyModule { /// use pyo3::prelude::*; /// /// #[pymodule] - /// fn my_module(py: Python, module: &PyModule) -> PyResult<()> { + /// fn my_module(py: Python<'_>, module: &PyModule) -> PyResult<()> { /// let submodule = PyModule::new(py, "submodule")?; /// submodule.add("super_useful_constant", "important")?; /// @@ -367,7 +367,7 @@ impl PyModule { /// println!("Hello world!") /// } /// #[pymodule] - /// fn my_module(_py: Python, module: &PyModule) -> PyResult<()> { + /// fn my_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> { /// module.add_function(wrap_pyfunction!(say_hello, module)?) /// } /// ``` diff --git a/src/types/num.rs b/src/types/num.rs index 7a49b6b5..75af9a19 100644 --- a/src/types/num.rs +++ b/src/types/num.rs @@ -14,12 +14,12 @@ macro_rules! int_fits_larger_int { ($rust_type:ty, $larger_type:ty) => { impl ToPyObject for $rust_type { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { (*self as $larger_type).into_py(py) } } impl IntoPy for $rust_type { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { (self as $larger_type).into_py(py) } } @@ -48,12 +48,12 @@ pyobject_native_type_core!(PyLong, ffi::PyLong_Type, #checkfunction=ffi::PyLong_ macro_rules! int_fits_c_long { ($rust_type:ty) => { impl ToPyObject for $rust_type { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_owned_ptr(py, ffi::PyLong_FromLong(*self as c_long)) } } } impl IntoPy for $rust_type { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_owned_ptr(py, ffi::PyLong_FromLong(self as c_long)) } } } @@ -82,13 +82,13 @@ macro_rules! int_convert_u64_or_i64 { ($rust_type:ty, $pylong_from_ll_or_ull:expr, $pylong_as_ll_or_ull:expr) => { impl ToPyObject for $rust_type { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_owned_ptr(py, $pylong_from_ll_or_ull(*self)) } } } impl IntoPy for $rust_type { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { unsafe { PyObject::from_owned_ptr(py, $pylong_from_ll_or_ull(self)) } } } @@ -152,12 +152,12 @@ mod fast_128bit_int_conversion { ($rust_type: ty, $is_signed: expr) => { impl ToPyObject for $rust_type { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { (*self).into_py(py) } } impl IntoPy for $rust_type { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { unsafe { // Always use little endian let bytes = self.to_le_bytes(); @@ -211,13 +211,13 @@ mod slow_128bit_int_conversion { ($rust_type: ty, $half_type: ty) => { impl ToPyObject for $rust_type { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { (*self).into_py(py) } } impl IntoPy for $rust_type { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let lower = self as u64; let upper = (self >> SHIFT) as $half_type; unsafe { @@ -262,7 +262,7 @@ mod slow_128bit_int_conversion { } fn err_if_invalid_value( - py: Python, + py: Python<'_>, invalid_value: T, actual_value: T, ) -> PyResult { diff --git a/src/types/sequence.rs b/src/types/sequence.rs index 8f96eeb5..7cb5ee9d 100644 --- a/src/types/sequence.rs +++ b/src/types/sequence.rs @@ -330,7 +330,7 @@ impl Py { /// Similar to [`as_ref`](#method.as_ref), and also consumes this `Py` and registers the /// Python object reference in PyO3's object storage. The reference count for the Python /// object will not be decreased until the GIL lifetime ends. - pub fn into_ref(self, py: Python) -> &PySequence { + pub fn into_ref(self, py: Python<'_>) -> &PySequence { unsafe { py.from_owned_ptr(self.into_ptr()) } } } diff --git a/src/types/set.rs b/src/types/set.rs index 9c52fe2e..63dc7c7e 100644 --- a/src/types/set.rs +++ b/src/types/set.rs @@ -37,7 +37,7 @@ impl PySet { } /// Creates a new empty set. - pub fn empty(py: Python) -> PyResult<&PySet> { + pub fn empty(py: Python<'_>) -> PyResult<&PySet> { unsafe { py.from_owned_ptr_or_err(ffi::PySet_New(ptr::null_mut())) } } @@ -111,7 +111,7 @@ impl PySet { /// Returns an iterator of values in this set. /// /// Note that it can be unsafe to use when the set might be changed by other code. - pub fn iter(&self) -> PySetIterator { + pub fn iter(&self) -> PySetIterator<'_> { PySetIterator::new(self) } } @@ -123,7 +123,7 @@ pub struct PySetIterator<'p> { #[cfg(Py_LIMITED_API)] impl PySetIterator<'_> { - fn new(set: &PyAny) -> PySetIterator { + fn new(set: &PyAny) -> PySetIterator<'_> { PySetIterator { it: PyIterator::from_object(set.py(), set).unwrap(), } @@ -148,7 +148,7 @@ pub struct PySetIterator<'py> { #[cfg(not(Py_LIMITED_API))] impl PySetIterator<'_> { - fn new(set: &PyAny) -> PySetIterator { + fn new(set: &PyAny) -> PySetIterator<'_> { PySetIterator { set, pos: 0 } } } @@ -195,7 +195,7 @@ where T: hash::Hash + Eq + ToPyObject, S: hash::BuildHasher + Default, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { let set = PySet::new::(py, &[]).expect("Failed to construct empty set"); { for val in self { @@ -210,7 +210,7 @@ impl ToPyObject for collections::BTreeSet where T: hash::Hash + Eq + ToPyObject, { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { let set = PySet::new::(py, &[]).expect("Failed to construct empty set"); { for val in self { @@ -226,7 +226,7 @@ where K: IntoPy + Eq + hash::Hash, S: hash::BuildHasher + Default, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let set = PySet::empty(py).expect("Failed to construct empty set"); { for val in self { @@ -252,7 +252,7 @@ impl IntoPy for BTreeSet where K: IntoPy + cmp::Ord, { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let set = PySet::empty(py).expect("Failed to construct empty set"); { for val in self { @@ -283,7 +283,7 @@ impl PyFrozenSet { } /// Creates a new empty frozen set - pub fn empty(py: Python) -> PyResult<&PyFrozenSet> { + pub fn empty(py: Python<'_>) -> PyResult<&PyFrozenSet> { unsafe { py.from_owned_ptr_or_err(ffi::PyFrozenSet_New(ptr::null_mut())) } } @@ -317,7 +317,7 @@ impl PyFrozenSet { /// Returns an iterator of values in this frozen set. /// /// Note that it can be unsafe to use when the set might be changed by other code. - pub fn iter(&self) -> PySetIterator { + pub fn iter(&self) -> PySetIterator<'_> { PySetIterator::new(self.as_ref()) } } diff --git a/src/types/slice.rs b/src/types/slice.rs index 90cd09da..557cb4cb 100644 --- a/src/types/slice.rs +++ b/src/types/slice.rs @@ -39,7 +39,7 @@ impl PySliceIndices { impl PySlice { /// Constructs a new slice with the given elements. - pub fn new(py: Python, start: isize, stop: isize, step: isize) -> &PySlice { + pub fn new(py: Python<'_>, start: isize, stop: isize, step: isize) -> &PySlice { unsafe { let ptr = ffi::PySlice_New( ffi::PyLong_FromLong(start as c_long), @@ -84,7 +84,7 @@ impl PySlice { } impl ToPyObject for PySliceIndices { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { PySlice::new(py, self.start, self.stop, self.step).into() } } diff --git a/src/types/string.rs b/src/types/string.rs index 1b0e2f15..76610a10 100644 --- a/src/types/string.rs +++ b/src/types/string.rs @@ -68,7 +68,7 @@ impl<'a> PyStringData<'a> { /// storage format. This should only occur for strings that were created via Python /// C APIs that skip input validation (like `PyUnicode_FromKindAndData`) and should /// never occur for strings that were created from Python code. - pub fn to_string(self, py: Python) -> PyResult> { + pub fn to_string(self, py: Python<'_>) -> PyResult> { use std::ffi::CStr; match self { Self::Ucs1(data) => match str::from_utf8(data) { @@ -190,7 +190,7 @@ impl PyString { /// /// Unpaired surrogates invalid UTF-8 sequences are /// replaced with `U+FFFD REPLACEMENT CHARACTER`. - pub fn to_string_lossy(&self) -> Cow { + pub fn to_string_lossy(&self) -> Cow<'_, str> { match self.to_str() { Ok(s) => Cow::Borrowed(s), Err(_) => { @@ -266,30 +266,30 @@ impl PyString { /// See `PyString::new` for details on the conversion. impl ToPyObject for str { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { PyString::new(py, self).into() } } impl<'a> IntoPy for &'a str { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { PyString::new(py, self).into() } } -/// Converts a Rust `Cow` to a Python object. +/// Converts a Rust `Cow<'_, str>` to a Python object. /// See `PyString::new` for details on the conversion. impl<'a> ToPyObject for Cow<'a, str> { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { PyString::new(py, self).into() } } impl IntoPy for Cow<'_, str> { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { self.to_object(py) } } @@ -298,33 +298,33 @@ impl IntoPy for Cow<'_, str> { /// See `PyString::new` for details on the conversion. impl ToPyObject for String { #[inline] - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { PyString::new(py, self).into() } } impl ToPyObject for char { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { self.into_py(py) } } impl IntoPy for char { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { let mut bytes = [0u8; 4]; PyString::new(py, self.encode_utf8(&mut bytes)).into() } } impl IntoPy for String { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { PyString::new(py, &self).into() } } impl<'a> IntoPy for &'a String { #[inline] - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { PyString::new(py, self).into() } } @@ -349,7 +349,7 @@ impl FromPyObject<'_> for String { impl FromPyObject<'_> for char { fn extract(obj: &PyAny) -> PyResult { - let s = PyString::try_from(obj)?.to_str()?; + let s = >::try_from(obj)?.to_str()?; let mut iter = s.chars(); if let (Some(ch), None) = (iter.next(), iter.next()) { Ok(ch) diff --git a/src/types/tuple.rs b/src/types/tuple.rs index aace9109..86454542 100644 --- a/src/types/tuple.rs +++ b/src/types/tuple.rs @@ -12,7 +12,10 @@ use crate::{ #[inline] #[track_caller] -fn new_from_iter(py: Python, elements: &mut dyn ExactSizeIterator) -> Py { +fn new_from_iter( + py: Python<'_>, + elements: &mut dyn ExactSizeIterator, +) -> Py { unsafe { // PyTuple_New checks for overflow but has a bad error message, so we check ourselves let len: Py_ssize_t = elements @@ -79,7 +82,10 @@ impl PyTuple { /// All standard library structures implement this trait correctly, if they do, so calling this /// function using [`Vec`]`` or `&[T]` will always succeed. #[track_caller] - pub fn new(py: Python, elements: impl IntoIterator) -> &PyTuple + pub fn new( + py: Python<'_>, + elements: impl IntoIterator, + ) -> &PyTuple where T: ToPyObject, U: ExactSizeIterator, @@ -90,7 +96,7 @@ impl PyTuple { } /// Constructs an empty tuple (on the Python side, a singleton object). - pub fn empty(py: Python) -> &PyTuple { + pub fn empty(py: Python<'_>) -> &PyTuple { unsafe { py.from_owned_ptr(ffi::PyTuple_New(0)) } } @@ -226,7 +232,7 @@ impl PyTuple { } /// Returns an iterator over the tuple items. - pub fn iter(&self) -> PyTupleIterator { + pub fn iter(&self) -> PyTupleIterator<'_> { PyTupleIterator { tuple: self, index: 0, @@ -296,7 +302,7 @@ fn wrong_tuple_length(t: &PyTuple, expected_length: usize) -> PyErr { macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+} => { impl <$($T: ToPyObject),+> ToPyObject for ($($T,)+) { - fn to_object(&self, py: Python) -> PyObject { + fn to_object(&self, py: Python<'_>) -> PyObject { unsafe { let ptr = ffi::PyTuple_New($length); let ret = PyObject::from_owned_ptr(py, ptr); @@ -306,7 +312,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+ } } impl <$($T: IntoPy),+> IntoPy for ($($T,)+) { - fn into_py(self, py: Python) -> PyObject { + fn into_py(self, py: Python<'_>) -> PyObject { unsafe { let ptr = ffi::PyTuple_New($length); let ret = PyObject::from_owned_ptr(py, ptr); @@ -317,7 +323,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+ } impl <$($T: IntoPy),+> IntoPy> for ($($T,)+) { - fn into_py(self, py: Python) -> Py { + fn into_py(self, py: Python<'_>) -> Py { unsafe { let ptr = ffi::PyTuple_New($length); let ret = Py::from_owned_ptr(py, ptr); @@ -836,7 +842,7 @@ mod tests { } impl ToPyObject for Bad { - fn to_object(&self, py: Python) -> Py { + fn to_object(&self, py: Python<'_>) -> Py { self.to_owned().into_py(py) } } @@ -905,7 +911,7 @@ mod tests { } impl ToPyObject for Bad { - fn to_object(&self, py: Python) -> Py { + fn to_object(&self, py: Python<'_>) -> Py { self.to_owned().into_py(py) } } diff --git a/src/types/typeobject.rs b/src/types/typeobject.rs index 8156a4f3..dfc97901 100644 --- a/src/types/typeobject.rs +++ b/src/types/typeobject.rs @@ -15,7 +15,7 @@ pyobject_native_type_core!(PyType, ffi::PyType_Type, #checkfunction=ffi::PyType_ impl PyType { /// Creates a new type object. #[inline] - pub fn new(py: Python) -> &PyType { + pub fn new(py: Python<'_>) -> &PyType { T::type_object(py) } @@ -31,7 +31,7 @@ impl PyType { /// - The pointer must be non-null. /// - The pointer must be valid for the entire of the lifetime for which the reference is used. #[inline] - pub unsafe fn from_type_ptr(py: Python, p: *mut ffi::PyTypeObject) -> &PyType { + pub unsafe fn from_type_ptr(py: Python<'_>, p: *mut ffi::PyTypeObject) -> &PyType { py.from_borrowed_ptr(p as *mut ffi::PyObject) } diff --git a/tests/test_arithmetics.rs b/tests/test_arithmetics.rs index 548ed913..0c4cd766 100644 --- a/tests/test_arithmetics.rs +++ b/tests/test_arithmetics.rs @@ -309,7 +309,7 @@ fn rhs_arithmetic() { struct LhsAndRhs {} impl std::fmt::Debug for LhsAndRhs { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "LR") } } @@ -320,43 +320,43 @@ impl LhsAndRhs { // "BA" // } - fn __add__(lhs: PyRef, rhs: &PyAny) -> String { + fn __add__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} + {:?}", lhs, rhs) } - fn __sub__(lhs: PyRef, rhs: &PyAny) -> String { + fn __sub__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} - {:?}", lhs, rhs) } - fn __mul__(lhs: PyRef, rhs: &PyAny) -> String { + fn __mul__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} * {:?}", lhs, rhs) } - fn __lshift__(lhs: PyRef, rhs: &PyAny) -> String { + fn __lshift__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} << {:?}", lhs, rhs) } - fn __rshift__(lhs: PyRef, rhs: &PyAny) -> String { + fn __rshift__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} >> {:?}", lhs, rhs) } - fn __and__(lhs: PyRef, rhs: &PyAny) -> String { + fn __and__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} & {:?}", lhs, rhs) } - fn __xor__(lhs: PyRef, rhs: &PyAny) -> String { + fn __xor__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} ^ {:?}", lhs, rhs) } - fn __or__(lhs: PyRef, rhs: &PyAny) -> String { + fn __or__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} | {:?}", lhs, rhs) } - fn __pow__(lhs: PyRef, rhs: &PyAny, _mod: Option) -> String { + fn __pow__(lhs: PyRef<'_, Self>, rhs: &PyAny, _mod: Option) -> String { format!("{:?} ** {:?}", lhs, rhs) } - fn __matmul__(lhs: PyRef, rhs: &PyAny) -> String { + fn __matmul__(lhs: PyRef<'_, Self>, rhs: &PyAny) -> String { format!("{:?} @ {:?}", lhs, rhs) } @@ -544,7 +544,7 @@ mod return_not_implemented { "RC_Self" } - fn __richcmp__(&self, other: PyRef, _op: CompareOp) -> PyObject { + fn __richcmp__(&self, other: PyRef<'_, Self>, _op: CompareOp) -> PyObject { other.py().None() } @@ -569,7 +569,7 @@ mod return_not_implemented { fn __mod__<'p>(slf: PyRef<'p, Self>, _other: PyRef<'p, Self>) -> PyRef<'p, Self> { slf } - fn __pow__(slf: PyRef, _other: u8, _modulo: Option) -> PyRef { + fn __pow__(slf: PyRef<'_, Self>, _other: u8, _modulo: Option) -> PyRef<'_, Self> { slf } fn __lshift__<'p>(slf: PyRef<'p, Self>, _other: PyRef<'p, Self>) -> PyRef<'p, Self> { @@ -592,19 +592,19 @@ mod return_not_implemented { } // Inplace assignments - fn __iadd__(&mut self, _other: PyRef) {} - fn __isub__(&mut self, _other: PyRef) {} - fn __imul__(&mut self, _other: PyRef) {} - fn __imatmul__(&mut self, _other: PyRef) {} - fn __itruediv__(&mut self, _other: PyRef) {} - fn __ifloordiv__(&mut self, _other: PyRef) {} - fn __imod__(&mut self, _other: PyRef) {} - fn __ilshift__(&mut self, _other: PyRef) {} - fn __irshift__(&mut self, _other: PyRef) {} - fn __iand__(&mut self, _other: PyRef) {} - fn __ior__(&mut self, _other: PyRef) {} - fn __ixor__(&mut self, _other: PyRef) {} - fn __ipow__(&mut self, _other: PyRef, _modulo: Option) {} + fn __iadd__(&mut self, _other: PyRef<'_, Self>) {} + fn __isub__(&mut self, _other: PyRef<'_, Self>) {} + fn __imul__(&mut self, _other: PyRef<'_, Self>) {} + fn __imatmul__(&mut self, _other: PyRef<'_, Self>) {} + fn __itruediv__(&mut self, _other: PyRef<'_, Self>) {} + fn __ifloordiv__(&mut self, _other: PyRef<'_, Self>) {} + fn __imod__(&mut self, _other: PyRef<'_, Self>) {} + fn __ilshift__(&mut self, _other: PyRef<'_, Self>) {} + fn __irshift__(&mut self, _other: PyRef<'_, Self>) {} + fn __iand__(&mut self, _other: PyRef<'_, Self>) {} + fn __ior__(&mut self, _other: PyRef<'_, Self>) {} + fn __ixor__(&mut self, _other: PyRef<'_, Self>) {} + fn __ipow__(&mut self, _other: PyRef<'_, Self>, _modulo: Option) {} } fn _test_binary_dunder(dunder: &str) { diff --git a/tests/test_arithmetics_protos.rs b/tests/test_arithmetics_protos.rs index b991599a..535b7567 100644 --- a/tests/test_arithmetics_protos.rs +++ b/tests/test_arithmetics_protos.rs @@ -291,7 +291,7 @@ fn rhs_arithmetic() { struct LhsAndRhs {} impl std::fmt::Debug for LhsAndRhs { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "LR") } } diff --git a/tests/test_buffer.rs b/tests/test_buffer.rs index 86a356db..7a5dc41d 100644 --- a/tests/test_buffer.rs +++ b/tests/test_buffer.rs @@ -28,7 +28,7 @@ struct TestBufferErrors { #[pymethods] impl TestBufferErrors { unsafe fn __getbuffer__( - slf: PyRefMut, + slf: PyRefMut<'_, Self>, view: *mut ffi::Py_buffer, flags: c_int, ) -> PyResult<()> { diff --git a/tests/test_buffer_protocol.rs b/tests/test_buffer_protocol.rs index 65c32e2d..a9252901 100644 --- a/tests/test_buffer_protocol.rs +++ b/tests/test_buffer_protocol.rs @@ -24,7 +24,7 @@ struct TestBufferClass { #[pymethods] impl TestBufferClass { unsafe fn __getbuffer__( - mut slf: PyRefMut, + mut slf: PyRefMut<'_, Self>, view: *mut ffi::Py_buffer, flags: c_int, ) -> PyResult<()> { diff --git a/tests/test_buffer_protocol_pyproto.rs b/tests/test_buffer_protocol_pyproto.rs index 84d0e469..9c1239ed 100644 --- a/tests/test_buffer_protocol_pyproto.rs +++ b/tests/test_buffer_protocol_pyproto.rs @@ -1,7 +1,7 @@ #![cfg(feature = "macros")] #![cfg(feature = "pyproto")] #![cfg(any(not(Py_LIMITED_API), Py_3_11))] -#![allow(deprecated)] +#![allow(deprecated, elided_lifetimes_in_paths)] use pyo3::buffer::PyBuffer; use pyo3::class::PyBufferProtocol; diff --git a/tests/test_bytes.rs b/tests/test_bytes.rs index 36ae41e4..d2d47e80 100644 --- a/tests/test_bytes.rs +++ b/tests/test_bytes.rs @@ -20,7 +20,7 @@ fn test_pybytes_bytes_conversion() { } #[pyfunction] -fn bytes_vec_conversion(py: Python, bytes: Vec) -> &PyBytes { +fn bytes_vec_conversion(py: Python<'_>, bytes: Vec) -> &PyBytes { PyBytes::new(py, bytes.as_slice()) } diff --git a/tests/test_class_conversion.rs b/tests/test_class_conversion.rs index ef7b403e..a564750a 100644 --- a/tests/test_class_conversion.rs +++ b/tests/test_class_conversion.rs @@ -24,11 +24,11 @@ fn test_cloneable_pyclass() { let c2: Cloneable = py_c.extract(py).unwrap(); assert_eq!(c, c2); { - let rc: PyRef = py_c.extract(py).unwrap(); + let rc: PyRef<'_, Cloneable> = py_c.extract(py).unwrap(); assert_eq!(&c, &*rc); // Drops PyRef before taking PyRefMut } - let mrc: PyRefMut = py_c.extract(py).unwrap(); + let mrc: PyRefMut<'_, Cloneable> = py_c.extract(py).unwrap(); assert_eq!(&c, &*mrc); } @@ -135,16 +135,16 @@ fn test_pyref_as_base() { let cell = PyCell::new(py, (SubClass {}, BaseClass { value: 120 })).unwrap(); // First try PyRefMut - let sub: PyRefMut = cell.borrow_mut(); - let mut base: PyRefMut = sub.into_super(); + let sub: PyRefMut<'_, SubClass> = cell.borrow_mut(); + let mut base: PyRefMut<'_, BaseClass> = sub.into_super(); assert_eq!(120, base.value); base.value = 999; assert_eq!(999, base.value); drop(base); // Repeat for PyRef - let sub: PyRef = cell.borrow(); - let base: PyRef = sub.into_super(); + let sub: PyRef<'_, SubClass> = cell.borrow(); + let base: PyRef<'_, BaseClass> = sub.into_super(); assert_eq!(999, base.value); } diff --git a/tests/test_datetime.rs b/tests/test_datetime.rs index 976c04ef..458e15d3 100644 --- a/tests/test_datetime.rs +++ b/tests/test_datetime.rs @@ -5,14 +5,14 @@ use pyo3::types::IntoPyDict; use pyo3_ffi::PyDateTime_IMPORT; fn _get_subclasses<'p>( - py: &'p Python, + py: Python<'p>, py_type: &str, args: &str, ) -> PyResult<(&'p PyAny, &'p PyAny, &'p PyAny)> { // Import the class from Python and create some subclasses let datetime = py.import("datetime")?; - let locals = [(py_type, datetime.getattr(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); @@ -57,7 +57,7 @@ macro_rules! assert_check_only { fn test_date_check() { let gil = Python::acquire_gil(); let py = gil.python(); - let (obj, sub_obj, sub_sub_obj) = _get_subclasses(&py, "date", "2018, 1, 1").unwrap(); + let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "date", "2018, 1, 1").unwrap(); unsafe { PyDateTime_IMPORT() } assert_check_exact!(PyDate_Check, PyDate_CheckExact, obj); assert_check_only!(PyDate_Check, PyDate_CheckExact, sub_obj); @@ -68,7 +68,7 @@ fn test_date_check() { fn test_time_check() { let gil = Python::acquire_gil(); let py = gil.python(); - let (obj, sub_obj, sub_sub_obj) = _get_subclasses(&py, "time", "12, 30, 15").unwrap(); + let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "time", "12, 30, 15").unwrap(); unsafe { PyDateTime_IMPORT() } assert_check_exact!(PyTime_Check, PyTime_CheckExact, obj); @@ -80,7 +80,7 @@ fn test_time_check() { fn test_datetime_check() { let gil = Python::acquire_gil(); let py = gil.python(); - let (obj, sub_obj, sub_sub_obj) = _get_subclasses(&py, "datetime", "2018, 1, 1, 13, 30, 15") + let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "datetime", "2018, 1, 1, 13, 30, 15") .map_err(|e| e.print(py)) .unwrap(); unsafe { PyDateTime_IMPORT() } @@ -95,7 +95,7 @@ fn test_datetime_check() { fn test_delta_check() { let gil = Python::acquire_gil(); let py = gil.python(); - let (obj, sub_obj, sub_sub_obj) = _get_subclasses(&py, "timedelta", "1, -3").unwrap(); + let (obj, sub_obj, sub_sub_obj) = _get_subclasses(py, "timedelta", "1, -3").unwrap(); unsafe { PyDateTime_IMPORT() } assert_check_exact!(PyDelta_Check, PyDelta_CheckExact, obj); diff --git a/tests/test_exceptions.rs b/tests/test_exceptions.rs index 50d0f0c7..da42f1b5 100644 --- a/tests/test_exceptions.rs +++ b/tests/test_exceptions.rs @@ -41,7 +41,7 @@ struct CustomError; impl Error for CustomError {} impl fmt::Display for CustomError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Oh no!") } } diff --git a/tests/test_frompyobject.rs b/tests/test_frompyobject.rs index 41557f36..7215ba82 100644 --- a/tests/test_frompyobject.rs +++ b/tests/test_frompyobject.rs @@ -10,7 +10,7 @@ mod common; /// Helper function that concatenates the error message from /// each error in the traceback into a single string that can /// be tested. -fn extract_traceback(py: Python, mut error: PyErr) -> String { +fn extract_traceback(py: Python<'_>, mut error: PyErr) -> String { let mut error_msg = error.to_string(); while let Some(cause) = error.cause(py) { error_msg.push_str(": "); @@ -57,7 +57,8 @@ fn test_named_fields_struct() { foo: None, }; let py_c = Py::new(py, pya).unwrap(); - let a: A = FromPyObject::extract(py_c.as_ref(py)).expect("Failed to extract A from PyA"); + let a: A<'_> = + FromPyObject::extract(py_c.as_ref(py)).expect("Failed to extract A from PyA"); assert_eq!(a.s, "foo"); assert_eq!(a.t.to_string_lossy(), "bar"); assert!(a.p.is_none()); diff --git a/tests/test_gc.rs b/tests/test_gc.rs index 506b1a21..7f7e5bcf 100644 --- a/tests/test_gc.rs +++ b/tests/test_gc.rs @@ -90,7 +90,7 @@ struct GcIntegration { #[pymethods] impl GcIntegration { - fn __traverse__(&self, visit: PyVisit) -> Result<(), PyTraverseError> { + fn __traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError> { visit.call(&self.self_ref) } @@ -187,7 +187,7 @@ fn inheritance_with_new_methods_with_drop() { let typeobj = py.get_type::(); let inst = typeobj.call((), None).unwrap(); - let obj: &PyCell = inst.try_into().unwrap(); + let obj: &PyCell = PyTryInto::try_into(&*inst).unwrap(); let mut obj_ref_mut = obj.borrow_mut(); obj_ref_mut.data = Some(Arc::clone(&drop_called1)); let base: &mut BaseClassWithDrop = obj_ref_mut.as_mut(); @@ -216,7 +216,7 @@ impl TraversableClass { fn __clear__(&mut self) {} #[allow(clippy::unnecessary_wraps)] - fn __traverse__(&self, _visit: PyVisit) -> Result<(), PyTraverseError> { + fn __traverse__(&self, _visit: PyVisit<'_>) -> Result<(), PyTraverseError> { self.traversed.store(true, Ordering::Relaxed); Ok(()) } @@ -270,14 +270,14 @@ struct PanickyTraverse { } impl PanickyTraverse { - fn new(py: Python) -> Self { + fn new(py: Python<'_>) -> Self { Self { member: py.None() } } } #[pymethods] impl PanickyTraverse { - fn __traverse__(&self, visit: PyVisit) -> Result<(), PyTraverseError> { + fn __traverse__(&self, visit: PyVisit<'_>) -> Result<(), PyTraverseError> { visit.call(&self.member)?; // In the test, we expect this to never be hit unreachable!() diff --git a/tests/test_gc_pyproto.rs b/tests/test_gc_pyproto.rs index f31195f1..76419751 100644 --- a/tests/test_gc_pyproto.rs +++ b/tests/test_gc_pyproto.rs @@ -1,6 +1,6 @@ #![cfg(feature = "macros")] #![cfg(feature = "pyproto")] -#![allow(deprecated)] +#![allow(deprecated, elided_lifetimes_in_paths)] use pyo3::class::PyGCProtocol; use pyo3::class::PyTraverseError; @@ -207,7 +207,7 @@ fn inheritance_with_new_methods_with_drop() { let typeobj = py.get_type::(); let inst = typeobj.call((), None).unwrap(); - let obj: &PyCell = inst.try_into().unwrap(); + let obj: &PyCell = PyTryInto::try_into(&*inst).unwrap(); let mut obj_ref_mut = obj.borrow_mut(); obj_ref_mut.data = Some(Arc::clone(&drop_called1)); let base: &mut BaseClassWithDrop = obj_ref_mut.as_mut(); diff --git a/tests/test_getter_setter.rs b/tests/test_getter_setter.rs index 685c0c79..3cfb28c2 100644 --- a/tests/test_getter_setter.rs +++ b/tests/test_getter_setter.rs @@ -113,12 +113,12 @@ struct RefGetterSetter { #[pymethods] impl RefGetterSetter { #[getter] - fn get_num(slf: PyRef) -> i32 { + fn get_num(slf: PyRef<'_, Self>) -> i32 { slf.num } #[setter] - fn set_num(mut slf: PyRefMut, value: i32) { + fn set_num(mut slf: PyRefMut<'_, Self>, value: i32) { slf.num = value; } } diff --git a/tests/test_mapping.rs b/tests/test_mapping.rs index 0e65f60d..2f916d8e 100644 --- a/tests/test_mapping.rs +++ b/tests/test_mapping.rs @@ -58,7 +58,7 @@ impl Mapping { } /// Return a dict with `m = Mapping(['1', '2', '3'])`. -fn map_dict(py: Python) -> &pyo3::types::PyDict { +fn map_dict(py: Python<'_>) -> &pyo3::types::PyDict { let d = [("Mapping", py.get_type::())].into_py_dict(py); py_run!(py, *d, "m = Mapping(['1', '2', '3'])"); d diff --git a/tests/test_mapping_pyproto.rs b/tests/test_mapping_pyproto.rs index 29dddbdf..40e07bd2 100644 --- a/tests/test_mapping_pyproto.rs +++ b/tests/test_mapping_pyproto.rs @@ -1,6 +1,6 @@ #![cfg(feature = "macros")] #![cfg(feature = "pyproto")] -#![allow(deprecated)] +#![allow(deprecated, elided_lifetimes_in_paths)] use std::collections::HashMap; @@ -64,7 +64,7 @@ impl PyMappingProtocol for Mapping { } /// Return a dict with `m = Mapping(['1', '2', '3'])`. -fn map_dict(py: Python) -> &pyo3::types::PyDict { +fn map_dict(py: Python<'_>) -> &pyo3::types::PyDict { let d = [("Mapping", py.get_type::())].into_py_dict(py); py_run!(py, *d, "m = Mapping(['1', '2', '3'])"); d diff --git a/tests/test_methods.rs b/tests/test_methods.rs index 00c752db..6b1b3bf1 100644 --- a/tests/test_methods.rs +++ b/tests/test_methods.rs @@ -127,7 +127,7 @@ impl StaticMethod { #[staticmethod] /// Test static method. - fn method(_py: Python) -> &'static str { + fn method(_py: Python<'_>) -> &'static str { "StaticMethod.method()!" } } @@ -152,7 +152,7 @@ struct StaticMethodWithArgs {} #[pymethods] impl StaticMethodWithArgs { #[staticmethod] - fn method(_py: Python, input: i32) -> String { + fn method(_py: Python<'_>, input: i32) -> String { format!("0x{:x}", input) } } @@ -202,14 +202,14 @@ impl MethArgs { test } #[args(args = "*", kwargs = "**")] - fn get_kwargs(&self, py: Python, args: &PyTuple, kwargs: Option<&PyDict>) -> PyObject { + fn get_kwargs(&self, py: Python<'_>, args: &PyTuple, kwargs: Option<&PyDict>) -> PyObject { [args.into(), kwargs.to_object(py)].to_object(py) } #[args(args = "*", kwargs = "**")] fn get_pos_arg_kw( &self, - py: Python, + py: Python<'_>, a: i32, args: &PyTuple, kwargs: Option<&PyDict>, @@ -253,7 +253,12 @@ impl MethArgs { } #[args(a, "/", kwargs = "**")] - fn get_pos_only_with_kwargs(&self, py: Python, a: i32, kwargs: Option<&PyDict>) -> PyObject { + fn get_pos_only_with_kwargs( + &self, + py: Python<'_>, + a: i32, + kwargs: Option<&PyDict>, + ) -> PyObject { [a.to_object(py), kwargs.to_object(py)].to_object(py) } @@ -273,7 +278,7 @@ impl MethArgs { } #[args(args = "*", a)] - fn get_args_and_required_keyword(&self, py: Python, args: &PyTuple, a: i32) -> PyObject { + fn get_args_and_required_keyword(&self, py: Python<'_>, args: &PyTuple, a: i32) -> PyObject { (args, a).to_object(py) } @@ -288,7 +293,7 @@ impl MethArgs { } #[args(kwargs = "**")] - fn get_pos_kw(&self, py: Python, a: i32, kwargs: Option<&PyDict>) -> PyObject { + fn get_pos_kw(&self, py: Python<'_>, a: i32, kwargs: Option<&PyDict>) -> PyObject { [a.to_object(py), kwargs.to_object(py)].to_object(py) } // "args" can be anything that can be extracted from PyTuple @@ -690,7 +695,7 @@ impl MethodWithPyClassArg { value: self.value + other.value, } } - fn add_pyref(&self, other: PyRef) -> MethodWithPyClassArg { + fn add_pyref(&self, other: PyRef<'_, MethodWithPyClassArg>) -> MethodWithPyClassArg { MethodWithPyClassArg { value: self.value + other.value, } @@ -698,7 +703,7 @@ impl MethodWithPyClassArg { fn inplace_add(&self, other: &mut MethodWithPyClassArg) { other.value += self.value; } - fn inplace_add_pyref(&self, mut other: PyRefMut) { + fn inplace_add_pyref(&self, mut other: PyRefMut<'_, MethodWithPyClassArg>) { other.value += self.value; } fn optional_add(&self, other: Option<&MethodWithPyClassArg>) -> MethodWithPyClassArg { @@ -838,7 +843,7 @@ struct r#RawIdents { impl r#RawIdents { #[new] pub fn r#new( - r#_py: Python, + r#_py: Python<'_>, r#type: PyObject, r#subtype: PyObject, r#subsubtype: PyObject, diff --git a/tests/test_module.rs b/tests/test_module.rs index 887f413b..7364d7ec 100644 --- a/tests/test_module.rs +++ b/tests/test_module.rs @@ -33,7 +33,7 @@ fn double(x: usize) -> usize { /// This module is implemented in Rust. #[pymodule] -fn module_with_functions(_py: Python, m: &PyModule) -> PyResult<()> { +fn module_with_functions(_py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pyfn(m)] #[pyo3(name = "no_parameters")] fn function_with_name() -> usize { @@ -116,7 +116,7 @@ fn test_module_with_functions() { #[pymodule] #[pyo3(name = "other_name")] -fn some_name(_: Python, m: &PyModule) -> PyResult<()> { +fn some_name(_: Python<'_>, m: &PyModule) -> PyResult<()> { m.add("other_name", "other_name")?; Ok(()) } @@ -166,7 +166,7 @@ fn r#move() -> usize { } #[pymodule] -fn raw_ident_module(_py: Python, module: &PyModule) -> PyResult<()> { +fn raw_ident_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> { module.add_function(wrap_pyfunction!(r#move, module)?) } @@ -189,7 +189,7 @@ fn custom_named_fn() -> usize { } #[pymodule] -fn foobar_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn foobar_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(custom_named_fn, m)?)?; m.dict().set_item("yay", "me")?; Ok(()) @@ -235,7 +235,7 @@ fn submodule(module: &PyModule) -> PyResult<()> { } #[pymodule] -fn submodule_with_init_fn(_py: Python, module: &PyModule) -> PyResult<()> { +fn submodule_with_init_fn(_py: Python<'_>, module: &PyModule) -> PyResult<()> { module.add_function(wrap_pyfunction!(subfunction, module)?)?; Ok(()) } @@ -246,7 +246,7 @@ fn superfunction() -> String { } #[pymodule] -fn supermodule(py: Python, module: &PyModule) -> PyResult<()> { +fn supermodule(py: Python<'_>, module: &PyModule) -> PyResult<()> { module.add_function(wrap_pyfunction!(superfunction, module)?)?; let module_to_add = PyModule::new(py, "submodule")?; submodule(module_to_add)?; @@ -285,14 +285,14 @@ fn test_module_nesting() { // Test that argument parsing specification works for pyfunctions #[pyfunction(a = 5, vararg = "*")] -fn ext_vararg_fn(py: Python, a: i32, vararg: &PyTuple) -> PyObject { +fn ext_vararg_fn(py: Python<'_>, a: i32, vararg: &PyTuple) -> PyObject { [a.to_object(py), vararg.into()].to_object(py) } #[pymodule] -fn vararg_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn vararg_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pyfn(m, a = 5, vararg = "*")] - fn int_vararg_fn(py: Python, a: i32, vararg: &PyTuple) -> PyObject { + fn int_vararg_fn(py: Python<'_>, a: i32, vararg: &PyTuple) -> PyObject { ext_vararg_fn(py, a, vararg) } @@ -318,7 +318,7 @@ fn test_module_with_constant() { // Regression test for #1102 #[pymodule] - fn module_with_constant(_py: Python, m: &PyModule) -> PyResult<()> { + fn module_with_constant(_py: Python<'_>, m: &PyModule) -> PyResult<()> { const ANON: AnonClass = AnonClass {}; m.add("ANON", ANON)?; @@ -382,7 +382,7 @@ fn pyfunction_with_pass_module_in_attribute(module: &PyModule) -> PyResult<&str> } #[pymodule] -fn module_with_functions_with_module(_py: Python, m: &PyModule) -> PyResult<()> { +fn module_with_functions_with_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { m.add_function(wrap_pyfunction!(pyfunction_with_module, m)?)?; m.add_function(wrap_pyfunction!(pyfunction_with_module_and_py, m)?)?; m.add_function(wrap_pyfunction!(pyfunction_with_module_and_arg, m)?)?; @@ -434,7 +434,7 @@ fn test_module_doc_hidden() { #[doc(hidden)] #[allow(clippy::unnecessary_wraps)] #[pymodule] - fn my_module(_py: Python, _m: &PyModule) -> PyResult<()> { + fn my_module(_py: Python<'_>, _m: &PyModule) -> PyResult<()> { Ok(()) } diff --git a/tests/test_proto_methods.rs b/tests/test_proto_methods.rs index 87035916..68881d6f 100644 --- a/tests/test_proto_methods.rs +++ b/tests/test_proto_methods.rs @@ -19,7 +19,7 @@ struct ExampleClass { #[pymethods] impl ExampleClass { - fn __getattr__(&self, py: Python, attr: &str) -> PyResult { + fn __getattr__(&self, py: Python<'_>, attr: &str) -> PyResult { if attr == "special_custom_attr" { Ok(self._custom_attr.into_py(py)) } else { @@ -63,7 +63,7 @@ impl ExampleClass { } } -fn make_example(py: Python) -> &PyCell { +fn make_example(py: Python<'_>) -> &PyCell { Py::new( py, ExampleClass { @@ -189,7 +189,7 @@ pub struct Mapping { #[pymethods] impl Mapping { - fn __len__(&self, py: Python) -> usize { + fn __len__(&self, py: Python<'_>) -> usize { self.values.as_ref(py).len() } @@ -262,7 +262,7 @@ impl Sequence { self.values.len() } - fn __getitem__(&self, index: SequenceIndex) -> PyResult { + fn __getitem__(&self, index: SequenceIndex<'_>) -> PyResult { match index { SequenceIndex::Integer(index) => { let uindex = self.usize_index(index)?; @@ -366,11 +366,11 @@ struct Iterator { #[pymethods] impl Iterator { - fn __iter__(slf: PyRef) -> PyRef { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } - fn __next__(mut slf: PyRefMut) -> Option { + fn __next__(mut slf: PyRefMut<'_, Self>) -> Option { slf.iter.next() } } @@ -680,14 +680,14 @@ impl OnceFuture { } } - fn __await__(slf: PyRef) -> PyRef { + fn __await__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } - fn __iter__(slf: PyRef) -> PyRef { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } - fn __next__(mut slf: PyRefMut) -> Option { + fn __next__(mut slf: PyRefMut<'_, Self>) -> Option { if !slf.polled { slf.polled = true; Some(slf.future.clone()) @@ -737,7 +737,7 @@ impl AsyncIterator { } } - fn __aiter__(slf: PyRef) -> PyRef { + fn __aiter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } @@ -876,7 +876,7 @@ struct DefaultedContains; #[pymethods] impl DefaultedContains { - fn __iter__(&self, py: Python) -> PyObject { + fn __iter__(&self, py: Python<'_>) -> PyObject { PyList::new(py, &["a", "b", "c"]) .as_ref() .iter() @@ -890,7 +890,7 @@ struct NoContains; #[pymethods] impl NoContains { - fn __iter__(&self, py: Python) -> PyObject { + fn __iter__(&self, py: Python<'_>) -> PyObject { PyList::new(py, &["a", "b", "c"]) .as_ref() .iter() diff --git a/tests/test_pyfunction.rs b/tests/test_pyfunction.rs index 14920dc1..ab80d4a0 100644 --- a/tests/test_pyfunction.rs +++ b/tests/test_pyfunction.rs @@ -29,7 +29,7 @@ fn test_optional_bool() { #[cfg(not(Py_LIMITED_API))] #[pyfunction] -fn buffer_inplace_add(py: Python, x: PyBuffer, y: PyBuffer) { +fn buffer_inplace_add(py: Python<'_>, x: PyBuffer, y: PyBuffer) { let x = x.as_mut_slice(py).unwrap(); let y = y.as_slice(py).unwrap(); for (xi, yi) in x.iter().zip(y) { @@ -263,7 +263,7 @@ conversion_error('string1', -100, ('string2', 10.), None, ValueClass(-5))", /// Helper function that concatenates the error message from /// each error in the traceback into a single string that can /// be tested. -fn extract_traceback(py: Python, mut error: PyErr) -> String { +fn extract_traceback(py: Python<'_>, mut error: PyErr) -> String { let mut error_msg = error.to_string(); while let Some(cause) = error.cause(py) { error_msg.push_str(": "); diff --git a/tests/test_pyself.rs b/tests/test_pyself.rs index 48196300..5195f5e1 100644 --- a/tests/test_pyself.rs +++ b/tests/test_pyself.rs @@ -32,9 +32,9 @@ impl Reader { } } fn get_iter_and_reset( - mut slf: PyRefMut, + mut slf: PyRefMut<'_, Self>, keys: Py, - py: Python, + py: Python<'_>, ) -> PyResult { let reader = Py::new(py, slf.clone())?; slf.inner.clear(); @@ -57,11 +57,11 @@ struct Iter { #[pymethods] impl Iter { #[allow(clippy::self_named_constructors)] - fn __iter__(slf: PyRef) -> PyRef { + fn __iter__(slf: PyRef<'_, Self>) -> PyRef<'_, Self> { slf } - fn __next__(mut slf: PyRefMut) -> PyResult> { + fn __next__(mut slf: PyRefMut<'_, Self>) -> PyResult> { let bytes = slf.keys.as_ref(slf.py()).as_bytes(); match bytes.get(slf.idx) { Some(&b) => { diff --git a/tests/test_sequence.rs b/tests/test_sequence.rs index e925bea3..c87247a2 100644 --- a/tests/test_sequence.rs +++ b/tests/test_sequence.rs @@ -72,7 +72,7 @@ impl ByteSequence { Self { elements } } - fn __inplace_concat__(mut slf: PyRefMut, other: &Self) -> Py { + fn __inplace_concat__(mut slf: PyRefMut<'_, Self>, other: &Self) -> Py { slf.elements.extend_from_slice(&other.elements); slf.into() } @@ -89,7 +89,7 @@ impl ByteSequence { } } - fn __inplace_repeat__(mut slf: PyRefMut, count: isize) -> PyResult> { + fn __inplace_repeat__(mut slf: PyRefMut<'_, Self>, count: isize) -> PyResult> { if count >= 0 { let mut elements = Vec::with_capacity(slf.elements.len() * count as usize); for _ in 0..count { @@ -104,7 +104,7 @@ impl ByteSequence { } /// Return a dict with `s = ByteSequence([1, 2, 3])`. -fn seq_dict(py: Python) -> &pyo3::types::PyDict { +fn seq_dict(py: Python<'_>) -> &pyo3::types::PyDict { let d = [("ByteSequence", py.get_type::())].into_py_dict(py); // Though we can construct `s` in Rust, let's test `__new__` works. py_run!(py, *d, "s = ByteSequence([1, 2, 3])"); diff --git a/tests/test_sequence_pyproto.rs b/tests/test_sequence_pyproto.rs index 203d76c5..d61b3ad3 100644 --- a/tests/test_sequence_pyproto.rs +++ b/tests/test_sequence_pyproto.rs @@ -88,7 +88,7 @@ impl PySequenceProtocol for ByteSequence { } /// Return a dict with `s = ByteSequence([1, 2, 3])`. -fn seq_dict(py: Python) -> &pyo3::types::PyDict { +fn seq_dict(py: Python<'_>) -> &pyo3::types::PyDict { let d = [("ByteSequence", py.get_type::())].into_py_dict(py); // Though we can construct `s` in Rust, let's test `__new__` works. py_run!(py, *d, "s = ByteSequence([1, 2, 3])"); diff --git a/tests/test_text_signature.rs b/tests/test_text_signature.rs index 47ea328f..f3368bd9 100644 --- a/tests/test_text_signature.rs +++ b/tests/test_text_signature.rs @@ -120,7 +120,7 @@ fn test_function() { #[test] fn test_pyfn() { #[pymodule] - fn my_module(_py: Python, m: &PyModule) -> PyResult<()> { + fn my_module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pyfn(m, a, b = "None", "*", c = 42)] #[pyo3(text_signature = "(a, b=None, *, c=42)")] fn my_function(a: i32, b: Option, c: i32) { diff --git a/tests/test_various.rs b/tests/test_various.rs index e830d8ca..b0053d10 100644 --- a/tests/test_various.rs +++ b/tests/test_various.rs @@ -18,7 +18,7 @@ impl MutRefArg { fn get(&self) -> i32 { self.n } - fn set_other(&self, mut other: PyRefMut) { + fn set_other(&self, mut other: PyRefMut<'_, MutRefArg>) { other.n = 100; } } @@ -137,7 +137,7 @@ impl PickleSupport { } } -fn add_module(py: Python, module: &PyModule) -> PyResult<()> { +fn add_module(py: Python<'_>, module: &PyModule) -> PyResult<()> { py.import("sys")? .dict() .get_item("modules") @@ -182,7 +182,7 @@ struct MyError { } impl fmt::Display for MyError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "My error message: {}", self.descr) } } diff --git a/tests/test_wrap_pyfunction_deduction.rs b/tests/test_wrap_pyfunction_deduction.rs index 4adb3975..8723ad43 100644 --- a/tests/test_wrap_pyfunction_deduction.rs +++ b/tests/test_wrap_pyfunction_deduction.rs @@ -5,7 +5,7 @@ use pyo3::{prelude::*, types::PyCFunction}; #[pyfunction] fn f() {} -pub fn add_wrapped(wrapper: &impl Fn(Python) -> PyResult<&PyCFunction>) { +pub fn add_wrapped(wrapper: &impl Fn(Python<'_>) -> PyResult<&PyCFunction>) { let _ = wrapper; } diff --git a/tests/ui/invalid_macro_args.rs b/tests/ui/invalid_macro_args.rs index 677c0cfb..f64ed4b5 100644 --- a/tests/ui/invalid_macro_args.rs +++ b/tests/ui/invalid_macro_args.rs @@ -1,32 +1,32 @@ use pyo3::prelude::*; #[pyfunction(a = 5, b)] -fn pos_after_kw(py: Python, a: i32, b: i32) -> PyObject { +fn pos_after_kw(py: Python<'_>, a: i32, b: i32) -> PyObject { [a.to_object(py), vararg.into()].to_object(py) } #[pyfunction(kwargs = "**", a = 5)] -fn kw_after_kwargs(py: Python, kwargs: &PyDict, a: i32) -> PyObject { +fn kw_after_kwargs(py: Python<'_>, kwargs: &PyDict, a: i32) -> PyObject { [a.to_object(py), vararg.into()].to_object(py) } #[pyfunction(a, "*", b, "/", c)] -fn pos_only_after_kw_only(py: Python, a: i32, b: i32, c: i32) -> i32 { +fn pos_only_after_kw_only(py: Python<'_>, a: i32, b: i32, c: i32) -> i32 { a + b + c } #[pyfunction(a, args="*", "/", b)] -fn pos_only_after_args(py: Python, a: i32, args: Vec, b: i32) -> i32 { +fn pos_only_after_args(py: Python<'_>, a: i32, args: Vec, b: i32) -> i32 { a + b + c } #[pyfunction(a, kwargs="**", "/", b)] -fn pos_only_after_kwargs(py: Python, a: i32, args: Vec, b: i32) -> i32 { +fn pos_only_after_kwargs(py: Python<'_>, a: i32, args: Vec, b: i32) -> i32 { a + b } #[pyfunction(kwargs = "**", "*", a)] -fn kw_only_after_kwargs(py: Python, kwargs: &PyDict, a: i32) -> PyObject { +fn kw_only_after_kwargs(py: Python<'_>, kwargs: &PyDict, a: i32) -> PyObject { [a.to_object(py), vararg.into()].to_object(py) } diff --git a/tests/ui/invalid_need_module_arg_position.rs b/tests/ui/invalid_need_module_arg_position.rs index b8837031..b3722ae4 100644 --- a/tests/ui/invalid_need_module_arg_position.rs +++ b/tests/ui/invalid_need_module_arg_position.rs @@ -1,7 +1,7 @@ use pyo3::prelude::*; #[pymodule] -fn module(_py: Python, m: &PyModule) -> PyResult<()> { +fn module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { #[pyfn(m, pass_module)] fn fail(string: &str, module: &PyModule) -> PyResult<&str> { module.name() diff --git a/tests/ui/invalid_property_args.rs b/tests/ui/invalid_property_args.rs index c1049946..3f335952 100644 --- a/tests/ui/invalid_property_args.rs +++ b/tests/ui/invalid_property_args.rs @@ -6,7 +6,7 @@ struct ClassWithGetter {} #[pymethods] impl ClassWithGetter { #[getter] - fn getter_with_arg(&self, py: Python, index: u32) {} + fn getter_with_arg(&self, py: Python<'_>, index: u32) {} } #[pyclass] @@ -15,13 +15,13 @@ struct ClassWithSetter {} #[pymethods] impl ClassWithSetter { #[setter] - fn setter_with_no_arg(&mut self, py: Python) {} + fn setter_with_no_arg(&mut self, py: Python<'_>) {} } #[pymethods] impl ClassWithSetter { #[setter] - fn setter_with_too_many_args(&mut self, py: Python, foo: u32, bar: u32) {} + fn setter_with_too_many_args(&mut self, py: Python<'_>, foo: u32, bar: u32) {} } #[pyclass] diff --git a/tests/ui/invalid_property_args.stderr b/tests/ui/invalid_property_args.stderr index 2147682c..74260550 100644 --- a/tests/ui/invalid_property_args.stderr +++ b/tests/ui/invalid_property_args.stderr @@ -1,20 +1,20 @@ error: getter function can only have one argument (of type pyo3::Python) - --> tests/ui/invalid_property_args.rs:9:50 + --> tests/ui/invalid_property_args.rs:9:54 | -9 | fn getter_with_arg(&self, py: Python, index: u32) {} - | ^^^ +9 | fn getter_with_arg(&self, py: Python<'_>, index: u32) {} + | ^^^ error: setter function expected to have one argument --> tests/ui/invalid_property_args.rs:18:8 | -18 | fn setter_with_no_arg(&mut self, py: Python) {} +18 | fn setter_with_no_arg(&mut self, py: Python<'_>) {} | ^^^^^^^^^^^^^^^^^^ error: setter function can have at most two arguments ([pyo3::Python,] and value) - --> tests/ui/invalid_property_args.rs:24:72 + --> tests/ui/invalid_property_args.rs:24:76 | -24 | fn setter_with_too_many_args(&mut self, py: Python, foo: u32, bar: u32) {} - | ^^^ +24 | fn setter_with_too_many_args(&mut self, py: Python<'_>, foo: u32, bar: u32) {} + | ^^^ error: `get` and `set` with tuple struct fields require `name` --> tests/ui/invalid_property_args.rs:28:50 diff --git a/tests/ui/invalid_pymethod_proto_args_py.rs b/tests/ui/invalid_pymethod_proto_args_py.rs index e5f9345f..33c6fe82 100644 --- a/tests/ui/invalid_pymethod_proto_args_py.rs +++ b/tests/ui/invalid_pymethod_proto_args_py.rs @@ -5,7 +5,7 @@ struct MyClass {} #[pymethods] impl MyClass { - fn __truediv__(&self, _py: Python) -> PyResult<()> { + fn __truediv__(&self, _py: Python<'_>) -> PyResult<()> { Ok(()) } } diff --git a/tests/ui/invalid_pymethod_proto_args_py.stderr b/tests/ui/invalid_pymethod_proto_args_py.stderr index 5661ed45..5b0aca19 100644 --- a/tests/ui/invalid_pymethod_proto_args_py.stderr +++ b/tests/ui/invalid_pymethod_proto_args_py.stderr @@ -1,5 +1,5 @@ error: Expected 1 arguments, got 0 --> tests/ui/invalid_pymethod_proto_args_py.rs:8:8 | -8 | fn __truediv__(&self, _py: Python) -> PyResult<()> { +8 | fn __truediv__(&self, _py: Python<'_>) -> PyResult<()> { | ^^^^^^^^^^^ diff --git a/tests/ui/invalid_pymethod_receiver.rs b/tests/ui/invalid_pymethod_receiver.rs index f85d30d5..77832e12 100644 --- a/tests/ui/invalid_pymethod_receiver.rs +++ b/tests/ui/invalid_pymethod_receiver.rs @@ -5,7 +5,7 @@ struct MyClass {} #[pymethods] impl MyClass { - fn method_with_invalid_self_type(slf: i32, py: Python, index: u32) {} + fn method_with_invalid_self_type(slf: i32, py: Python<'_>, index: u32) {} } fn main() {} diff --git a/tests/ui/invalid_pymethod_receiver.stderr b/tests/ui/invalid_pymethod_receiver.stderr index 09057ae7..fec45af8 100644 --- a/tests/ui/invalid_pymethod_receiver.stderr +++ b/tests/ui/invalid_pymethod_receiver.stderr @@ -1,7 +1,7 @@ error[E0277]: the trait bound `i32: From<&PyCell>` is not satisfied --> tests/ui/invalid_pymethod_receiver.rs:8:43 | -8 | fn method_with_invalid_self_type(slf: i32, py: Python, index: u32) {} +8 | fn method_with_invalid_self_type(slf: i32, py: Python<'_>, index: u32) {} | ^^^ the trait `From<&PyCell>` is not implemented for `i32` | = help: the following implementations were found: diff --git a/tests/ui/invalid_pymodule_args.rs b/tests/ui/invalid_pymodule_args.rs index a11ec937..ebd229ee 100644 --- a/tests/ui/invalid_pymodule_args.rs +++ b/tests/ui/invalid_pymodule_args.rs @@ -1,7 +1,7 @@ use pyo3::prelude::*; #[pymodule(some_arg)] -fn module(_py: Python, m: &PyModule) -> PyResult<()> { +fn module(_py: Python<'_>, m: &PyModule) -> PyResult<()> { Ok(()) } diff --git a/tests/ui/invalid_result_conversion.rs b/tests/ui/invalid_result_conversion.rs index c053edea..53770248 100644 --- a/tests/ui/invalid_result_conversion.rs +++ b/tests/ui/invalid_result_conversion.rs @@ -13,7 +13,7 @@ struct MyError { } impl fmt::Display for MyError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "My error message: {}", self.descr) } } diff --git a/tests/ui/not_send.rs b/tests/ui/not_send.rs index d7c47dec..6566f2d7 100644 --- a/tests/ui/not_send.rs +++ b/tests/ui/not_send.rs @@ -1,6 +1,6 @@ use pyo3::prelude::*; -fn test_not_send_allow_threads(py: Python) { +fn test_not_send_allow_threads(py: Python<'_>) { py.allow_threads(|| { drop(py); }); } diff --git a/tests/ui/not_send_auto_trait.rs b/tests/ui/not_send_auto_trait.rs index d7c47dec..6566f2d7 100644 --- a/tests/ui/not_send_auto_trait.rs +++ b/tests/ui/not_send_auto_trait.rs @@ -1,6 +1,6 @@ use pyo3::prelude::*; -fn test_not_send_allow_threads(py: Python) { +fn test_not_send_allow_threads(py: Python<'_>) { py.allow_threads(|| { drop(py); }); } From 1b9763fef2627e09a4900c8d0c262b672fb93e09 Mon Sep 17 00:00:00 2001 From: mejrs Date: Wed, 23 Mar 2022 10:10:35 +0100 Subject: [PATCH 2/3] Fix merge conflict --- pyo3-macros-backend/src/attributes.rs | 8 ++++---- pyo3-macros-backend/src/pyclass.rs | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pyo3-macros-backend/src/attributes.rs b/pyo3-macros-backend/src/attributes.rs index 111e8ca8..2b63f0cf 100644 --- a/pyo3-macros-backend/src/attributes.rs +++ b/pyo3-macros-backend/src/attributes.rs @@ -42,7 +42,7 @@ pub struct KeywordAttribute { pub struct LitStrValue(pub T); impl Parse for LitStrValue { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lit_str: LitStr = input.parse()?; lit_str.parse().map(LitStrValue) } @@ -59,7 +59,7 @@ impl ToTokens for LitStrValue { pub struct NameLitStr(pub Ident); impl Parse for NameLitStr { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let string_literal: LitStr = input.parse()?; if let Ok(ident) = string_literal.parse() { Ok(NameLitStr(ident)) @@ -82,7 +82,7 @@ pub type NameAttribute = KeywordAttribute; pub type TextSignatureAttribute = KeywordAttribute; impl Parse for KeywordAttribute { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let kw: K = input.parse()?; let _: Token![=] = input.parse()?; let value = input.parse()?; @@ -152,4 +152,4 @@ pub fn take_pyo3_options(attrs: &mut Vec) -> Result Result { + fn parse(input: ParseStream<'_>, kind: PyClassKind) -> Result { Ok(PyClassArgs { class_kind: kind, options: PyClassPyO3Options::parse(input)?, @@ -39,11 +39,11 @@ impl PyClassArgs { }) } - pub fn parse_stuct_args(input: ParseStream) -> syn::Result { + pub fn parse_stuct_args(input: ParseStream<'_>) -> syn::Result { Self::parse(input, PyClassKind::Struct) } - pub fn parse_enum_args(input: ParseStream) -> syn::Result { + pub fn parse_enum_args(input: ParseStream<'_>) -> syn::Result { Self::parse(input, PyClassKind::Enum) } } @@ -80,7 +80,7 @@ enum PyClassPyO3Option { } impl Parse for PyClassPyO3Option { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(Token![crate]) { input.parse().map(PyClassPyO3Option::Crate) @@ -111,7 +111,7 @@ impl Parse for PyClassPyO3Option { } impl PyClassPyO3Options { - fn parse(input: ParseStream) -> syn::Result { + fn parse(input: ParseStream<'_>) -> syn::Result { let mut options: PyClassPyO3Options = Default::default(); for option in Punctuated::::parse_terminated(input)? { @@ -220,7 +220,7 @@ enum FieldPyO3Option { } impl Parse for FieldPyO3Option { - fn parse(input: ParseStream) -> Result { + fn parse(input: ParseStream<'_>) -> Result { let lookahead = input.lookahead1(); if lookahead.peek(attributes::kw::get) { input.parse().map(FieldPyO3Option::Get) @@ -391,7 +391,7 @@ pub fn build_py_enum( } fn impl_enum( - enum_: PyClassEnum, + enum_: PyClassEnum<'_>, args: &PyClassArgs, doc: PythonDoc, methods_type: PyClassMethodsType, @@ -401,7 +401,7 @@ fn impl_enum( } fn impl_enum_class( - enum_: PyClassEnum, + enum_: PyClassEnum<'_>, args: &PyClassArgs, doc: PythonDoc, methods_type: PyClassMethodsType, @@ -545,7 +545,7 @@ fn enum_default_slots( gen_default_items(cls, default_items).collect() } -fn extract_variant_data(variant: &syn::Variant) -> syn::Result { +fn extract_variant_data(variant: &syn::Variant) -> syn::Result> { use syn::Fields; let ident = match variant.fields { Fields::Unit => &variant.ident, @@ -925,4 +925,4 @@ fn define_inventory_class(inventory_class_name: &syn::Ident) -> TokenStream { _pyo3::inventory::collect!(#inventory_class_name); } -} \ No newline at end of file +} From 00ea040834cf0816da29cc13c13715810d0741c6 Mon Sep 17 00:00:00 2001 From: mejrs Date: Wed, 23 Mar 2022 13:30:32 +0100 Subject: [PATCH 3/3] Feedback --- pyo3-build-config/src/lib.rs | 2 ++ pyo3-ffi/src/lib.rs | 1 + pyo3-macros-backend/src/lib.rs | 1 + src/lib.rs | 3 ++- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pyo3-build-config/src/lib.rs b/pyo3-build-config/src/lib.rs index 8a52fe0d..107e0ad8 100644 --- a/pyo3-build-config/src/lib.rs +++ b/pyo3-build-config/src/lib.rs @@ -5,6 +5,8 @@ //! //! It used internally by the PyO3 crate's build script to apply the same configuration. +#![warn(elided_lifetimes_in_paths, unused_lifetimes)] + mod errors; mod impl_; diff --git a/pyo3-ffi/src/lib.rs b/pyo3-ffi/src/lib.rs index 562cfcba..efea47c2 100644 --- a/pyo3-ffi/src/lib.rs +++ b/pyo3-ffi/src/lib.rs @@ -252,6 +252,7 @@ clippy::upper_case_acronyms, clippy::missing_safety_doc )] +#![warn(elided_lifetimes_in_paths, unused_lifetimes)] // Until `extern type` is stabilized, use the recommended approach to // model opaque types: diff --git a/pyo3-macros-backend/src/lib.rs b/pyo3-macros-backend/src/lib.rs index fd6ec4a4..7ed8e504 100644 --- a/pyo3-macros-backend/src/lib.rs +++ b/pyo3-macros-backend/src/lib.rs @@ -1,6 +1,7 @@ // Copyright (c) 2017-present PyO3 Project and Contributors //! This crate contains the implementation of the proc macro attributes +#![warn(elided_lifetimes_in_paths, unused_lifetimes)] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![recursion_limit = "1024"] diff --git a/src/lib.rs b/src/lib.rs index 0c166ace..ce2a1e24 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ rustdoc::bare_urls ) )] +#![warn(elided_lifetimes_in_paths, unused_lifetimes)] // Deny some lints in doctests. // Use `#[allow(...)]` locally to override. #![doc(test(attr( @@ -234,7 +235,7 @@ //! let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'"; //! let user: String = py.eval(code, None, Some(&locals))?.extract()?; //! -//! println!("Hello {}, I'm Python<'_> {}", user, version); +//! println!("Hello {}, I'm Python {}", user, version); //! Ok(()) //! }) //! }