Skip to content

Commit fb703b7

Browse files
authored
Merge pull request #127 from PyO3/release0.9
Bump version to 0.9.0
2 parents e8b3ced + e6deb3f commit fb703b7

File tree

13 files changed

+97
-109
lines changed

13 files changed

+97
-109
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Changelog
2+
- v0.9.0
3+
- Update PyO3 to 0.10.0
4+
25
- v0.8.0
36
- Update PyO3 to 0.9.0
47
- Fix SliceBox initialization

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "numpy"
3-
version = "0.8.0"
3+
version = "0.9.0"
44
authors = ["Toshiki Teramura <[email protected]>", "Yuji Kanagawa <[email protected]>"]
55
description = "Rust binding of NumPy C-API"
66
documentation = "https://rust-numpy.github.io/rust-numpy/numpy"
@@ -15,7 +15,7 @@ libc = "0.2"
1515
num-complex = "0.2"
1616
num-traits = "0.2"
1717
ndarray = ">=0.13"
18-
pyo3 = "0.9.0"
18+
pyo3 = "0.10.1"
1919

2020
[features]
2121
# In default setting, python version is automatically detected

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ using [setuptools-rust](https://github.com/PyO3/setuptools-rust).
5656
name = "numpy-test"
5757

5858
[dependencies]
59-
pyo3 = "0.9.0"
60-
numpy = "0.8.0"
59+
pyo3 = "0.10.1"
60+
numpy = "0.9.0"
6161
```
6262

6363
```rust
6464
use numpy::{PyArray1, get_array_module};
65-
use pyo3::prelude::{ObjectProtocol, PyResult, Python};
65+
use pyo3::prelude::{PyResult, Python};
6666
use pyo3::types::PyDict;
6767

6868
fn main() -> Result<(), ()> {
@@ -98,7 +98,7 @@ name = "rust_ext"
9898
crate-type = ["cdylib"]
9999

100100
[dependencies]
101-
numpy = "0.8.0"
101+
numpy = "0.9.0"
102102
ndarray = "0.13"
103103

104104
[dependencies.pyo3]

examples/linalg/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ ndarray = ">= 0.13"
1414
ndarray-linalg = { version = "0.12", features = ["openblas"] }
1515

1616
[dependencies.pyo3]
17-
version = "0.9.0"
17+
version = "0.10.1"
1818
features = ["extension-module"]

examples/simple-extension/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ numpy = { path = "../.." }
1313
ndarray = ">= 0.12"
1414

1515
[dependencies.pyo3]
16-
version = "0.9.0"
16+
version = "0.10.1"
1717
features = ["extension-module"]

src/array.rs

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@ use ndarray::*;
44
use num_traits::AsPrimitive;
55
use pyo3::{ffi, prelude::*, type_object, types::PyAny};
66
use pyo3::{AsPyPointer, PyDowncastError, PyNativeType};
7-
use std::iter::ExactSizeIterator;
8-
use std::marker::PhantomData;
9-
use std::mem;
10-
use std::os::raw::c_int;
11-
use std::ptr;
7+
use std::{iter::ExactSizeIterator, marker::PhantomData};
8+
use std::{mem, os::raw::c_int, ptr, slice};
129

1310
use crate::convert::{IntoPyArray, NpyIndex, ToNpyDims, ToPyArray};
1411
use crate::error::{ErrorKind, IntoPyResult};
1512
use crate::slice_box::SliceBox;
1613
use crate::types::{NpyDataType, TypeNum};
1714

1815
/// A safe, static-typed interface for
19-
/// [NumPy ndarray](https://docs.scipy.org/doc/numpy/reference/arrays.ndarray.html).
16+
/// [NumPy ndarray](https://numpy.org/doc/stable/reference/arrays.ndarray.html).
2017
///
2118
/// # Memory location
2219
///
@@ -77,7 +74,7 @@ use crate::types::{NpyDataType, TypeNum};
7774
/// );
7875
/// # }
7976
/// ```
80-
pub struct PyArray<T, D>(PyObject, PhantomData<T>, PhantomData<D>);
77+
pub struct PyArray<T, D>(PyAny, PhantomData<T>, PhantomData<D>);
8178

8279
/// one-dimensional array
8380
pub type PyArray1<T> = PyArray<T, Ix1>;
@@ -113,7 +110,7 @@ pyobject_native_type_convert!(
113110

114111
pyobject_native_type_named!(PyArray<T, D>, T, D);
115112

116-
impl<'a, T, D> ::std::convert::From<&'a PyArray<T, D>> for &'a PyAny {
113+
impl<'a, T, D> std::convert::From<&'a PyArray<T, D>> for &'a PyAny {
117114
fn from(ob: &'a PyArray<T, D>) -> Self {
118115
unsafe { &*(ob as *const PyArray<T, D> as *const PyAny) }
119116
}
@@ -139,8 +136,8 @@ impl<'a, T: TypeNum, D: Dimension> FromPyObject<'a> for &'a PyArray<T, D> {
139136
}
140137

141138
impl<T, D> IntoPy<PyObject> for PyArray<T, D> {
142-
fn into_py(self, _py: Python<'_>) -> PyObject {
143-
self.0
139+
fn into_py(self, py: Python<'_>) -> PyObject {
140+
unsafe { PyObject::from_borrowed_ptr(py, self.as_ptr()) }
144141
}
145142
}
146143

@@ -226,7 +223,7 @@ impl<T, D> PyArray<T, D> {
226223

227224
/// Returns the number of dimensions in the array.
228225
///
229-
/// Same as [numpy.ndarray.ndim](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.ndim.html)
226+
/// Same as [numpy.ndarray.ndim](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.ndim.html)
230227
///
231228
/// # Example
232229
/// ```
@@ -237,15 +234,15 @@ impl<T, D> PyArray<T, D> {
237234
/// assert_eq!(arr.ndim(), 3);
238235
/// # }
239236
/// ```
240-
// C API: https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_NDIM
237+
// C API: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_NDIM
241238
pub fn ndim(&self) -> usize {
242239
let ptr = self.as_array_ptr();
243240
unsafe { (*ptr).nd as usize }
244241
}
245242

246243
/// Returns a slice which contains how many bytes you need to jump to the next row.
247244
///
248-
/// Same as [numpy.ndarray.strides](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.strides.html)
245+
/// Same as [numpy.ndarray.strides](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.strides.html)
249246
/// # Example
250247
/// ```
251248
/// # fn main() {
@@ -255,19 +252,19 @@ impl<T, D> PyArray<T, D> {
255252
/// assert_eq!(arr.strides(), &[240, 48, 8]);
256253
/// # }
257254
/// ```
258-
// C API: https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_STRIDES
255+
// C API: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_STRIDES
259256
pub fn strides(&self) -> &[isize] {
260257
let n = self.ndim();
261258
let ptr = self.as_array_ptr();
262259
unsafe {
263260
let p = (*ptr).strides;
264-
::std::slice::from_raw_parts(p, n)
261+
slice::from_raw_parts(p, n)
265262
}
266263
}
267264

268265
/// Returns a slice which contains dimmensions of the array.
269266
///
270-
/// Same as [numpy.ndarray.shape](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.shape.html)
267+
/// Same as [numpy.ndarray.shape](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.shape.html)
271268
/// # Example
272269
/// ```
273270
/// # fn main() {
@@ -277,13 +274,13 @@ impl<T, D> PyArray<T, D> {
277274
/// assert_eq!(arr.shape(), &[4, 5, 6]);
278275
/// # }
279276
/// ```
280-
// C API: https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_DIMS
277+
// C API: https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_DIMS
281278
pub fn shape(&self) -> &[usize] {
282279
let n = self.ndim();
283280
let ptr = self.as_array_ptr();
284281
unsafe {
285282
let p = (*ptr).dimensions as *mut usize;
286-
::std::slice::from_raw_parts(p, n)
283+
slice::from_raw_parts(p, n)
287284
}
288285
}
289286

@@ -314,7 +311,7 @@ impl<T, D> PyArray<T, D> {
314311
let ptr = self.as_array_ptr();
315312
unsafe {
316313
let p = (*ptr).strides;
317-
::std::slice::from_raw_parts(p as *const _, n)
314+
slice::from_raw_parts(p as *const _, n)
318315
}
319316
}
320317
}
@@ -371,11 +368,11 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
371368
dims.ndim_cint(),
372369
dims.as_dims_ptr(),
373370
T::typenum_default(),
374-
strides as *mut _, // strides
375-
ptr::null_mut(), // data
376-
0, // itemsize
377-
flag, // flag
378-
::std::ptr::null_mut(), //obj
371+
strides as *mut _, // strides
372+
ptr::null_mut(), // data
373+
0, // itemsize
374+
flag, // flag
375+
ptr::null_mut(), //obj
379376
);
380377
Self::from_owned_ptr(py, ptr)
381378
}
@@ -404,7 +401,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
404401
data_ptr as _, // data
405402
mem::size_of::<T>() as i32, // itemsize
406403
0, // flag
407-
::std::ptr::null_mut(), //obj
404+
ptr::null_mut(), //obj
408405
);
409406
PY_ARRAY_API.PyArray_SetBaseObject(ptr as *mut npyffi::PyArrayObject, cell as _);
410407
Self::from_owned_ptr(py, ptr)
@@ -415,7 +412,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
415412
/// If `is_fortran` is true, then
416413
/// a fortran order array is created, otherwise a C-order array is created.
417414
///
418-
/// See also [PyArray_Zeros](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_Zeros)
415+
/// See also [PyArray_Zeros](https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_Zeros)
419416
///
420417
/// # Example
421418
/// ```
@@ -469,7 +466,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
469466
if !self.is_contiguous() {
470467
Err(ErrorKind::NotContiguous)
471468
} else {
472-
Ok(unsafe { ::std::slice::from_raw_parts(self.data(), self.len()) })
469+
Ok(unsafe { slice::from_raw_parts(self.data(), self.len()) })
473470
}
474471
}
475472

@@ -479,7 +476,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
479476
if !self.is_contiguous() {
480477
Err(ErrorKind::NotContiguous)
481478
} else {
482-
Ok(unsafe { ::std::slice::from_raw_parts_mut(self.data(), self.len()) })
479+
Ok(unsafe { slice::from_raw_parts_mut(self.data(), self.len()) })
483480
}
484481
}
485482

@@ -1037,9 +1034,9 @@ impl<T: TypeNum, D> PyArray<T, D> {
10371034

10381035
impl<T: TypeNum + AsPrimitive<f64>> PyArray<T, Ix1> {
10391036
/// Return evenly spaced values within a given interval.
1040-
/// Same as [numpy.arange](https://docs.scipy.org/doc/numpy/reference/generated/numpy.arange.html).
1037+
/// Same as [numpy.arange](https://numpy.org/doc/stable/reference/generated/numpy.arange.html).
10411038
///
1042-
/// See also [PyArray_Arange](https://docs.scipy.org/doc/numpy/reference/c-api.array.html#c.PyArray_Arange).
1039+
/// See also [PyArray_Arange](https://numpy.org/doc/stable/reference/c-api/array.html#c.PyArray_Arange).
10431040
///
10441041
/// # Example
10451042
/// ```

src/convert.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
use ndarray::{ArrayBase, Data, Dimension, IntoDimension, Ix1, OwnedRepr};
44
use pyo3::Python;
55

6-
use std::mem;
7-
use std::os::raw::c_int;
6+
use std::{mem, os::raw::c_int};
87

98
use super::*;
109
use crate::npyffi::npy_intp;

src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
//! `rust-numpy` provides Rust interfaces for [NumPy C APIs](https://docs.scipy.org/doc/numpy/reference/c-api.html),
2-
//! especially for [ndarray](https://www.numpy.org/devdocs/reference/arrays.ndarray.html) class.
1+
//! `rust-numpy` provides Rust interfaces for [NumPy C APIs](https://numpy.org/doc/stable/reference/c-api),
2+
//! especially for [ndarray](https://numpy.org/doc/stable/reference/arrays.ndarray.html) class.
33
//!
44
//! It uses [pyo3](https://github.com/PyO3/pyo3) for rust bindings to cpython, and uses
55
//! [ndarray](https://github.com/bluss/ndarray) for rust side matrix library.

src/npyffi/array.rs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
//! Low-Level binding for [Array API](https://docs.scipy.org/doc/numpy/reference/c-api.array.html)
1+
//! Low-Level binding for [Array API](https://numpy.org/doc/stable/reference/c-api/array.html)
22
use libc::FILE;
33
use pyo3::ffi::{self, PyObject, PyTypeObject};
4-
use std::ops::Deref;
54
use std::os::raw::*;
6-
use std::ptr;
7-
use std::sync::Once;
5+
use std::{cell::Cell, ptr, sync::Once};
86

97
use crate::npyffi::*;
108

119
pub(crate) const MOD_NAME: &str = "numpy.core.multiarray";
1210
const CAPSULE_NAME: &str = "_ARRAY_API";
1311

1412
/// A global variable which stores a ['capsule'](https://docs.python.org/3/c-api/capsule.html)
15-
/// pointer to [Numpy Array API](https://docs.scipy.org/doc/numpy/reference/c-api.array.html).
13+
/// pointer to [Numpy Array API](https://numpy.org/doc/stable/reference/c-api/array.html).
1614
///
1715
/// You can acceess raw c APIs via this variable and its Deref implementation.
1816
///
@@ -31,35 +29,33 @@ const CAPSULE_NAME: &str = "_ARRAY_API";
3129
/// assert_eq!(array.as_slice().unwrap(), &[2, 3, 4])
3230
/// # }
3331
/// ```
34-
pub static PY_ARRAY_API: PyArrayAPI = PyArrayAPI {
35-
__private_field: (),
36-
};
32+
pub static PY_ARRAY_API: PyArrayAPI = PyArrayAPI::new();
3733

34+
/// See [PY_ARRAY_API] for more.
3835
pub struct PyArrayAPI {
39-
__private_field: (),
36+
once: Once,
37+
api: Cell<*const *const c_void>,
4038
}
4139

42-
impl Deref for PyArrayAPI {
43-
type Target = PyArrayAPI_Inner;
44-
fn deref(&self) -> &Self::Target {
45-
static INIT_API: Once = Once::new();
46-
static mut ARRAY_API_CACHE: PyArrayAPI_Inner = PyArrayAPI_Inner(ptr::null());
47-
unsafe {
48-
if ARRAY_API_CACHE.0.is_null() {
49-
let api = get_numpy_api(MOD_NAME, CAPSULE_NAME);
50-
INIT_API.call_once(move || {
51-
ARRAY_API_CACHE = PyArrayAPI_Inner(api);
52-
});
53-
}
54-
&ARRAY_API_CACHE
40+
impl PyArrayAPI {
41+
const fn new() -> Self {
42+
Self {
43+
once: Once::new(),
44+
api: Cell::new(ptr::null_mut()),
45+
}
46+
}
47+
fn get(&self, offset: isize) -> *const *const c_void {
48+
if self.api.get().is_null() {
49+
let api = get_numpy_api(MOD_NAME, CAPSULE_NAME);
50+
self.once.call_once(|| self.api.set(api));
5551
}
52+
unsafe { self.api.get().offset(offset) }
5653
}
5754
}
5855

59-
#[allow(non_camel_case_types)]
60-
pub struct PyArrayAPI_Inner(*const *const c_void);
56+
unsafe impl Sync for PyArrayAPI {}
6157

62-
impl PyArrayAPI_Inner {
58+
impl PyArrayAPI {
6359
impl_api![0; PyArray_GetNDArrayCVersion() -> c_uint];
6460
impl_api![40; PyArray_SetNumericOps(dict: *mut PyObject) -> c_int];
6561
impl_api![41; PyArray_GetNumericOps() -> *mut PyObject];
@@ -322,13 +318,15 @@ impl PyArrayAPI_Inner {
322318
/// Define PyTypeObject related to Array API
323319
macro_rules! impl_array_type {
324320
($(($offset:expr, $tname:ident)),*) => {
321+
/// All type objects that numpy has.
325322
#[allow(non_camel_case_types)]
326323
#[repr(i32)]
327324
pub enum ArrayType { $($tname),* }
328-
impl PyArrayAPI_Inner {
325+
impl PyArrayAPI {
326+
/// Get the pointer of the type object that `self` refers.
329327
pub unsafe fn get_type_object(&self, ty: ArrayType) -> *mut PyTypeObject {
330328
match ty {
331-
$( ArrayType::$tname => *(self.0.offset($offset)) as *mut PyTypeObject ),*
329+
$( ArrayType::$tname => *(self.get($offset)) as *mut PyTypeObject ),*
332330
}
333331
}
334332
}
@@ -377,11 +375,13 @@ impl_array_type!(
377375
(39, PyVoidArrType_Type)
378376
);
379377

378+
/// Checks that `op` is an instance of `PyArray` or not.
380379
#[allow(non_snake_case)]
381380
pub unsafe fn PyArray_Check(op: *mut PyObject) -> c_int {
382381
ffi::PyObject_TypeCheck(op, PY_ARRAY_API.get_type_object(ArrayType::PyArray_Type))
383382
}
384383

384+
/// Checks that `op` is an exact instance of `PyArray` or not.
385385
#[allow(non_snake_case)]
386386
pub unsafe fn PyArray_CheckExact(op: *mut PyObject) -> c_int {
387387
(ffi::Py_TYPE(op) == PY_ARRAY_API.get_type_object(ArrayType::PyArray_Type)) as c_int

0 commit comments

Comments
 (0)