# PyO3-ArrayLike This crate provides a single struct `PyArrayLike` which can be used for extracting an array from any Python object which can be regarded as an array of type `T` and dimension `D` in a reasonable way. ## How it works `PyArrayLike` is basically an enum consisting of either a `PyReadonlyArray` from the [rust-numpy](https://github.com/PyO3/rust-numpy) project (i.e. a readonly reference to an actual numpy array on the Python heap), or of an owned `Array` from the [ndarray](https://github.com/rust-ndarray/ndarray) project. When calling `pyobject.extract::>()` it immediately checks whether `pyobject` is already a numpy array of the right type and dimension by calling `pyobject.downcast::>()` internally. Only if this fails, it will try to construct an owned array from `pyobject` by iterating over its elements and trying to convert them into the right type recursively. ## Example Consider the following function. It takes anything which "looks like" an array of dimension two consisting of integers bewteen 0 and 4294967295. It computes the sum of the array's rows and returns a one dimensional numpy array. ```rust #[pyfunction] fn sum_of_rows<'py>(py: Python<'py>, ar: PyArrayLike2<'py, u32>) -> Bound<'py, PyArray1> { ar.view().sum_axis(Axis(0)).into_pyarray_bound(py) } ``` You can call this function from Python in the following ways. The first two functions will succeed, the latter two will raise an error. ```python def call1(): """Succeeds by passing a reference of the input array to the rust component.""" return sum_of_rows(np.array([[1,2,3],[4,5,6]], dtype='uint32')) def call2(): """Succeeds but allocates extra memory for rebuilding the input array inside the rust component.""" return sum_of_rows([[1,2,3], iter([4,5,6]), np.array([7,8,9], dtype='int64')]) def call3(): """Raises an error since the input array is expected to be two dimensional.""" return sum_of_rows([1,2,3]) def call4(): """Raises an error since the input array contains a value which cannot be safely casted to u32.""" return sum_of_rows([[2**32,0,0], [0,0,0]]) ```