Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update PyO3 to 0.9.0 #124

Merged
merged 5 commits into from
Mar 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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