diff --git a/benches/array.rs b/benches/array.rs index d746e39fb..d81939b56 100644 --- a/benches/array.rs +++ b/benches/array.rs @@ -6,15 +6,15 @@ use test::{black_box, Bencher}; use std::ops::Range; use numpy::{PyArray1, PyArray2, PyArray3}; -use pyo3::{PyAny, Python, ToPyObject}; +use pyo3::{types::PyAnyMethods, Python, ToPyObject}; #[bench] fn extract_success(bencher: &mut Bencher) { Python::with_gil(|py| { - let any: &PyAny = PyArray2::::zeros(py, (10, 10), false); + let any = PyArray2::::zeros_bound(py, (10, 10), false).into_any(); bencher.iter(|| { - black_box(any).extract::<&PyArray2>().unwrap(); + black_box(&any).extract::<&PyArray2>().unwrap(); }); }); } @@ -22,10 +22,10 @@ fn extract_success(bencher: &mut Bencher) { #[bench] fn extract_failure(bencher: &mut Bencher) { Python::with_gil(|py| { - let any: &PyAny = PyArray2::::zeros(py, (10, 10), false); + let any = PyArray2::::zeros_bound(py, (10, 10), false).into_any(); bencher.iter(|| { - black_box(any).extract::<&PyArray2>().unwrap_err(); + black_box(&any).extract::<&PyArray2>().unwrap_err(); }); }); } @@ -33,10 +33,10 @@ fn extract_failure(bencher: &mut Bencher) { #[bench] fn downcast_success(bencher: &mut Bencher) { Python::with_gil(|py| { - let any: &PyAny = PyArray2::::zeros(py, (10, 10), false); + let any = PyArray2::::zeros_bound(py, (10, 10), false).into_any(); bencher.iter(|| { - black_box(any).downcast::>().unwrap(); + black_box(&any).downcast::>().unwrap(); }); }); } @@ -44,10 +44,10 @@ fn downcast_success(bencher: &mut Bencher) { #[bench] fn downcast_failure(bencher: &mut Bencher) { Python::with_gil(|py| { - let any: &PyAny = PyArray2::::zeros(py, (10, 10), false); + let any = PyArray2::::zeros_bound(py, (10, 10), false).into_any(); bencher.iter(|| { - black_box(any).downcast::>().unwrap_err(); + black_box(&any).downcast::>().unwrap_err(); }); }); } diff --git a/benches/borrow.rs b/benches/borrow.rs index eb3eb0cda..79e7dc030 100644 --- a/benches/borrow.rs +++ b/benches/borrow.rs @@ -3,16 +3,16 @@ extern crate test; use test::{black_box, Bencher}; -use numpy::PyArray; +use numpy::{PyArray, PyArrayMethods}; use pyo3::Python; #[bench] fn initial_shared_borrow(bencher: &mut Bencher) { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (6, 5, 4, 3, 2, 1), false); + let array = PyArray::::zeros_bound(py, (6, 5, 4, 3, 2, 1), false); bencher.iter(|| { - let array = black_box(array); + let array = black_box(&array); let _shared = array.readonly(); }); @@ -22,12 +22,12 @@ fn initial_shared_borrow(bencher: &mut Bencher) { #[bench] fn additional_shared_borrow(bencher: &mut Bencher) { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (6, 5, 4, 3, 2, 1), false); + let array = PyArray::::zeros_bound(py, (6, 5, 4, 3, 2, 1), false); let _shared = (0..128).map(|_| array.readonly()).collect::>(); bencher.iter(|| { - let array = black_box(array); + let array = black_box(&array); let _shared = array.readonly(); }); @@ -37,10 +37,10 @@ fn additional_shared_borrow(bencher: &mut Bencher) { #[bench] fn exclusive_borrow(bencher: &mut Bencher) { Python::with_gil(|py| { - let array = PyArray::::zeros(py, (6, 5, 4, 3, 2, 1), false); + let array = PyArray::::zeros_bound(py, (6, 5, 4, 3, 2, 1), false); bencher.iter(|| { - let array = black_box(array); + let array = black_box(&array); let _exclusive = array.readwrite(); }); diff --git a/src/array.rs b/src/array.rs index fc4478086..4d68f7c2e 100644 --- a/src/array.rs +++ b/src/array.rs @@ -326,7 +326,8 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::{PyArray3, PyArrayMethods, PyUntypedArrayMethods}; + /// use numpy::prelude::*; + /// use numpy::PyArray3; /// use pyo3::Python; /// /// Python::with_gil(|py| { @@ -1329,7 +1330,8 @@ impl PyArray { /// # Example /// /// ``` - /// use numpy::{PyArray, PyArrayMethods, PyUntypedArrayMethods}; + /// use numpy::prelude::*; + /// use numpy::PyArray; /// use pyo3::Python; /// /// Python::with_gil(|py| { @@ -1846,8 +1848,8 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// Extends or truncates the dimensions of an array. /// - /// This method works only on [contiguous][PyUntypedArray::is_contiguous] arrays. - /// Missing elements will be initialized as if calling [`zeros`][Self::zeros]. + /// This method works only on [contiguous][PyUntypedArrayMethods::is_contiguous] arrays. + /// Missing elements will be initialized as if calling [`zeros`][PyArray::zeros_bound]. /// /// See also [`ndarray.resize`][ndarray-resize] and [`PyArray_Resize`][PyArray_Resize]. /// @@ -1859,7 +1861,8 @@ pub trait PyArrayMethods<'py, T, D>: PyUntypedArrayMethods<'py> { /// # Example /// /// ``` - /// use numpy::{PyArray, PyArrayMethods, PyUntypedArrayMethods}; + /// use numpy::prelude::*; + /// use numpy::PyArray; /// use pyo3::Python; /// /// Python::with_gil(|py| { diff --git a/src/array_like.rs b/src/array_like.rs index 86747d13f..8a1e3bc46 100644 --- a/src/array_like.rs +++ b/src/array_like.rs @@ -10,13 +10,18 @@ use pyo3::{ }; use crate::array::PyArrayMethods; -use crate::sealed::Sealed; use crate::{get_array_module, Element, IntoPyArray, PyArray, PyReadonlyArray}; pub trait Coerce: Sealed { const VAL: bool; } +mod sealed { + pub trait Sealed {} +} + +use sealed::Sealed; + /// Marker type to indicate that the element type received via [`PyArrayLike`] must match the specified type exactly. #[derive(Debug)] pub struct TypeMustMatch; diff --git a/src/convert.rs b/src/convert.rs index a0d04018c..51be38f56 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -9,7 +9,6 @@ use crate::array::{PyArray, PyArrayMethods}; use crate::dtype::Element; use crate::error::MAX_DIMENSIONALITY_ERR; use crate::npyffi::{self, npy_intp}; -use crate::sealed::Sealed; use crate::slice_container::PySliceContainer; /// Conversion trait from owning Rust types into [`PyArray`]. @@ -273,6 +272,12 @@ pub trait ToNpyDims: Dimension + Sealed { } } +mod sealed { + pub trait Sealed {} +} + +use sealed::Sealed; + impl ToNpyDims for D where D: Dimension {} /// Trait implemented by types that can be used to index an array. diff --git a/src/dtype.rs b/src/dtype.rs index ae6f5e8fe..e1fd1b7ba 100644 --- a/src/dtype.rs +++ b/src/dtype.rs @@ -364,7 +364,7 @@ impl PyArrayDescr { /// Implementation of functionality for [`PyArrayDescr`]. #[doc(alias = "PyArrayDescr")] -pub trait PyArrayDescrMethods<'py>: sealed::Sealed { +pub trait PyArrayDescrMethods<'py>: Sealed { /// Returns `self` as `*mut PyArray_Descr`. fn as_dtype_ptr(&self) -> *mut PyArray_Descr; @@ -553,6 +553,12 @@ pub trait PyArrayDescrMethods<'py>: sealed::Sealed { fn get_field(&self, name: &str) -> PyResult<(Bound<'py, PyArrayDescr>, usize)>; } +mod sealed { + pub trait Sealed {} +} + +use sealed::Sealed; + impl<'py> PyArrayDescrMethods<'py> for Bound<'py, PyArrayDescr> { fn as_dtype_ptr(&self) -> *mut PyArray_Descr { self.as_ptr() as _ @@ -632,13 +638,7 @@ impl<'py> PyArrayDescrMethods<'py> for Bound<'py, PyArrayDescr> { } } -mod sealed { - use super::PyArrayDescr; - - pub trait Sealed {} - - impl Sealed for pyo3::Bound<'_, PyArrayDescr> {} -} +impl Sealed for Bound<'_, PyArrayDescr> {} /// Represents that a type can be an element of `PyArray`. /// diff --git a/src/lib.rs b/src/lib.rs index a03e44799..095cb01e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -119,6 +119,21 @@ pub use crate::untyped_array::{PyUntypedArray, PyUntypedArrayMethods}; pub use ndarray::{array, Ix1, Ix2, Ix3, Ix4, Ix5, Ix6, IxDyn}; +/// A prelude +/// +/// The purpose of this module is to avoid direct imports of +/// the method traits defined by this crate via a glob import: +/// +/// ``` +/// # #![allow(unused_imports)] +/// use numpy::prelude::*; +/// ``` +pub mod prelude { + pub use crate::array::{PyArray0Methods, PyArrayMethods}; + pub use crate::dtype::PyArrayDescrMethods; + pub use crate::untyped_array::PyUntypedArrayMethods; +} + #[cfg(doctest)] mod doctest { macro_rules! doc_comment { @@ -130,10 +145,6 @@ mod doctest { doc_comment!(include_str!("../README.md"), readme); } -mod sealed { - pub trait Sealed {} -} - #[cold] #[inline(always)] fn cold() {} diff --git a/src/untyped_array.rs b/src/untyped_array.rs index 16c9d5f1f..5c02db2fc 100644 --- a/src/untyped_array.rs +++ b/src/untyped_array.rs @@ -258,7 +258,7 @@ impl PyUntypedArray { /// Implementation of functionality for [`PyUntypedArray`]. #[doc(alias = "PyUntypedArray")] -pub trait PyUntypedArrayMethods<'py>: sealed::Sealed { +pub trait PyUntypedArrayMethods<'py>: Sealed { /// Returns a raw pointer to the underlying [`PyArrayObject`][npyffi::PyArrayObject]. fn as_array_ptr(&self) -> *mut npyffi::PyArrayObject; @@ -423,6 +423,12 @@ pub trait PyUntypedArrayMethods<'py>: sealed::Sealed { } } +mod sealed { + pub trait Sealed {} +} + +use sealed::Sealed; + fn check_flags(obj: &npyffi::PyArrayObject, flags: i32) -> bool { obj.flags & flags != 0 } @@ -441,6 +447,8 @@ impl<'py> PyUntypedArrayMethods<'py> for Bound<'py, PyUntypedArray> { } } +impl Sealed for Bound<'_, PyUntypedArray> {} + // We won't be able to provide a `Deref` impl from `Bound<'_, PyArray>` to // `Bound<'_, PyUntypedArray>`, so this seems to be the next best thing to do impl<'py, T, D> PyUntypedArrayMethods<'py> for Bound<'py, PyArray> { @@ -455,11 +463,4 @@ impl<'py, T, D> PyUntypedArrayMethods<'py> for Bound<'py, PyArray> { } } -mod sealed { - use super::{PyArray, PyUntypedArray}; - - pub trait Sealed {} - - impl Sealed for pyo3::Bound<'_, PyUntypedArray> {} - impl Sealed for pyo3::Bound<'_, PyArray> {} -} +impl Sealed for Bound<'_, PyArray> {}