Skip to content

Commit

Permalink
Merge pull request #124 from PyO3/v0.8.0
Browse files Browse the repository at this point in the history
Update PyO3 to 0.9.0
  • Loading branch information
kngwyu authored Mar 19, 2020
2 parents 5138ba5 + ce3a106 commit 6811345
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 60 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ cfg-if = "0.1"
libc = "0.2"
num-complex = "0.2"
num-traits = "0.2"
ndarray = ">=0.12"
pyo3 = "0.8"
ndarray = ">=0.13"
pyo3 = "0.9.0"

[features]
# In default setting, python version is automatically detected
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ using [setuptools-rust](https://github.com/PyO3/setuptools-rust).
name = "numpy-test"

[dependencies]
pyo3 = "0.8"
pyo3 = "0.9.0"
numpy = "0.7.0"
```

Expand Down Expand Up @@ -102,7 +102,7 @@ numpy = "0.7.0"
ndarray = "0.13"

[dependencies.pyo3]
version = "0.8"
version = "0.9.0-alpha.1"
features = ["extension-module"]
```

Expand Down
6 changes: 3 additions & 3 deletions examples/linalg/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ crate-type = ["cdylib"]

[dependencies]
numpy = { path = "../.." }
ndarray = ">= 0.12"
ndarray-linalg = { version = "0.10", features = ["openblas"] }
ndarray = ">= 0.13"
ndarray-linalg = { version = "0.12", features = ["openblas"] }

[dependencies.pyo3]
version = "0.8"
version = "0.9.0"
features = ["extension-module"]
2 changes: 1 addition & 1 deletion examples/simple-extension/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ numpy = { path = "../.." }
ndarray = ">= 0.12"

[dependencies.pyo3]
version = "0.8"
version = "0.9.0"
features = ["extension-module"]
20 changes: 14 additions & 6 deletions src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::npyffi::{self, npy_intp, NPY_ORDER, PY_ARRAY_API};
use ndarray::*;
use num_traits::AsPrimitive;
use pyo3::{ffi, prelude::*, types::PyAny};
use pyo3::{ffi, prelude::*, type_object, types::PyAny};
use pyo3::{AsPyPointer, PyDowncastError, PyNativeType};
use std::iter::ExactSizeIterator;
use std::marker::PhantomData;
Expand Down Expand Up @@ -99,8 +99,12 @@ pub fn get_array_module(py: Python<'_>) -> PyResult<&PyModule> {
PyModule::import(py, npyffi::array::MOD_NAME)
}

unsafe impl<T, D> type_object::PyLayout<PyArray<T, D>> for npyffi::PyArrayObject {}
impl<T, D> type_object::PySizedLayout<PyArray<T, D>> for npyffi::PyArrayObject {}

pyobject_native_type_convert!(
PyArray<T, D>,
npyffi::PyArrayObject,
*npyffi::PY_ARRAY_API.get_type_object(npyffi::ArrayType::PyArray_Type),
Some("numpy"),
npyffi::PyArray_Check,
Expand Down Expand Up @@ -166,7 +170,7 @@ impl<T, D> PyArray<T, D> {
/// let not_contiguous: &numpy::PyArray1<f32> = py
/// .eval("np.zeros((3, 5))[::2, 4]", Some(locals), None)
/// .unwrap()
/// .downcast_ref()
/// .downcast()
/// .unwrap();
/// assert!(!not_contiguous.is_contiguous());
/// # }
Expand Down Expand Up @@ -386,19 +390,23 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
ID: IntoDimension<Dim = D>,
{
let dims = dims.into_dimension();
let slice = SliceBox::new(slice);
let container = SliceBox::new(slice);
let data_ptr = container.data;
let cell = pyo3::PyClassInitializer::from(container)
.create_cell(py)
.expect("Object creation failed.");
let ptr = PY_ARRAY_API.PyArray_New(
PY_ARRAY_API.get_type_object(npyffi::ArrayType::PyArray_Type),
dims.ndim_cint(),
dims.as_dims_ptr(),
T::typenum_default(),
strides as *mut _, // strides
slice.data(), // data
data_ptr as _, // data
mem::size_of::<T>() as i32, // itemsize
0, // flag
::std::ptr::null_mut(), //obj
);
PY_ARRAY_API.PyArray_SetBaseObject(ptr as *mut npyffi::PyArrayObject, slice.as_ptr());
PY_ARRAY_API.PyArray_SetBaseObject(ptr as *mut npyffi::PyArrayObject, cell as _);
Self::from_owned_ptr(py, ptr)
}

Expand Down Expand Up @@ -451,7 +459,7 @@ impl<T: TypeNum, D: Dimension> PyArray<T, D> {
/// let not_contiguous: &PyArray1<f32> = py
/// .eval("np.zeros((3, 5))[[0, 2], [3, 4]]", Some(locals), None)
/// .unwrap()
/// .downcast_ref()
/// .downcast()
/// .unwrap();
/// assert!(not_contiguous.as_slice().is_err());
/// # }
Expand Down
77 changes: 32 additions & 45 deletions src/slice_box.rs
Original file line number Diff line number Diff line change
@@ -1,43 +1,51 @@
use pyo3::class::methods::{PyMethodDefType, PyMethodsProtocol};
use pyo3::{ffi, type_object, types::PyAny, AsPyPointer, PyObjectAlloc, Python};
use std::os::raw::c_void;
use pyo3::pyclass::{PyClass, PyClassAlloc};
use pyo3::pyclass_slots::PyClassDummySlot;
use pyo3::{ffi, type_object, types::PyAny, PyCell, PyClassInitializer};

/// It's a memory store for IntoPyArray.
/// See IntoPyArray's doc for what concretely this type is for.
#[repr(C)]
pub(crate) struct SliceBox<T> {
ob_base: ffi::PyObject,
inner: *mut [T],
pub(crate) data: *mut [T],
}

impl<T> SliceBox<T> {
pub(crate) unsafe fn new<'a>(box_: Box<[T]>) -> &'a Self {
let type_ob = <Self as type_object::PyTypeObject>::init_type().as_ptr();
let base = ffi::_PyObject_New(type_ob);
*base = ffi::PyObject_HEAD_INIT;
(*base).ob_type = type_ob;
let self_ = base as *mut SliceBox<T>;
(*self_).inner = Box::into_raw(box_);
&*self_
pub(crate) fn new(value: Box<[T]>) -> Self {
SliceBox {
data: Box::into_raw(value),
}
}
pub(crate) fn data(&self) -> *mut c_void {
self.inner as *mut c_void
}

impl<T> Drop for SliceBox<T> {
fn drop(&mut self) {
let _boxed_slice = unsafe { Box::from_raw(self.data) };
}
}

impl<T> type_object::PyTypeInfo for SliceBox<T> {
impl<T> PyClassAlloc for SliceBox<T> {}

impl<T> PyClass for SliceBox<T> {
type Dict = PyClassDummySlot;
type WeakRef = PyClassDummySlot;
type BaseNativeType = PyAny;
}

unsafe impl<T> type_object::PyTypeInfo for SliceBox<T> {
type Type = ();
type BaseType = PyAny;
type BaseLayout = pyo3::pycell::PyCellBase<PyAny>;
type Layout = PyCell<Self>;
type Initializer = PyClassInitializer<Self>;
type AsRefTarget = PyCell<Self>;
const NAME: &'static str = "SliceBox";
const MODULE: Option<&'static str> = Some("_rust_numpy");
const DESCRIPTION: &'static str = "Memory store for PyArray using rust's Box<[T]>.";
const DESCRIPTION: &'static str = "Memory store for PyArray using rust's Box<[T]> \0";
const FLAGS: usize = 0;
const SIZE: usize = std::mem::size_of::<Self>();
const OFFSET: isize = 0;

#[inline]
unsafe fn type_object() -> &'static mut ffi::PyTypeObject {
static mut TYPE_OBJECT: ::pyo3::ffi::PyTypeObject = ::pyo3::ffi::PyTypeObject_INIT;
&mut TYPE_OBJECT
fn type_object() -> &'static ffi::PyTypeObject {
use pyo3::type_object::LazyStaticType;
static TYPE_OBJECT: LazyStaticType = LazyStaticType::new();
TYPE_OBJECT.get_or_init::<Self>()
}
}

Expand All @@ -46,24 +54,3 @@ impl<T> PyMethodsProtocol for SliceBox<T> {
Vec::new()
}
}

impl<T> AsPyPointer for SliceBox<T> {
#[inline]
fn as_ptr(&self) -> *mut ffi::PyObject {
&self.ob_base as *const _ as *mut _
}
}

impl<T> PyObjectAlloc for SliceBox<T> {
/// Calls the rust destructor for the object.
unsafe fn drop(py: Python<'_>, obj: *mut ffi::PyObject) {
let data = (*(obj as *mut SliceBox<T>)).inner;
let boxed_slice = Box::from_raw(data);
drop(boxed_slice);
<Self as type_object::PyTypeInfo>::BaseType::drop(py, obj);
}
unsafe fn dealloc(py: Python<'_>, obj: *mut ffi::PyObject) {
Self::drop(py, obj);
ffi::PyObject_Free(obj as *mut c_void);
}
}
2 changes: 1 addition & 1 deletion tests/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ fn not_contiguous_array<'py>(py: Python<'py>) -> &'py PyArray1<i32> {
None,
)
.unwrap()
.downcast_ref()
.downcast()
.unwrap()
}

Expand Down

0 comments on commit 6811345

Please sign in to comment.