diff --git a/README.md b/README.md index 1a4fefb4b..5a7231d1a 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ use numpy::{IntoPyArray, PyArrayDyn, PyReadonlyArrayDyn}; use pyo3::{pymodule, types::PyModule, PyResult, Python}; #[pymodule] -fn rust_ext(_py: Python<'_>, m: &PyModule) -> PyResult<()> { +fn rust_exty<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { // example using immutable borrows producing a new array fn axpy(a: f64, x: ArrayViewD<'_, f64>, y: ArrayViewD<'_, f64>) -> ArrayD { a * &x + &y @@ -65,8 +65,8 @@ fn rust_ext(_py: Python<'_>, m: &PyModule) -> PyResult<()> { fn axpy_py<'py>( py: Python<'py>, a: f64, - x: PyReadonlyArrayDyn, - y: PyReadonlyArrayDyn, + x: PyReadonlyArrayDyn<'py, f64>, + y: PyReadonlyArrayDyn<'py, f64>, ) -> &'py PyArrayDyn { let x = x.as_array(); let y = y.as_array(); @@ -77,7 +77,7 @@ fn rust_ext(_py: Python<'_>, m: &PyModule) -> PyResult<()> { // wrapper of `mult` #[pyfn(m)] #[pyo3(name = "mult")] - fn mult_py(_py: Python<'_>, a: f64, x: &PyArrayDyn) { + fn mult_py<'py>(a: f64, x: &PyArrayDyn<'py, f64>) { let x = unsafe { x.as_array_mut() }; mult(a, x); } diff --git a/examples/linalg/src/lib.rs b/examples/linalg/src/lib.rs index 7b0b20a5e..4a904718a 100755 --- a/examples/linalg/src/lib.rs +++ b/examples/linalg/src/lib.rs @@ -3,9 +3,9 @@ use numpy::{IntoPyArray, PyArray2, PyReadonlyArray2}; use pyo3::{exceptions::PyRuntimeError, pymodule, types::PyModule, PyResult, Python}; #[pymodule] -fn rust_linalg(_py: Python, m: &PyModule) -> PyResult<()> { +fn rust_linalg<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { #[pyfn(m)] - fn inv<'py>(py: Python<'py>, x: PyReadonlyArray2) -> PyResult<&'py PyArray2> { + fn inv<'py>(py: Python<'py>, x: PyReadonlyArray2<'py, f64>) -> PyResult<&'py PyArray2> { let x = x.as_array(); let y = x .inv() diff --git a/examples/parallel/src/lib.rs b/examples/parallel/src/lib.rs index cc20dc039..2a12d406f 100755 --- a/examples/parallel/src/lib.rs +++ b/examples/parallel/src/lib.rs @@ -6,12 +6,12 @@ use numpy::{IntoPyArray, PyArray1, PyReadonlyArray1, PyReadonlyArray2}; use pyo3::{pymodule, types::PyModule, PyResult, Python}; #[pymodule] -fn rust_parallel(_py: Python, m: &PyModule) -> PyResult<()> { +fn rust_parallel<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { #[pyfn(m)] fn rows_dot<'py>( py: Python<'py>, - x: PyReadonlyArray2, - y: PyReadonlyArray1, + x: PyReadonlyArray2<'py, f64>, + y: PyReadonlyArray1<'py, f64>, ) -> &'py PyArray1 { let x = x.as_array(); let y = y.as_array(); diff --git a/examples/simple/src/lib.rs b/examples/simple/src/lib.rs index cdd4d9b6a..6c1267e5b 100644 --- a/examples/simple/src/lib.rs +++ b/examples/simple/src/lib.rs @@ -14,38 +14,41 @@ use pyo3::{ }; #[pymodule] -fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> { +fn rust_ext<'py>(_py: Python<'py>, m: &'py PyModule) -> PyResult<()> { // example using generic PyObject - fn head(x: ArrayViewD) -> PyResult { + fn head(x: ArrayViewD<'_, PyObject>) -> PyResult { x.get(0) .cloned() .ok_or_else(|| PyIndexError::new_err("array index out of range")) } // example using immutable borrows producing a new array - fn axpy(a: f64, x: ArrayViewD, y: ArrayViewD) -> ArrayD { + fn axpy(a: f64, x: ArrayViewD<'_, f64>, y: ArrayViewD<'_, f64>) -> ArrayD { a * &x + &y } // example using a mutable borrow to modify an array in-place - fn mult(a: f64, mut x: ArrayViewMutD) { + fn mult(a: f64, mut x: ArrayViewMutD<'_, f64>) { x *= a; } // example using complex numbers - fn conj(x: ArrayViewD) -> ArrayD { + fn conj(x: ArrayViewD<'_, Complex64>) -> ArrayD { x.map(|c| c.conj()) } // example using generics - fn generic_add>(x: ArrayView1, y: ArrayView1) -> Array1 { + fn generic_add>( + x: ArrayView1<'_, T>, + y: ArrayView1<'_, T>, + ) -> Array1 { &x + &y } // wrapper of `head` #[pyfn(m)] #[pyo3(name = "head")] - fn head_py(_py: Python, x: PyReadonlyArrayDyn) -> PyResult { + fn head_py<'py>(x: PyReadonlyArrayDyn<'py, PyObject>) -> PyResult { head(x.as_array()) } @@ -55,8 +58,8 @@ fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> { fn axpy_py<'py>( py: Python<'py>, a: f64, - x: PyReadonlyArrayDyn, - y: PyReadonlyArrayDyn, + x: PyReadonlyArrayDyn<'py, f64>, + y: PyReadonlyArrayDyn<'py, f64>, ) -> &'py PyArrayDyn { let x = x.as_array(); let y = y.as_array(); @@ -67,7 +70,7 @@ fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> { // wrapper of `mult` #[pyfn(m)] #[pyo3(name = "mult")] - fn mult_py(a: f64, mut x: PyReadwriteArrayDyn) { + fn mult_py<'py>(a: f64, mut x: PyReadwriteArrayDyn<'py, f64>) { let x = x.as_array_mut(); mult(a, x); } @@ -77,7 +80,7 @@ fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> { #[pyo3(name = "conj")] fn conj_py<'py>( py: Python<'py>, - x: PyReadonlyArrayDyn, + x: PyReadonlyArrayDyn<'py, Complex64>, ) -> &'py PyArrayDyn { conj(x.as_array()).into_pyarray(py) } @@ -96,9 +99,9 @@ fn rust_ext(_py: Python, m: &PyModule) -> PyResult<()> { // example using timedelta64 array #[pyfn(m)] - fn add_minutes_to_seconds( - mut x: PyReadwriteArray1>, - y: PyReadonlyArray1>, + fn add_minutes_to_seconds<'py>( + mut x: PyReadwriteArray1<'py, Timedelta>, + y: PyReadonlyArray1<'py, Timedelta>, ) { #[allow(deprecated)] Zip::from(x.as_array_mut()) diff --git a/src/array.rs b/src/array.rs index bf242d713..4bdf7fa4b 100644 --- a/src/array.rs +++ b/src/array.rs @@ -118,7 +118,7 @@ pub type PyArray6 = PyArray; pub type PyArrayDyn = PyArray; /// Returns a handle to NumPy's multiarray module. -pub fn get_array_module(py: Python<'_>) -> PyResult<&PyModule> { +pub fn get_array_module<'py>(py: Python<'py>) -> PyResult<&PyModule> { PyModule::import(py, npyffi::array::MOD_NAME) } @@ -128,7 +128,7 @@ unsafe impl PyTypeInfo for PyArray { const NAME: &'static str = "PyArray"; const MODULE: Option<&'static str> = Some("numpy"); - fn type_object_raw(py: Python) -> *mut ffi::PyTypeObject { + fn type_object_raw<'py>(py: Python<'py>) -> *mut ffi::PyTypeObject { unsafe { npyffi::PY_ARRAY_API.get_type_object(py, npyffi::NpyTypes::PyArray_Type) } } @@ -164,7 +164,7 @@ impl AsPyPointer for PyArray { impl IntoPy>> for &'_ PyArray { #[inline] - fn into_py(self, py: Python<'_>) -> Py> { + fn into_py<'py>(self, py: Python<'py>) -> Py> { unsafe { Py::from_borrowed_ptr(py, self.as_ptr()) } } } @@ -183,7 +183,7 @@ impl<'a, T, D> From<&'a PyArray> for &'a PyAny { } impl IntoPy for PyArray { - fn into_py(self, py: Python<'_>) -> PyObject { + fn into_py<'py>(self, py: Python<'py>) -> PyObject { unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } @@ -327,7 +327,7 @@ impl PyArray { /// assert_eq!(arr.shape(), &[4, 5, 6]); /// }); /// ``` - pub unsafe fn new(py: Python, dims: ID, is_fortran: bool) -> &Self + pub unsafe fn new<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self where ID: IntoDimension, { @@ -335,8 +335,8 @@ impl PyArray { Self::new_uninit(py, dims, ptr::null_mut(), flags) } - pub(crate) unsafe fn new_uninit( - py: Python, + pub(crate) unsafe fn new_uninit<'py, ID>( + py: Python<'py>, dims: ID, strides: *const npy_intp, flag: c_int, @@ -484,7 +484,7 @@ impl PyArray { /// /// [numpy-zeros]: https://numpy.org/doc/stable/reference/generated/numpy.zeros.html /// [PyArray_Zeros]: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_Zeros - pub fn zeros(py: Python, dims: ID, is_fortran: bool) -> &Self + pub fn zeros<'py, ID>(py: Python<'py>, dims: ID, is_fortran: bool) -> &Self where ID: IntoDimension, { @@ -989,7 +989,7 @@ where #[doc(alias = "nalgebra")] pub unsafe fn try_as_matrix( &self, - ) -> Option> + ) -> Option> where R: nalgebra::Dim, C: nalgebra::Dim, @@ -1011,7 +1011,7 @@ where #[doc(alias = "nalgebra")] pub unsafe fn try_as_matrix_mut( &self, - ) -> Option> + ) -> Option> where R: nalgebra::Dim, C: nalgebra::Dim, @@ -1144,7 +1144,7 @@ impl PyArray { /// assert_eq!(pyarray.readonly().as_slice().unwrap(), &[97, 98, 99, 100, 101]); /// }); /// ``` - pub fn from_iter(py: Python<'_>, iter: I) -> &Self + pub fn from_iter<'py, I>(py: Python<'py>, iter: I) -> &'py Self where I: IntoIterator, { @@ -1448,7 +1448,7 @@ impl> PyArray { /// /// [numpy.arange]: https://numpy.org/doc/stable/reference/generated/numpy.arange.html /// [PyArray_Arange]: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_Arange - pub fn arange(py: Python, start: T, stop: T, step: T) -> &Self { + pub fn arange<'py>(py: Python<'py>, start: T, stop: T, step: T) -> &Self { unsafe { let ptr = PY_ARRAY_API.PyArray_Arange( py, diff --git a/src/borrow/mod.rs b/src/borrow/mod.rs index 9009072d2..6f48c757e 100644 --- a/src/borrow/mod.rs +++ b/src/borrow/mod.rs @@ -246,7 +246,7 @@ where /// Provides an immutable array view of the interior of the NumPy array. #[inline(always)] - pub fn as_array(&self) -> ArrayView { + pub fn as_array(&self) -> ArrayView<'_, T, D> { // SAFETY: Global borrow flags ensure aliasing discipline. unsafe { self.array.as_array() } } @@ -278,7 +278,7 @@ where #[doc(alias = "nalgebra")] pub fn try_as_matrix( &self, - ) -> Option> + ) -> Option> where R: nalgebra::Dim, C: nalgebra::Dim, @@ -300,7 +300,7 @@ where /// /// Panics if the array has negative strides. #[doc(alias = "nalgebra")] - pub fn as_matrix(&self) -> nalgebra::DMatrixView { + pub fn as_matrix(&self) -> nalgebra::DMatrixView<'_, N, nalgebra::Dyn, nalgebra::Dyn> { self.try_as_matrix().unwrap() } } @@ -316,7 +316,7 @@ where /// /// Panics if the array has negative strides. #[doc(alias = "nalgebra")] - pub fn as_matrix(&self) -> nalgebra::DMatrixView { + pub fn as_matrix(&self) -> nalgebra::DMatrixView<'_, N, nalgebra::Dyn, nalgebra::Dyn> { self.try_as_matrix().unwrap() } } @@ -428,7 +428,7 @@ where /// Provides a mutable array view of the interior of the NumPy array. #[inline(always)] - pub fn as_array_mut(&mut self) -> ArrayViewMut { + pub fn as_array_mut(&mut self) -> ArrayViewMut<'_, T, D> { // SAFETY: Global borrow flags ensure aliasing discipline. unsafe { self.array.as_array_mut() } } @@ -460,7 +460,7 @@ where #[doc(alias = "nalgebra")] pub fn try_as_matrix_mut( &self, - ) -> Option> + ) -> Option> where R: nalgebra::Dim, C: nalgebra::Dim, @@ -482,7 +482,7 @@ where /// /// Panics if the array has negative strides. #[doc(alias = "nalgebra")] - pub fn as_matrix_mut(&self) -> nalgebra::DMatrixViewMut { + pub fn as_matrix_mut(&self) -> nalgebra::DMatrixViewMut<'_, N, nalgebra::Dyn, nalgebra::Dyn> { self.try_as_matrix_mut().unwrap() } } @@ -498,7 +498,7 @@ where /// /// Panics if the array has negative strides. #[doc(alias = "nalgebra")] - pub fn as_matrix_mut(&self) -> nalgebra::DMatrixViewMut { + pub fn as_matrix_mut(&self) -> nalgebra::DMatrixViewMut<'_, N, nalgebra::Dyn, nalgebra::Dyn> { self.try_as_matrix_mut().unwrap() } } diff --git a/src/borrow/shared.rs b/src/borrow/shared.rs index 2193f36ef..23590be2f 100644 --- a/src/borrow/shared.rs +++ b/src/borrow/shared.rs @@ -121,7 +121,7 @@ fn get_or_insert_shared<'py>(py: Python<'py>) -> PyResult<&'py Shared> { // immediately initialize the cache used access it from this extension. #[cold] -fn insert_shared(py: Python) -> PyResult<*const Shared> { +fn insert_shared<'py>(py: Python<'py>) -> PyResult<*const Shared> { let module = get_array_module(py)?; let capsule: &PyCapsule = match module.getattr("_RUST_NUMPY_BORROW_CHECKING_API") { @@ -170,7 +170,7 @@ fn insert_shared(py: Python) -> PyResult<*const Shared> { // These entry points will be used to access the shared borrow checking API from this extension: -pub fn acquire(py: Python, array: *mut PyArrayObject) -> Result<(), BorrowError> { +pub fn acquire<'py>(py: Python<'py>, array: *mut PyArrayObject) -> Result<(), BorrowError> { let shared = get_or_insert_shared(py).expect("Interal borrow checking API error"); let rc = unsafe { (shared.acquire)(shared.flags, array) }; @@ -182,7 +182,7 @@ pub fn acquire(py: Python, array: *mut PyArrayObject) -> Result<(), BorrowError> } } -pub fn acquire_mut(py: Python, array: *mut PyArrayObject) -> Result<(), BorrowError> { +pub fn acquire_mut<'py>(py: Python<'py>, array: *mut PyArrayObject) -> Result<(), BorrowError> { let shared = get_or_insert_shared(py).expect("Interal borrow checking API error"); let rc = unsafe { (shared.acquire_mut)(shared.flags, array) }; @@ -195,7 +195,7 @@ pub fn acquire_mut(py: Python, array: *mut PyArrayObject) -> Result<(), BorrowEr } } -pub fn release(py: Python, array: *mut PyArrayObject) { +pub fn release<'py>(py: Python<'py>, array: *mut PyArrayObject) { let shared = get_or_insert_shared(py).expect("Interal borrow checking API error"); unsafe { @@ -203,7 +203,7 @@ pub fn release(py: Python, array: *mut PyArrayObject) { } } -pub fn release_mut(py: Python, array: *mut PyArrayObject) { +pub fn release_mut<'py>(py: Python<'py>, array: *mut PyArrayObject) { let shared = get_or_insert_shared(py).expect("Interal borrow checking API error"); unsafe { @@ -365,7 +365,7 @@ impl BorrowFlags { } } -fn base_address(py: Python, mut array: *mut PyArrayObject) -> *mut c_void { +fn base_address<'py>(py: Python<'py>, mut array: *mut PyArrayObject) -> *mut c_void { loop { let base = unsafe { (*array).base }; @@ -450,7 +450,7 @@ mod tests { use crate::array::{PyArray, PyArray1, PyArray2, PyArray3}; use crate::convert::IntoPyArray; - fn get_borrow_flags<'py>(py: Python) -> &'py BorrowFlagsInner { + fn get_borrow_flags<'py>(py: Python<'py>) -> &'py BorrowFlagsInner { let shared = get_or_insert_shared(py).unwrap(); assert_eq!(shared.version, 1); unsafe { &(*(shared.flags as *mut BorrowFlags)).0 } diff --git a/src/datetime.rs b/src/datetime.rs index f5df21211..3800e2a32 100644 --- a/src/datetime.rs +++ b/src/datetime.rs @@ -156,7 +156,7 @@ impl From> for i64 { unsafe impl Element for Datetime { const IS_COPY: bool = true; - fn get_dtype(py: Python) -> &PyArrayDescr { + fn get_dtype<'py>(py: Python<'py>) -> &'py PyArrayDescr { static DTYPES: TypeDescriptors = unsafe { TypeDescriptors::new(NPY_TYPES::NPY_DATETIME) }; DTYPES.from_unit(py, U::UNIT) @@ -191,7 +191,7 @@ impl From> for i64 { unsafe impl Element for Timedelta { const IS_COPY: bool = true; - fn get_dtype(py: Python) -> &PyArrayDescr { + fn get_dtype<'py>(py: Python<'py>) -> &'py PyArrayDescr { static DTYPES: TypeDescriptors = unsafe { TypeDescriptors::new(NPY_TYPES::NPY_TIMEDELTA) }; DTYPES.from_unit(py, U::UNIT) @@ -314,7 +314,7 @@ mod tests { #[test] fn unit_conversion() { #[track_caller] - fn convert(py: Python<'_>, expected_value: i64) { + fn convert<'py, S: Unit, D: Unit>(py: Python<'py>, expected_value: i64) { let array = PyArray1::>::from_slice(py, &[Timedelta::::from(1)]); let array = array.cast::>(false).unwrap(); diff --git a/src/dtype.rs b/src/dtype.rs index c32113df3..95e3dcdd0 100644 --- a/src/dtype.rs +++ b/src/dtype.rs @@ -59,7 +59,7 @@ unsafe impl PyTypeInfo for PyArrayDescr { const MODULE: Option<&'static str> = Some("numpy"); #[inline] - fn type_object_raw(py: Python) -> *mut ffi::PyTypeObject { + fn type_object_raw<'py>(py: Python<'py>) -> *mut ffi::PyTypeObject { unsafe { PY_ARRAY_API.get_type_object(py, NpyTypes::PyArrayDescr_Type) } } @@ -71,7 +71,7 @@ unsafe impl PyTypeInfo for PyArrayDescr { pyobject_native_type_extract!(PyArrayDescr); /// Returns the type descriptor ("dtype") for a registered type. -pub fn dtype(py: Python) -> &PyArrayDescr { +pub fn dtype<'py, T: Element>(py: Python<'py>) -> &'py PyArrayDescr { T::get_dtype(py) } @@ -108,12 +108,12 @@ impl PyArrayDescr { } /// Shortcut for creating a type descriptor of `object` type. - pub fn object(py: Python) -> &Self { + pub fn object<'py>(py: Python<'py>) -> &'py Self { Self::from_npy_type(py, NPY_TYPES::NPY_OBJECT) } /// Returns the type descriptor for a registered type. - pub fn of(py: Python) -> &Self { + pub fn of<'py, T: Element>(py: Python<'py>) -> &'py Self { T::get_dtype(py) } @@ -128,14 +128,14 @@ impl PyArrayDescr { } } - fn from_npy_type(py: Python, npy_type: NPY_TYPES) -> &Self { + fn from_npy_type<'py>(py: Python<'py>, npy_type: NPY_TYPES) -> &'py Self { unsafe { let descr = PY_ARRAY_API.PyArray_DescrFromType(py, npy_type as _); py.from_owned_ptr(descr as _) } } - pub(crate) fn new_from_npy_type(py: Python, npy_type: NPY_TYPES) -> &Self { + pub(crate) fn new_from_npy_type<'py>(py: Python<'py>, npy_type: NPY_TYPES) -> &'py Self { unsafe { let descr = PY_ARRAY_API.PyArray_DescrNewFromType(py, npy_type as _); py.from_owned_ptr(descr as _) @@ -401,7 +401,7 @@ pub unsafe trait Element: Clone + Send { const IS_COPY: bool; /// Returns the associated type descriptor ("dtype") for the given element type. - fn get_dtype(py: Python) -> &PyArrayDescr; + fn get_dtype<'py>(py: Python<'py>) -> &'py PyArrayDescr; } fn npy_int_type_lookup(npy_types: [NPY_TYPES; 3]) -> NPY_TYPES { @@ -455,7 +455,7 @@ macro_rules! impl_element_scalar { unsafe impl Element for $ty { const IS_COPY: bool = true; - fn get_dtype(py: Python) -> &PyArrayDescr { + fn get_dtype<'py>(py: Python<'py>) -> &'py PyArrayDescr { PyArrayDescr::from_npy_type(py, $npy_type) } } @@ -483,7 +483,7 @@ impl_element_scalar!(f16 => NPY_HALF); unsafe impl Element for bf16 { const IS_COPY: bool = true; - fn get_dtype(py: Python) -> &PyArrayDescr { + fn get_dtype<'py>(py: Python<'py>) -> &PyArrayDescr { static DTYPE: GILOnceCell> = GILOnceCell::new(); DTYPE @@ -506,7 +506,7 @@ impl_element_scalar!(usize, isize); unsafe impl Element for PyObject { const IS_COPY: bool = false; - fn get_dtype(py: Python) -> &PyArrayDescr { + fn get_dtype<'py>(py: Python<'py>) -> &PyArrayDescr { PyArrayDescr::object(py) } } @@ -538,7 +538,7 @@ mod tests { #[test] fn test_dtype_names() { - fn type_name(py: Python) -> &str { + fn type_name<'py, T: Element>(py: Python<'py>) -> &str { dtype::(py).typeobj().name().unwrap() } Python::with_gil(|py| { diff --git a/src/error.rs b/src/error.rs index ca8825b16..1d7b3a20a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -19,7 +19,7 @@ macro_rules! impl_pyerr { impl Error for $err_type {} impl PyErrArguments for $err_type { - fn arguments(self, py: Python) -> PyObject { + fn arguments<'py>(self, py: Python<'py>) -> PyObject { self.to_string().to_object(py) } } @@ -46,7 +46,7 @@ impl DimensionalityError { } impl fmt::Display for DimensionalityError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "dimensionality mismatch:\n from={}, to={}", @@ -71,7 +71,7 @@ impl<'a> TypeError<'a> { } impl fmt::Display for TypeError<'_> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "type mismatch:\n from={}, to={}", self.from, self.to) } } @@ -84,7 +84,7 @@ struct TypeErrorArguments { } impl PyErrArguments for TypeErrorArguments { - fn arguments(self, py: Python) -> PyObject { + fn arguments<'py>(self, py: Python<'py>) -> PyObject { let err = TypeError { from: self.from.as_ref(py), to: self.to.as_ref(py), @@ -119,7 +119,7 @@ impl FromVecError { } impl fmt::Display for FromVecError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!( f, "invalid length: {}, but expected {}", @@ -135,7 +135,7 @@ impl_pyerr!(FromVecError); pub struct NotContiguousError; impl fmt::Display for NotContiguousError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "The given array is not contiguous") } } @@ -153,7 +153,7 @@ pub enum BorrowError { } impl fmt::Display for BorrowError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::AlreadyBorrowed => write!(f, "The given array is already borrowed"), Self::NotWriteable => write!(f, "The given array is not writeable"), diff --git a/src/lib.rs b/src/lib.rs index 04ab7efe0..064226f17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,8 +71,6 @@ as well as the [`PyReadonlyArray::try_as_matrix`] and [`PyReadwriteArray::try_as //! [ndarray]: https://numpy.org/doc/stable/reference/arrays.ndarray.html #![deny(missing_docs, missing_debug_implementations)] -// We often want to make the GIL lifetime explicit. -#![allow(clippy::needless_lifetimes)] pub mod array; pub mod borrow; diff --git a/src/npyffi/array.rs b/src/npyffi/array.rs index f6bbf698a..60c373d22 100644 --- a/src/npyffi/array.rs +++ b/src/npyffi/array.rs @@ -45,7 +45,7 @@ unsafe impl Send for PyArrayAPI {} unsafe impl Sync for PyArrayAPI {} impl PyArrayAPI { - unsafe fn get(&self, py: Python, offset: isize) -> *const *const c_void { + unsafe fn get<'py>(&self, py: Python<'py>, offset: isize) -> *const *const c_void { let api = self .0 .get_or_try_init(py, || get_numpy_api(py, MOD_NAME, CAPSULE_NAME)) @@ -326,7 +326,7 @@ macro_rules! impl_array_type { impl PyArrayAPI { /// Get a pointer of the type object assocaited with `ty`. - pub unsafe fn get_type_object(&self, py: Python, ty: NpyTypes) -> *mut PyTypeObject { + pub unsafe fn get_type_object<'py>(&self, py: Python<'py>, ty: NpyTypes) -> *mut PyTypeObject { match ty { $( NpyTypes::$tname => *(self.get(py, $offset)) as _ ),* } @@ -379,13 +379,13 @@ impl_array_type! { /// Checks that `op` is an instance of `PyArray` or not. #[allow(non_snake_case)] -pub unsafe fn PyArray_Check(py: Python, op: *mut PyObject) -> c_int { +pub unsafe fn PyArray_Check<'py>(py: Python<'py>, op: *mut PyObject) -> c_int { ffi::PyObject_TypeCheck(op, PY_ARRAY_API.get_type_object(py, NpyTypes::PyArray_Type)) } /// Checks that `op` is an exact instance of `PyArray` or not. #[allow(non_snake_case)] -pub unsafe fn PyArray_CheckExact(py: Python, op: *mut PyObject) -> c_int { +pub unsafe fn PyArray_CheckExact<'py>(py: Python<'py>, op: *mut PyObject) -> c_int { (ffi::Py_TYPE(op) == PY_ARRAY_API.get_type_object(py, NpyTypes::PyArray_Type)) as _ } diff --git a/src/npyffi/mod.rs b/src/npyffi/mod.rs index 245e406c2..afc0b425e 100644 --- a/src/npyffi/mod.rs +++ b/src/npyffi/mod.rs @@ -17,7 +17,11 @@ use pyo3::{ Py, PyResult, PyTryInto, Python, }; -fn get_numpy_api(py: Python, module: &str, capsule: &str) -> PyResult<*const *const c_void> { +fn get_numpy_api<'py>( + py: Python<'py>, + module: &str, + capsule: &str, +) -> PyResult<*const *const c_void> { let module = PyModule::import(py, module)?; let capsule: &PyCapsule = PyTryInto::try_into(module.getattr(capsule)?)?; @@ -34,7 +38,7 @@ fn get_numpy_api(py: Python, module: &str, capsule: &str) -> PyResult<*const *co macro_rules! impl_api { [$offset: expr; $fname: ident ( $($arg: ident : $t: ty),* $(,)?) $( -> $ret: ty )* ] => { #[allow(non_snake_case)] - pub unsafe fn $fname(&self, py: Python, $($arg : $t), *) $( -> $ret )* { + pub unsafe fn $fname<'py>(&self, py: Python<'py>, $($arg : $t), *) $( -> $ret )* { let fptr = self.get(py, $offset) as *const extern fn ($($arg : $t), *) $( -> $ret )*; (*fptr)($($arg), *) diff --git a/src/npyffi/ufunc.rs b/src/npyffi/ufunc.rs index 748658e40..c906962ca 100644 --- a/src/npyffi/ufunc.rs +++ b/src/npyffi/ufunc.rs @@ -20,7 +20,7 @@ unsafe impl Send for PyUFuncAPI {} unsafe impl Sync for PyUFuncAPI {} impl PyUFuncAPI { - unsafe fn get(&self, py: Python, offset: isize) -> *const *const c_void { + unsafe fn get<'py>(&self, py: Python<'py>, offset: isize) -> *const *const c_void { let api = self .0 .get_or_try_init(py, || get_numpy_api(py, MOD_NAME, CAPSULE_NAME)) diff --git a/src/strings.rs b/src/strings.rs index f76cc01b4..f42e31e47 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -63,7 +63,7 @@ use crate::npyffi::NPY_TYPES; pub struct PyFixedString(pub [Py_UCS1; N]); impl fmt::Display for PyFixedString { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { fmt.write_str(str::from_utf8(&self.0).unwrap().trim_end_matches('\0')) } } @@ -77,7 +77,7 @@ impl From<[Py_UCS1; N]> for PyFixedString { unsafe impl Element for PyFixedString { const IS_COPY: bool = true; - fn get_dtype(py: Python) -> &PyArrayDescr { + fn get_dtype<'py>(py: Python<'py>) -> &PyArrayDescr { static DTYPES: TypeDescriptors = TypeDescriptors::new(); unsafe { DTYPES.from_size(py, NPY_TYPES::NPY_STRING, b'|' as _, size_of::()) } @@ -126,7 +126,7 @@ unsafe impl Element for PyFixedString { pub struct PyFixedUnicode(pub [Py_UCS4; N]); impl fmt::Display for PyFixedUnicode { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { for character in self.0 { if character == 0 { break; @@ -148,7 +148,7 @@ impl From<[Py_UCS4; N]> for PyFixedUnicode { unsafe impl Element for PyFixedUnicode { const IS_COPY: bool = true; - fn get_dtype(py: Python) -> &PyArrayDescr { + fn get_dtype<'py>(py: Python<'py>) -> &PyArrayDescr { static DTYPES: TypeDescriptors = TypeDescriptors::new(); unsafe { DTYPES.from_size(py, NPY_TYPES::NPY_UNICODE, b'=' as _, size_of::()) } diff --git a/src/untyped_array.rs b/src/untyped_array.rs index 647171dbf..cd873a2b9 100644 --- a/src/untyped_array.rs +++ b/src/untyped_array.rs @@ -66,7 +66,7 @@ unsafe impl PyTypeInfo for PyUntypedArray { const NAME: &'static str = "PyUntypedArray"; const MODULE: Option<&'static str> = Some("numpy"); - fn type_object_raw(py: Python) -> *mut ffi::PyTypeObject { + fn type_object_raw<'py>(py: Python<'py>) -> *mut ffi::PyTypeObject { unsafe { npyffi::PY_ARRAY_API.get_type_object(py, npyffi::NpyTypes::PyArray_Type) } } @@ -78,7 +78,7 @@ unsafe impl PyTypeInfo for PyUntypedArray { pyobject_native_type_named!(PyUntypedArray); impl IntoPy for PyUntypedArray { - fn into_py(self, py: Python<'_>) -> PyObject { + fn into_py<'py>(self, py: Python<'py>) -> PyObject { unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) } } } diff --git a/tests/array.rs b/tests/array.rs index 3564c9c76..48654479c 100644 --- a/tests/array.rs +++ b/tests/array.rs @@ -13,11 +13,11 @@ use pyo3::{ IntoPy, Py, PyAny, PyCell, PyResult, Python, }; -fn get_np_locals(py: Python) -> &PyDict { +fn get_np_locals<'py>(py: Python<'py>) -> &'py PyDict { [("np", get_array_module(py).unwrap())].into_py_dict(py) } -fn not_contiguous_array(py: Python) -> &PyArray1 { +fn not_contiguous_array<'py>(py: Python<'py>) -> &'py PyArray1 { py.eval( "np.array([1, 2, 3, 4], dtype='int32')[::2]", None, diff --git a/tests/borrow.rs b/tests/borrow.rs index 466b0fa32..584940798 100644 --- a/tests/borrow.rs +++ b/tests/borrow.rs @@ -88,9 +88,9 @@ fn borrows_span_frames() { #[pymethods] impl Borrower { - fn shared(&self, _array: PyReadonlyArray3) {} + fn shared(&self, _array: PyReadonlyArray3<'_, f64>) {} - fn exclusive(&self, _array: PyReadwriteArray3) {} + fn exclusive(&self, _array: PyReadwriteArray3<'_, f64>) {} } Python::with_gil(|py| { @@ -290,7 +290,7 @@ fn interleaved_views_do_not_conflict() { fn extract_readonly() { Python::with_gil(|py| { let ob: &PyAny = PyArray::::zeros(py, (1, 2, 3), false); - ob.extract::>().unwrap(); + ob.extract::>().unwrap(); }); } @@ -298,7 +298,7 @@ fn extract_readonly() { fn extract_readwrite() { Python::with_gil(|py| { let ob: &PyAny = PyArray::::zeros(py, (1, 2, 3), false); - ob.extract::>().unwrap(); + ob.extract::>().unwrap(); }); } @@ -356,6 +356,7 @@ fn matrix_from_numpy() { assert_eq!(matrix, nalgebra::Matrix3::new(0, 1, 2, 3, 4, 5, 6, 7, 8)); let matrix: nalgebra::MatrixView< + '_, i32, nalgebra::Const<3>, nalgebra::Const<3>, @@ -372,6 +373,7 @@ fn matrix_from_numpy() { assert_eq!(matrix, nalgebra::Matrix3::new(0, 1, 2, 3, 4, 5, 6, 7, 8)); let matrix: nalgebra::MatrixViewMut< + '_, i32, nalgebra::Const<3>, nalgebra::Const<3>, @@ -391,7 +393,7 @@ fn matrix_from_numpy() { let matrix = array.as_matrix(); assert_eq!(matrix, nalgebra::Matrix3x1::new(0, 1, 2)); - let matrix: nalgebra::MatrixView, nalgebra::Const<1>> = + let matrix: nalgebra::MatrixView<'_, i32, nalgebra::Const<3>, nalgebra::Const<1>> = array.try_as_matrix().unwrap(); assert_eq!(matrix, nalgebra::Matrix3x1::new(0, 1, 2)); } @@ -402,7 +404,7 @@ fn matrix_from_numpy() { let matrix = array.as_matrix_mut(); assert_eq!(matrix, nalgebra::Matrix3x1::new(0, 1, 2)); - let matrix: nalgebra::MatrixViewMut, nalgebra::Const<1>> = + let matrix: nalgebra::MatrixViewMut<'_, i32, nalgebra::Const<3>, nalgebra::Const<1>> = array.try_as_matrix_mut().unwrap(); assert_eq!(matrix, nalgebra::Matrix3x1::new(0, 1, 2)); } @@ -412,7 +414,7 @@ fn matrix_from_numpy() { let array = PyArray::::zeros(py, (2, 2, 2), false); let array = array.readonly(); - let matrix: Option> = + let matrix: Option> = array.try_as_matrix(); assert!(matrix.is_none()); }); @@ -426,7 +428,7 @@ fn matrix_from_numpy() { .unwrap(); let array = array.readonly(); - let matrix: Option> = + let matrix: Option> = array.try_as_matrix(); assert!(matrix.is_none()); }); @@ -437,6 +439,7 @@ fn matrix_from_numpy() { let matrix: Option< nalgebra::MatrixView< + '_, i32, nalgebra::Const<2>, nalgebra::Const<3>, @@ -448,6 +451,7 @@ fn matrix_from_numpy() { let matrix: Option< nalgebra::MatrixView< + '_, i32, nalgebra::Const<3>, nalgebra::Const<2>, @@ -459,6 +463,7 @@ fn matrix_from_numpy() { let matrix: Option< nalgebra::MatrixView< + '_, i32, nalgebra::Const<3>, nalgebra::Const<3>, @@ -470,6 +475,7 @@ fn matrix_from_numpy() { let matrix: Option< nalgebra::MatrixView< + '_, i32, nalgebra::Const<3>, nalgebra::Const<3>, diff --git a/x.py b/x.py index bbf5e6f10..f5a5351ac 100755 --- a/x.py +++ b/x.py @@ -44,6 +44,16 @@ def default(args): def check(args): + LINT_CONFIG = ( + "--deny", + "warnings", + # We usually want to make the GIL lifetime explicit. + "--deny", + "elided-lifetimes-in-paths", + "--allow", + "clippy::needless-lifetimes", + ) + run("cargo", "fmt", "--", "--check") run( @@ -52,8 +62,7 @@ def check(args): "--all-features", "--tests", "--", - "--deny", - "warnings", + *LINT_CONFIG, ) for manifest in gen_examples("Cargo.toml"): @@ -65,8 +74,7 @@ def check(args): "--manifest-path", manifest, "--", - "--deny", - "warnings", + *LINT_CONFIG, )