New Native Types and lighter GILPool
This commit is contained in:
parent
e40f022014
commit
823b8e7f8a
|
@ -3,7 +3,7 @@
|
||||||
//! Conversions between various states of Rust and Python types and their wrappers.
|
//! Conversions between various states of Rust and Python types and their wrappers.
|
||||||
use crate::err::{self, PyDowncastError, PyResult};
|
use crate::err::{self, PyDowncastError, PyResult};
|
||||||
use crate::object::PyObject;
|
use crate::object::PyObject;
|
||||||
use crate::type_object::{PyDowncastImpl, PyTypeInfo};
|
use crate::type_object::PyTypeInfo;
|
||||||
use crate::types::PyTuple;
|
use crate::types::PyTuple;
|
||||||
use crate::{ffi, gil, Py, PyAny, PyCell, PyClass, PyNativeType, PyRef, PyRefMut, Python};
|
use crate::{ffi, gil, Py, PyAny, PyCell, PyClass, PyNativeType, PyRef, PyRefMut, Python};
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
@ -311,7 +311,7 @@ where
|
||||||
/// If `T` implements `PyTryFrom`, we can convert `&PyAny` to `&T`.
|
/// If `T` implements `PyTryFrom`, we can convert `&PyAny` to `&T`.
|
||||||
///
|
///
|
||||||
/// This trait is similar to `std::convert::TryFrom`
|
/// This trait is similar to `std::convert::TryFrom`
|
||||||
pub trait PyTryFrom<'v>: Sized + PyDowncastImpl {
|
pub trait PyTryFrom<'v>: Sized + PyNativeType {
|
||||||
/// Cast from a concrete Python object type to PyObject.
|
/// Cast from a concrete Python object type to PyObject.
|
||||||
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError>;
|
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError>;
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ where
|
||||||
|
|
||||||
impl<'v, T> PyTryFrom<'v> for T
|
impl<'v, T> PyTryFrom<'v> for T
|
||||||
where
|
where
|
||||||
T: PyDowncastImpl + PyTypeInfo + PyNativeType,
|
T: PyTypeInfo + PyNativeType,
|
||||||
{
|
{
|
||||||
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError> {
|
fn try_from<V: Into<&'v PyAny>>(value: V) -> Result<&'v Self, PyDowncastError> {
|
||||||
let value = value.into();
|
let value = value.into();
|
||||||
|
@ -460,28 +460,14 @@ where
|
||||||
T: 'p + crate::PyNativeType,
|
T: 'p + crate::PyNativeType,
|
||||||
{
|
{
|
||||||
unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self> {
|
unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self> {
|
||||||
NonNull::new(ptr).map(|p| Self::unchecked_downcast(gil::register_owned(py, p)))
|
gil::register_owned(py, NonNull::new(ptr)?);
|
||||||
|
Some(&*(ptr as *mut Self))
|
||||||
}
|
}
|
||||||
unsafe fn from_borrowed_ptr_or_opt(
|
unsafe fn from_borrowed_ptr_or_opt(
|
||||||
py: Python<'p>,
|
_py: Python<'p>,
|
||||||
ptr: *mut ffi::PyObject,
|
ptr: *mut ffi::PyObject,
|
||||||
) -> Option<&'p Self> {
|
) -> Option<&'p Self> {
|
||||||
NonNull::new(ptr).map(|p| Self::unchecked_downcast(gil::register_borrowed(py, p)))
|
NonNull::new(ptr as *mut Self).map(|p| &*p.as_ptr())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<'p, T> FromPyPointer<'p> for PyCell<T>
|
|
||||||
where
|
|
||||||
T: PyClass,
|
|
||||||
{
|
|
||||||
unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<&'p Self> {
|
|
||||||
NonNull::new(ptr).map(|p| &*(gil::register_owned(py, p).as_ptr() as *const PyCell<T>))
|
|
||||||
}
|
|
||||||
unsafe fn from_borrowed_ptr_or_opt(
|
|
||||||
py: Python<'p>,
|
|
||||||
ptr: *mut ffi::PyObject,
|
|
||||||
) -> Option<&'p Self> {
|
|
||||||
NonNull::new(ptr).map(|p| &*(gil::register_borrowed(py, p).as_ptr() as *const PyCell<T>))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
155
src/gil.rs
155
src/gil.rs
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
//! Interaction with python's global interpreter lock
|
//! Interaction with python's global interpreter lock
|
||||||
|
|
||||||
use crate::{ffi, internal_tricks::Unsendable, PyAny, Python};
|
use crate::{ffi, internal_tricks::Unsendable, Python};
|
||||||
use std::cell::{Cell, UnsafeCell};
|
use std::cell::{Cell, UnsafeCell};
|
||||||
use std::{any, mem::ManuallyDrop, ptr::NonNull, sync};
|
use std::{any, mem::ManuallyDrop, ptr::NonNull, sync};
|
||||||
|
|
||||||
|
@ -144,8 +144,7 @@ impl Drop for GILGuard {
|
||||||
|
|
||||||
/// Implementation of release pool
|
/// Implementation of release pool
|
||||||
struct ReleasePoolImpl {
|
struct ReleasePoolImpl {
|
||||||
owned: ArrayList<NonNull<ffi::PyObject>>,
|
owned: Vec<NonNull<ffi::PyObject>>,
|
||||||
borrowed: ArrayList<NonNull<ffi::PyObject>>,
|
|
||||||
pointers: *mut Vec<NonNull<ffi::PyObject>>,
|
pointers: *mut Vec<NonNull<ffi::PyObject>>,
|
||||||
obj: Vec<Box<dyn any::Any>>,
|
obj: Vec<Box<dyn any::Any>>,
|
||||||
p: parking_lot::Mutex<*mut Vec<NonNull<ffi::PyObject>>>,
|
p: parking_lot::Mutex<*mut Vec<NonNull<ffi::PyObject>>>,
|
||||||
|
@ -154,8 +153,7 @@ struct ReleasePoolImpl {
|
||||||
impl ReleasePoolImpl {
|
impl ReleasePoolImpl {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
owned: ArrayList::new(),
|
owned: Vec::with_capacity(256),
|
||||||
borrowed: ArrayList::new(),
|
|
||||||
pointers: Box::into_raw(Box::new(Vec::with_capacity(256))),
|
pointers: Box::into_raw(Box::new(Vec::with_capacity(256))),
|
||||||
obj: Vec::with_capacity(8),
|
obj: Vec::with_capacity(8),
|
||||||
p: parking_lot::Mutex::new(Box::into_raw(Box::new(Vec::with_capacity(256)))),
|
p: parking_lot::Mutex::new(Box::into_raw(Box::new(Vec::with_capacity(256)))),
|
||||||
|
@ -180,14 +178,12 @@ impl ReleasePoolImpl {
|
||||||
vec.set_len(0);
|
vec.set_len(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn drain(&mut self, _py: Python, owned: usize, borrowed: usize) {
|
pub unsafe fn drain(&mut self, _py: Python, owned: usize) {
|
||||||
// Release owned objects(call decref)
|
// Release owned objects(call decref)
|
||||||
while owned < self.owned.len() {
|
for i in owned..self.owned.len() {
|
||||||
let last = self.owned.pop_back().unwrap();
|
ffi::Py_DECREF(self.owned[i].as_ptr());
|
||||||
ffi::Py_DECREF(last.as_ptr());
|
|
||||||
}
|
}
|
||||||
// Release borrowed objects(don't call decref)
|
self.owned.truncate(owned);
|
||||||
self.borrowed.truncate(borrowed);
|
|
||||||
self.release_pointers();
|
self.release_pointers();
|
||||||
self.obj.clear();
|
self.obj.clear();
|
||||||
}
|
}
|
||||||
|
@ -219,7 +215,6 @@ unsafe impl Sync for ReleasePool {}
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
pub struct GILPool {
|
pub struct GILPool {
|
||||||
owned: usize,
|
owned: usize,
|
||||||
borrowed: usize,
|
|
||||||
// Stable solution for impl !Send
|
// Stable solution for impl !Send
|
||||||
no_send: Unsendable,
|
no_send: Unsendable,
|
||||||
}
|
}
|
||||||
|
@ -235,7 +230,6 @@ impl GILPool {
|
||||||
pool.release_pointers();
|
pool.release_pointers();
|
||||||
GILPool {
|
GILPool {
|
||||||
owned: pool.owned.len(),
|
owned: pool.owned.len(),
|
||||||
borrowed: pool.borrowed.len(),
|
|
||||||
no_send: Unsendable::default(),
|
no_send: Unsendable::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,7 +242,7 @@ impl Drop for GILPool {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let pool = POOL.get_or_init();
|
let pool = POOL.get_or_init();
|
||||||
pool.drain(self.python(), self.owned, self.borrowed);
|
pool.drain(self.python(), self.owned);
|
||||||
}
|
}
|
||||||
decrement_gil_count();
|
decrement_gil_count();
|
||||||
}
|
}
|
||||||
|
@ -275,14 +269,9 @@ pub unsafe fn register_pointer(obj: NonNull<ffi::PyObject>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn register_owned(_py: Python, obj: NonNull<ffi::PyObject>) -> &PyAny {
|
pub unsafe fn register_owned(_py: Python, obj: NonNull<ffi::PyObject>) {
|
||||||
let pool = POOL.get_or_init();
|
let pool = POOL.get_or_init();
|
||||||
&*(pool.owned.push_back(obj) as *const _ as *const PyAny)
|
pool.owned.push(obj);
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn register_borrowed(_py: Python, obj: NonNull<ffi::PyObject>) -> &PyAny {
|
|
||||||
let pool = POOL.get_or_init();
|
|
||||||
&*(pool.borrowed.push_back(obj) as *const _ as *const PyAny)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Increment pyo3's internal GIL count - to be called whenever GILPool or GILGuard is created.
|
/// Increment pyo3's internal GIL count - to be called whenever GILPool or GILGuard is created.
|
||||||
|
@ -304,70 +293,10 @@ fn decrement_gil_count() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
use self::array_list::ArrayList;
|
|
||||||
|
|
||||||
mod array_list {
|
|
||||||
use std::collections::LinkedList;
|
|
||||||
const BLOCK_SIZE: usize = 256;
|
|
||||||
|
|
||||||
/// A container type for Release Pool
|
|
||||||
/// See #271 for why this is crated
|
|
||||||
pub(super) struct ArrayList<T> {
|
|
||||||
inner: LinkedList<[Option<T>; BLOCK_SIZE]>,
|
|
||||||
length: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Copy> ArrayList<T> {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
ArrayList {
|
|
||||||
inner: LinkedList::new(),
|
|
||||||
length: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn push_back(&mut self, item: T) -> &T {
|
|
||||||
let next_idx = self.next_idx();
|
|
||||||
if next_idx == 0 {
|
|
||||||
self.inner.push_back([None; BLOCK_SIZE]);
|
|
||||||
}
|
|
||||||
self.inner.back_mut().unwrap()[next_idx] = Some(item);
|
|
||||||
self.length += 1;
|
|
||||||
self.inner.back().unwrap()[next_idx].as_ref().unwrap()
|
|
||||||
}
|
|
||||||
pub fn pop_back(&mut self) -> Option<T> {
|
|
||||||
self.length -= 1;
|
|
||||||
let current_idx = self.next_idx();
|
|
||||||
if current_idx == 0 {
|
|
||||||
let last_list = self.inner.pop_back()?;
|
|
||||||
return last_list[0];
|
|
||||||
}
|
|
||||||
self.inner.back().and_then(|arr| arr[current_idx])
|
|
||||||
}
|
|
||||||
pub fn len(&self) -> usize {
|
|
||||||
self.length
|
|
||||||
}
|
|
||||||
pub fn truncate(&mut self, new_len: usize) {
|
|
||||||
if self.length <= new_len {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while self.inner.len() > (new_len + BLOCK_SIZE - 1) / BLOCK_SIZE {
|
|
||||||
self.inner.pop_back();
|
|
||||||
}
|
|
||||||
self.length = new_len;
|
|
||||||
}
|
|
||||||
fn next_idx(&self) -> usize {
|
|
||||||
self.length % BLOCK_SIZE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{GILPool, NonNull, GIL_COUNT, POOL};
|
use super::{GILPool, GIL_COUNT, POOL};
|
||||||
use crate::object::PyObject;
|
use crate::{ffi, gil, AsPyPointer, PyObject, Python, ToPyObject};
|
||||||
use crate::AsPyPointer;
|
|
||||||
use crate::Python;
|
|
||||||
use crate::ToPyObject;
|
|
||||||
use crate::{ffi, gil};
|
|
||||||
|
|
||||||
fn get_object() -> PyObject {
|
fn get_object() -> PyObject {
|
||||||
// Convenience function for getting a single unique object
|
// Convenience function for getting a single unique object
|
||||||
|
@ -442,66 +371,6 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_borrowed() {
|
|
||||||
unsafe {
|
|
||||||
let p = POOL.get_or_init();
|
|
||||||
|
|
||||||
let obj = get_object();
|
|
||||||
let obj_ptr = obj.as_ptr();
|
|
||||||
{
|
|
||||||
let gil = Python::acquire_gil();
|
|
||||||
let py = gil.python();
|
|
||||||
assert_eq!(p.borrowed.len(), 0);
|
|
||||||
|
|
||||||
gil::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
|
||||||
|
|
||||||
assert_eq!(p.borrowed.len(), 1);
|
|
||||||
assert_eq!(ffi::Py_REFCNT(obj_ptr), 1);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let _gil = Python::acquire_gil();
|
|
||||||
assert_eq!(p.borrowed.len(), 0);
|
|
||||||
assert_eq!(ffi::Py_REFCNT(obj_ptr), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_borrowed_nested() {
|
|
||||||
unsafe {
|
|
||||||
let p = POOL.get_or_init();
|
|
||||||
|
|
||||||
let obj = get_object();
|
|
||||||
let obj_ptr = obj.as_ptr();
|
|
||||||
{
|
|
||||||
let gil = Python::acquire_gil();
|
|
||||||
let py = gil.python();
|
|
||||||
assert_eq!(p.borrowed.len(), 0);
|
|
||||||
|
|
||||||
gil::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
|
||||||
|
|
||||||
assert_eq!(p.borrowed.len(), 1);
|
|
||||||
assert_eq!(ffi::Py_REFCNT(obj_ptr), 1);
|
|
||||||
|
|
||||||
{
|
|
||||||
let _pool = GILPool::new();
|
|
||||||
assert_eq!(p.borrowed.len(), 1);
|
|
||||||
gil::register_borrowed(py, NonNull::new(obj_ptr).unwrap());
|
|
||||||
assert_eq!(p.borrowed.len(), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(p.borrowed.len(), 1);
|
|
||||||
assert_eq!(ffi::Py_REFCNT(obj_ptr), 1);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let _gil = Python::acquire_gil();
|
|
||||||
assert_eq!(p.borrowed.len(), 0);
|
|
||||||
assert_eq!(ffi::Py_REFCNT(obj_ptr), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_pyobject_drop_with_gil_decreases_refcnt() {
|
fn test_pyobject_drop_with_gil_decreases_refcnt() {
|
||||||
let gil = Python::acquire_gil();
|
let gil = Python::acquire_gil();
|
||||||
|
|
|
@ -3,7 +3,7 @@ use crate::err::{PyErr, PyResult};
|
||||||
use crate::gil;
|
use crate::gil;
|
||||||
use crate::object::PyObject;
|
use crate::object::PyObject;
|
||||||
use crate::objectprotocol::ObjectProtocol;
|
use crate::objectprotocol::ObjectProtocol;
|
||||||
use crate::type_object::{PyBorrowFlagLayout, PyDowncastImpl};
|
use crate::type_object::PyBorrowFlagLayout;
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyAny, PyCell, PyClass,
|
ffi, AsPyPointer, FromPyObject, IntoPy, IntoPyPointer, PyAny, PyCell, PyClass,
|
||||||
PyClassInitializer, PyRef, PyRefMut, PyTypeInfo, Python, ToPyObject,
|
PyClassInitializer, PyRef, PyRefMut, PyTypeInfo, Python, ToPyObject,
|
||||||
|
@ -21,6 +21,15 @@ pub unsafe trait PyNativeType: Sized {
|
||||||
fn py(&self) -> Python {
|
fn py(&self) -> Python {
|
||||||
unsafe { Python::assume_gil_acquired() }
|
unsafe { Python::assume_gil_acquired() }
|
||||||
}
|
}
|
||||||
|
/// Cast `&PyAny` to `&Self` without no type checking.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// Unless obj is not an instance of a type corresponding to Self,
|
||||||
|
/// this method causes undefined behavior.
|
||||||
|
unsafe fn unchecked_downcast(obj: &PyAny) -> &Self {
|
||||||
|
&*(obj.as_ptr() as *const Self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A Python object of known type.
|
/// A Python object of known type.
|
||||||
|
@ -176,8 +185,8 @@ where
|
||||||
{
|
{
|
||||||
type Target = T::AsRefTarget;
|
type Target = T::AsRefTarget;
|
||||||
fn as_ref<'p>(&'p self, _py: Python<'p>) -> &'p Self::Target {
|
fn as_ref<'p>(&'p self, _py: Python<'p>) -> &'p Self::Target {
|
||||||
let any = self as *const Py<T> as *const PyAny;
|
let any = self.as_ptr() as *const PyAny;
|
||||||
unsafe { PyDowncastImpl::unchecked_downcast(&*any) }
|
unsafe { PyNativeType::unchecked_downcast(&*any) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ impl PyObject {
|
||||||
PyObject(ptr)
|
PyObject(ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
pub(crate) unsafe fn into_nonnull(self) -> NonNull<ffi::PyObject> {
|
pub(crate) unsafe fn into_nonnull(self) -> NonNull<ffi::PyObject> {
|
||||||
let res = self.0;
|
let res = self.0;
|
||||||
std::mem::forget(self); // Avoid Drop
|
std::mem::forget(self); // Avoid Drop
|
||||||
|
@ -268,7 +269,7 @@ impl PyObject {
|
||||||
impl AsPyRef for PyObject {
|
impl AsPyRef for PyObject {
|
||||||
type Target = PyAny;
|
type Target = PyAny;
|
||||||
fn as_ref<'p>(&'p self, _py: Python<'p>) -> &'p PyAny {
|
fn as_ref<'p>(&'p self, _py: Python<'p>) -> &'p PyAny {
|
||||||
unsafe { &*(self as *const _ as *const PyAny) }
|
unsafe { &*(self.as_ptr() as *const PyAny) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
use crate::conversion::{AsPyPointer, FromPyPointer, ToPyObject};
|
use crate::conversion::{AsPyPointer, FromPyPointer, ToPyObject};
|
||||||
use crate::pyclass_init::PyClassInitializer;
|
use crate::pyclass_init::PyClassInitializer;
|
||||||
use crate::pyclass_slots::{PyClassDict, PyClassWeakRef};
|
use crate::pyclass_slots::{PyClassDict, PyClassWeakRef};
|
||||||
use crate::type_object::{PyBorrowFlagLayout, PyDowncastImpl, PyLayout, PySizedLayout, PyTypeInfo};
|
use crate::type_object::{PyBorrowFlagLayout, PyLayout, PySizedLayout, PyTypeInfo};
|
||||||
use crate::{ffi, FromPy, PyAny, PyClass, PyErr, PyNativeType, PyObject, PyResult, Python};
|
use crate::{ffi, FromPy, PyClass, PyErr, PyNativeType, PyObject, PyResult, Python};
|
||||||
use std::cell::{Cell, UnsafeCell};
|
use std::cell::{Cell, UnsafeCell};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
@ -159,6 +159,8 @@ pub struct PyCell<T: PyClass> {
|
||||||
weakref: T::WeakRef,
|
weakref: T::WeakRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl<T: PyClass> PyNativeType for PyCell<T> {}
|
||||||
|
|
||||||
impl<T: PyClass> PyCell<T> {
|
impl<T: PyClass> PyCell<T> {
|
||||||
/// Make new `PyCell` on the Python heap and returns the reference of it.
|
/// Make new `PyCell` on the Python heap and returns the reference of it.
|
||||||
///
|
///
|
||||||
|
@ -360,13 +362,6 @@ unsafe impl<T: PyClass> PyLayout<T> for PyCell<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: PyClass> PyDowncastImpl for PyCell<T> {
|
|
||||||
unsafe fn unchecked_downcast(obj: &PyAny) -> &Self {
|
|
||||||
&*(obj.as_ptr() as *const Self)
|
|
||||||
}
|
|
||||||
private_impl! {}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: PyClass> AsPyPointer for PyCell<T> {
|
impl<T: PyClass> AsPyPointer for PyCell<T> {
|
||||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||||
self.inner.as_ptr()
|
self.inner.as_ptr()
|
||||||
|
|
|
@ -3,17 +3,15 @@
|
||||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||||
|
|
||||||
use crate::err::{PyDowncastError, PyErr, PyResult};
|
use crate::err::{PyDowncastError, PyErr, PyResult};
|
||||||
use crate::ffi;
|
|
||||||
use crate::gil::{self, GILGuard};
|
use crate::gil::{self, GILGuard};
|
||||||
use crate::instance::AsPyRef;
|
use crate::type_object::{PyTypeInfo, PyTypeObject};
|
||||||
use crate::object::PyObject;
|
|
||||||
use crate::type_object::{PyDowncastImpl, PyTypeInfo, PyTypeObject};
|
|
||||||
use crate::types::{PyAny, PyDict, PyModule, PyType};
|
use crate::types::{PyAny, PyDict, PyModule, PyType};
|
||||||
use crate::{AsPyPointer, FromPyPointer, IntoPyPointer, PyTryFrom};
|
use crate::{
|
||||||
|
ffi, AsPyPointer, AsPyRef, FromPyPointer, IntoPyPointer, PyNativeType, PyObject, PyTryFrom,
|
||||||
|
};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
use std::ptr::NonNull;
|
|
||||||
|
|
||||||
pub use gil::prepare_freethreaded_python;
|
pub use gil::prepare_freethreaded_python;
|
||||||
|
|
||||||
|
@ -293,27 +291,18 @@ impl<'p> Python<'p> {
|
||||||
where
|
where
|
||||||
T: PyTryFrom<'p>,
|
T: PyTryFrom<'p>,
|
||||||
{
|
{
|
||||||
let obj = unsafe { gil::register_owned(self, obj.into_nonnull()) };
|
let any: &PyAny = unsafe { self.from_owned_ptr(obj.into_ptr()) };
|
||||||
<T as PyTryFrom>::try_from(obj)
|
<T as PyTryFrom>::try_from(any)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers the object in the release pool, and does an unchecked downcast
|
/// Registers the object in the release pool, and does an unchecked downcast
|
||||||
/// to the specific type.
|
/// to the specific type.
|
||||||
pub unsafe fn cast_as<T>(self, obj: PyObject) -> &'p T
|
pub unsafe fn cast_as<T>(self, obj: PyObject) -> &'p T
|
||||||
where
|
where
|
||||||
T: PyDowncastImpl + PyTypeInfo,
|
T: PyNativeType + PyTypeInfo,
|
||||||
{
|
{
|
||||||
let obj = gil::register_owned(self, obj.into_nonnull());
|
let any: &PyAny = self.from_owned_ptr(obj.into_ptr());
|
||||||
T::unchecked_downcast(obj)
|
T::unchecked_downcast(any)
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers the object pointer in the release pool.
|
|
||||||
#[allow(clippy::wrong_self_convention)]
|
|
||||||
pub unsafe fn from_borrowed_ptr_to_obj(self, ptr: *mut ffi::PyObject) -> &'p PyAny {
|
|
||||||
match NonNull::new(ptr) {
|
|
||||||
Some(p) => gil::register_borrowed(self, p),
|
|
||||||
None => crate::err::panic_after_error(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Registers the object pointer in the release pool,
|
/// Registers the object pointer in the release pool,
|
||||||
|
|
|
@ -63,32 +63,6 @@ pub mod type_flags {
|
||||||
pub const EXTENDED: usize = 1 << 4;
|
pub const EXTENDED: usize = 1 << 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reference abstraction for `PyClass` and `PyNativeType`. Used internaly.
|
|
||||||
// NOTE(kngwyu):
|
|
||||||
// `&PyCell` is a pointer of `ffi::PyObject` but `&PyAny` is a pointer of a pointer,
|
|
||||||
// so we need abstraction.
|
|
||||||
// This mismatch eventually should be fixed(e.g., https://github.com/PyO3/pyo3/issues/679).
|
|
||||||
pub unsafe trait PyDowncastImpl {
|
|
||||||
/// Cast `&PyAny` to `&Self` without no type checking.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// Unless obj is not an instance of a type corresponding to Self,
|
|
||||||
/// this method causes undefined behavior.
|
|
||||||
unsafe fn unchecked_downcast(obj: &PyAny) -> &Self;
|
|
||||||
private_decl! {}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl<'py, T> PyDowncastImpl for T
|
|
||||||
where
|
|
||||||
T: 'py + crate::PyNativeType,
|
|
||||||
{
|
|
||||||
unsafe fn unchecked_downcast(obj: &PyAny) -> &Self {
|
|
||||||
&*(obj as *const _ as *const Self)
|
|
||||||
}
|
|
||||||
private_impl! {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Python type information.
|
/// Python type information.
|
||||||
/// All Python native types(e.g., `PyDict`) and `#[pyclass]` structs implement this trait.
|
/// All Python native types(e.g., `PyDict`) and `#[pyclass]` structs implement this trait.
|
||||||
///
|
///
|
||||||
|
@ -124,7 +98,7 @@ pub unsafe trait PyTypeInfo: Sized {
|
||||||
type Initializer: PyObjectInit<Self>;
|
type Initializer: PyObjectInit<Self>;
|
||||||
|
|
||||||
/// Utility type to make AsPyRef work
|
/// Utility type to make AsPyRef work
|
||||||
type AsRefTarget: PyDowncastImpl;
|
type AsRefTarget: crate::PyNativeType;
|
||||||
|
|
||||||
/// PyTypeObject instance for this type.
|
/// PyTypeObject instance for this type.
|
||||||
fn type_object() -> &'static ffi::PyTypeObject;
|
fn type_object() -> &'static ffi::PyTypeObject;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::conversion::PyTryFrom;
|
use crate::conversion::{AsPyPointer, PyTryFrom};
|
||||||
use crate::err::PyDowncastError;
|
use crate::err::PyDowncastError;
|
||||||
use crate::internal_tricks::Unsendable;
|
use crate::ffi;
|
||||||
use crate::{ffi, PyObject};
|
use std::cell::UnsafeCell;
|
||||||
|
|
||||||
/// A Python object with GIL lifetime
|
/// A Python object with GIL lifetime
|
||||||
///
|
///
|
||||||
|
@ -28,10 +28,26 @@ use crate::{ffi, PyObject};
|
||||||
/// assert!(any.downcast::<PyList>().is_err());
|
/// assert!(any.downcast::<PyList>().is_err());
|
||||||
/// ```
|
/// ```
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyAny(PyObject, Unsendable);
|
pub struct PyAny(UnsafeCell<ffi::PyObject>);
|
||||||
|
|
||||||
|
impl crate::AsPyPointer for PyAny {
|
||||||
|
#[inline]
|
||||||
|
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||||
|
self.0.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for PyAny {
|
||||||
|
#[inline]
|
||||||
|
fn eq(&self, o: &PyAny) -> bool {
|
||||||
|
self.as_ptr() == o.as_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl crate::PyNativeType for PyAny {}
|
||||||
unsafe impl crate::type_object::PyLayout<PyAny> for ffi::PyObject {}
|
unsafe impl crate::type_object::PyLayout<PyAny> for ffi::PyObject {}
|
||||||
impl crate::type_object::PySizedLayout<PyAny> for ffi::PyObject {}
|
impl crate::type_object::PySizedLayout<PyAny> for ffi::PyObject {}
|
||||||
pyobject_native_type_named!(PyAny);
|
|
||||||
pyobject_native_type_convert!(
|
pyobject_native_type_convert!(
|
||||||
PyAny,
|
PyAny,
|
||||||
ffi::PyObject,
|
ffi::PyObject,
|
||||||
|
@ -39,6 +55,7 @@ pyobject_native_type_convert!(
|
||||||
Some("builtins"),
|
Some("builtins"),
|
||||||
ffi::PyObject_Check
|
ffi::PyObject_Check
|
||||||
);
|
);
|
||||||
|
|
||||||
pyobject_native_type_extract!(PyAny);
|
pyobject_native_type_extract!(PyAny);
|
||||||
|
|
||||||
impl PyAny {
|
impl PyAny {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, AsPyPointer, FromPy, FromPyObject, PyAny, PyObject, PyResult, PyTryFrom, Python,
|
ffi, AsPyPointer, FromPy, FromPyObject, PyAny, PyObject, PyResult, PyTryFrom, Python,
|
||||||
ToPyObject,
|
ToPyObject,
|
||||||
|
@ -7,7 +6,7 @@ use crate::{
|
||||||
|
|
||||||
/// Represents a Python `bool`.
|
/// Represents a Python `bool`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyBool(PyObject, Unsendable);
|
pub struct PyBool(PyAny);
|
||||||
|
|
||||||
pyobject_native_type!(PyBool, ffi::PyObject, ffi::PyBool_Type, ffi::PyBool_Check);
|
pyobject_native_type!(PyBool, ffi::PyObject, ffi::PyBool_Type, ffi::PyBool_Check);
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
use crate::err::{PyErr, PyResult};
|
use crate::err::{PyErr, PyResult};
|
||||||
use crate::ffi;
|
|
||||||
use crate::instance::PyNativeType;
|
use crate::instance::PyNativeType;
|
||||||
use crate::internal_tricks::Unsendable;
|
use crate::{ffi, AsPyPointer, PyAny, Python};
|
||||||
use crate::object::PyObject;
|
|
||||||
use crate::AsPyPointer;
|
|
||||||
use crate::Python;
|
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
/// Represents a Python `bytearray`.
|
/// Represents a Python `bytearray`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyByteArray(PyObject, Unsendable);
|
pub struct PyByteArray(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyByteArray, ffi::PyByteArray_Type, ffi::PyByteArray_Check);
|
pyobject_native_var_type!(PyByteArray, ffi::PyByteArray_Type, ffi::PyByteArray_Check);
|
||||||
|
|
||||||
|
@ -38,7 +34,7 @@ impl PyByteArray {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
// non-negative Py_ssize_t should always fit into Rust usize
|
// non-negative Py_ssize_t should always fit into Rust usize
|
||||||
unsafe { ffi::PyByteArray_Size(self.0.as_ptr()) as usize }
|
unsafe { ffi::PyByteArray_Size(self.as_ptr()) as usize }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if the bytearray is empty.
|
/// Checks if the bytearray is empty.
|
||||||
|
@ -69,8 +65,8 @@ impl PyByteArray {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn to_vec(&self) -> Vec<u8> {
|
pub fn to_vec(&self) -> Vec<u8> {
|
||||||
let slice = unsafe {
|
let slice = unsafe {
|
||||||
let buffer = ffi::PyByteArray_AsString(self.0.as_ptr()) as *mut u8;
|
let buffer = ffi::PyByteArray_AsString(self.as_ptr()) as *mut u8;
|
||||||
let length = ffi::PyByteArray_Size(self.0.as_ptr()) as usize;
|
let length = ffi::PyByteArray_Size(self.as_ptr()) as usize;
|
||||||
slice::from_raw_parts_mut(buffer, length)
|
slice::from_raw_parts_mut(buffer, length)
|
||||||
};
|
};
|
||||||
slice.to_vec()
|
slice.to_vec()
|
||||||
|
@ -79,7 +75,7 @@ impl PyByteArray {
|
||||||
/// Resizes the bytearray object to the new length `len`.
|
/// Resizes the bytearray object to the new length `len`.
|
||||||
pub fn resize(&self, len: usize) -> PyResult<()> {
|
pub fn resize(&self, len: usize) -> PyResult<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let result = ffi::PyByteArray_Resize(self.0.as_ptr(), len as ffi::Py_ssize_t);
|
let result = ffi::PyByteArray_Resize(self.as_ptr(), len as ffi::Py_ssize_t);
|
||||||
if result == 0 {
|
if result == 0 {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, AsPyPointer, FromPy, FromPyObject, PyAny, PyObject, PyResult, PyTryFrom, Python,
|
ffi, AsPyPointer, FromPy, FromPyObject, PyAny, PyObject, PyResult, PyTryFrom, Python,
|
||||||
ToPyObject,
|
ToPyObject,
|
||||||
|
@ -12,7 +11,7 @@ use std::str;
|
||||||
///
|
///
|
||||||
/// This type is immutable.
|
/// This type is immutable.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyBytes(PyObject, Unsendable);
|
pub struct PyBytes(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyBytes, ffi::PyBytes_Type, ffi::PyBytes_Check);
|
pyobject_native_var_type!(PyBytes, ffi::PyBytes_Type, ffi::PyBytes_Check);
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,13 @@
|
||||||
use crate::ffi;
|
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
use crate::instance::PyNativeType;
|
use crate::instance::PyNativeType;
|
||||||
use crate::internal_tricks::Unsendable;
|
use crate::{ffi, AsPyPointer, PyAny, Python};
|
||||||
use crate::AsPyPointer;
|
|
||||||
use crate::PyObject;
|
|
||||||
use crate::Python;
|
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
use std::ops::*;
|
use std::ops::*;
|
||||||
use std::os::raw::c_double;
|
use std::os::raw::c_double;
|
||||||
|
|
||||||
/// Represents a Python `complex`.
|
/// Represents a Python `complex`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyComplex(PyObject, Unsendable);
|
pub struct PyComplex(PyAny);
|
||||||
|
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyComplex,
|
PyComplex,
|
||||||
|
@ -133,7 +129,7 @@ impl<'py> Neg for &'py PyComplex {
|
||||||
#[cfg(feature = "num-complex")]
|
#[cfg(feature = "num-complex")]
|
||||||
mod complex_conversion {
|
mod complex_conversion {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{FromPyObject, PyAny, PyErr, PyResult, ToPyObject};
|
use crate::{FromPyObject, PyAny, PyErr, PyObject, PyResult, ToPyObject};
|
||||||
use num_complex::Complex;
|
use num_complex::Complex;
|
||||||
|
|
||||||
impl PyComplex {
|
impl PyComplex {
|
||||||
|
|
|
@ -25,12 +25,9 @@ use crate::ffi::{
|
||||||
PyDateTime_TIME_GET_HOUR, PyDateTime_TIME_GET_MICROSECOND, PyDateTime_TIME_GET_MINUTE,
|
PyDateTime_TIME_GET_HOUR, PyDateTime_TIME_GET_MICROSECOND, PyDateTime_TIME_GET_MINUTE,
|
||||||
PyDateTime_TIME_GET_SECOND,
|
PyDateTime_TIME_GET_SECOND,
|
||||||
};
|
};
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::object::PyObject;
|
use crate::object::PyObject;
|
||||||
use crate::types::PyTuple;
|
use crate::types::PyTuple;
|
||||||
use crate::AsPyPointer;
|
use crate::{AsPyPointer, PyAny, Python, ToPyObject};
|
||||||
use crate::Python;
|
|
||||||
use crate::ToPyObject;
|
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -66,7 +63,8 @@ pub trait PyTimeAccess {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bindings around `datetime.date`
|
/// Bindings around `datetime.date`
|
||||||
pub struct PyDate(PyObject, Unsendable);
|
#[repr(transparent)]
|
||||||
|
pub struct PyDate(PyAny);
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyDate,
|
PyDate,
|
||||||
crate::ffi::PyDateTime_Date,
|
crate::ffi::PyDateTime_Date,
|
||||||
|
@ -122,7 +120,8 @@ impl PyDateAccess for PyDate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bindings for `datetime.datetime`
|
/// Bindings for `datetime.datetime`
|
||||||
pub struct PyDateTime(PyObject, Unsendable);
|
#[repr(transparent)]
|
||||||
|
pub struct PyDateTime(PyAny);
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyDateTime,
|
PyDateTime,
|
||||||
crate::ffi::PyDateTime_DateTime,
|
crate::ffi::PyDateTime_DateTime,
|
||||||
|
@ -232,7 +231,8 @@ impl PyTimeAccess for PyDateTime {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bindings for `datetime.time`
|
/// Bindings for `datetime.time`
|
||||||
pub struct PyTime(PyObject, Unsendable);
|
#[repr(transparent)]
|
||||||
|
pub struct PyTime(PyAny);
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyTime,
|
PyTime,
|
||||||
crate::ffi::PyDateTime_Time,
|
crate::ffi::PyDateTime_Time,
|
||||||
|
@ -317,7 +317,8 @@ impl PyTimeAccess for PyTime {
|
||||||
/// Bindings for `datetime.tzinfo`
|
/// Bindings for `datetime.tzinfo`
|
||||||
///
|
///
|
||||||
/// This is an abstract base class and should not be constructed directly.
|
/// This is an abstract base class and should not be constructed directly.
|
||||||
pub struct PyTzInfo(PyObject, Unsendable);
|
#[repr(transparent)]
|
||||||
|
pub struct PyTzInfo(PyAny);
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyTzInfo,
|
PyTzInfo,
|
||||||
crate::ffi::PyObject,
|
crate::ffi::PyObject,
|
||||||
|
@ -327,7 +328,8 @@ pyobject_native_type!(
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Bindings for `datetime.timedelta`
|
/// Bindings for `datetime.timedelta`
|
||||||
pub struct PyDelta(PyObject, Unsendable);
|
#[repr(transparent)]
|
||||||
|
pub struct PyDelta(PyAny);
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyDelta,
|
PyDelta,
|
||||||
crate::ffi::PyDateTime_Delta,
|
crate::ffi::PyDateTime_Delta,
|
||||||
|
|
|
@ -2,22 +2,19 @@
|
||||||
|
|
||||||
use crate::err::{self, PyErr, PyResult};
|
use crate::err::{self, PyErr, PyResult};
|
||||||
use crate::instance::PyNativeType;
|
use crate::instance::PyNativeType;
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::object::PyObject;
|
use crate::object::PyObject;
|
||||||
use crate::types::{PyAny, PyList};
|
use crate::types::{PyAny, PyList};
|
||||||
use crate::AsPyPointer;
|
|
||||||
#[cfg(not(PyPy))]
|
#[cfg(not(PyPy))]
|
||||||
use crate::IntoPyPointer;
|
use crate::IntoPyPointer;
|
||||||
use crate::Python;
|
use crate::{
|
||||||
use crate::{ffi, IntoPy};
|
ffi, AsPyPointer, FromPyObject, IntoPy, PyTryFrom, Python, ToBorrowedObject, ToPyObject,
|
||||||
use crate::{FromPyObject, PyTryFrom};
|
};
|
||||||
use crate::{ToBorrowedObject, ToPyObject};
|
|
||||||
use std::collections::{BTreeMap, HashMap};
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::{cmp, collections, hash};
|
use std::{cmp, collections, hash};
|
||||||
|
|
||||||
/// Represents a Python `dict`.
|
/// Represents a Python `dict`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyDict(PyObject, Unsendable);
|
pub struct PyDict(PyAny);
|
||||||
|
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyDict,
|
PyDict,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
//
|
//
|
||||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, AsPyPointer, FromPy, FromPyObject, ObjectProtocol, PyAny, PyErr, PyNativeType, PyObject,
|
ffi, AsPyPointer, FromPy, FromPyObject, ObjectProtocol, PyAny, PyErr, PyNativeType, PyObject,
|
||||||
PyResult, Python, ToPyObject,
|
PyResult, Python, ToPyObject,
|
||||||
|
@ -15,7 +14,7 @@ use std::os::raw::c_double;
|
||||||
/// and [extract](struct.PyObject.html#method.extract)
|
/// and [extract](struct.PyObject.html#method.extract)
|
||||||
/// with `f32`/`f64`.
|
/// with `f32`/`f64`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyFloat(PyObject, Unsendable);
|
pub struct PyFloat(PyAny);
|
||||||
|
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PyFloat,
|
PyFloat,
|
||||||
|
@ -32,7 +31,7 @@ impl PyFloat {
|
||||||
|
|
||||||
/// Gets the value of this float.
|
/// Gets the value of this float.
|
||||||
pub fn value(&self) -> c_double {
|
pub fn value(&self) -> c_double {
|
||||||
unsafe { ffi::PyFloat_AsDouble(self.0.as_ptr()) }
|
unsafe { ffi::PyFloat_AsDouble(self.as_ptr()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
use crate::err::{self, PyResult};
|
use crate::err::{self, PyResult};
|
||||||
use crate::ffi::{self, Py_ssize_t};
|
use crate::ffi::{self, Py_ssize_t};
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AsPyPointer, IntoPy, IntoPyPointer, PyAny, PyNativeType, PyObject, Python, ToBorrowedObject,
|
AsPyPointer, IntoPy, IntoPyPointer, PyAny, PyNativeType, PyObject, Python, ToBorrowedObject,
|
||||||
ToPyObject,
|
ToPyObject,
|
||||||
|
@ -12,7 +11,7 @@ use crate::{
|
||||||
|
|
||||||
/// Represents a Python `list`.
|
/// Represents a Python `list`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyList(PyObject, Unsendable);
|
pub struct PyList(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyList, ffi::PyList_Type, ffi::PyList_Check);
|
pyobject_native_var_type!(PyList, ffi::PyList_Type, ffi::PyList_Check);
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ macro_rules! pyobject_native_type_named (
|
||||||
impl<$($type_param,)*> ::std::convert::AsRef<$crate::PyAny> for $name {
|
impl<$($type_param,)*> ::std::convert::AsRef<$crate::PyAny> for $name {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn as_ref(&self) -> &$crate::PyAny {
|
fn as_ref(&self) -> &$crate::PyAny {
|
||||||
unsafe{&*(self as *const $name as *const $crate::PyAny)}
|
unsafe { &*(self.as_ptr() as *const $crate::PyAny) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ macro_rules! pyobject_native_type_convert(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_object(&self, py: $crate::Python) -> $crate::PyObject {
|
fn to_object(&self, py: $crate::Python) -> $crate::PyObject {
|
||||||
use $crate::AsPyPointer;
|
use $crate::AsPyPointer;
|
||||||
unsafe {$crate::PyObject::from_borrowed_ptr(py, self.0.as_ptr())}
|
unsafe { $crate::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ use crate::err::{PyErr, PyResult};
|
||||||
use crate::exceptions;
|
use crate::exceptions;
|
||||||
use crate::ffi;
|
use crate::ffi;
|
||||||
use crate::instance::PyNativeType;
|
use crate::instance::PyNativeType;
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::object::PyObject;
|
use crate::object::PyObject;
|
||||||
use crate::objectprotocol::ObjectProtocol;
|
use crate::objectprotocol::ObjectProtocol;
|
||||||
use crate::pyclass::PyClass;
|
use crate::pyclass::PyClass;
|
||||||
|
@ -20,7 +19,7 @@ use std::str;
|
||||||
|
|
||||||
/// Represents a Python `module` object.
|
/// Represents a Python `module` object.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyModule(PyObject, Unsendable);
|
pub struct PyModule(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyModule, ffi::PyModule_Type, ffi::PyModule_Check);
|
pyobject_native_var_type!(PyModule, ffi::PyModule_Type, ffi::PyModule_Check);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
//
|
//
|
||||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||||
|
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
exceptions, ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject,
|
exceptions, ffi, AsPyPointer, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject,
|
||||||
PyResult, Python, ToPyObject,
|
PyResult, Python, ToPyObject,
|
||||||
|
@ -111,7 +110,7 @@ macro_rules! int_convert_128 {
|
||||||
/// and [extract](struct.PyObject.html#method.extract)
|
/// and [extract](struct.PyObject.html#method.extract)
|
||||||
/// with the primitive Rust integer types.
|
/// with the primitive Rust integer types.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyLong(PyObject, Unsendable);
|
pub struct PyLong(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyLong, ffi::PyLong_Type, ffi::PyLong_Check);
|
pyobject_native_var_type!(PyLong, ffi::PyLong_Type, ffi::PyLong_Check);
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ use crate::err::{self, PyDowncastError, PyErr, PyResult};
|
||||||
use crate::exceptions;
|
use crate::exceptions;
|
||||||
use crate::ffi::{self, Py_ssize_t};
|
use crate::ffi::{self, Py_ssize_t};
|
||||||
use crate::instance::PyNativeType;
|
use crate::instance::PyNativeType;
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::object::PyObject;
|
|
||||||
use crate::objectprotocol::ObjectProtocol;
|
use crate::objectprotocol::ObjectProtocol;
|
||||||
use crate::types::{PyAny, PyList, PyTuple};
|
use crate::types::{PyAny, PyList, PyTuple};
|
||||||
use crate::AsPyPointer;
|
use crate::AsPyPointer;
|
||||||
|
@ -14,7 +12,7 @@ use crate::{FromPyObject, PyTryFrom, ToBorrowedObject};
|
||||||
|
|
||||||
/// Represents a reference to a Python object supporting the sequence protocol.
|
/// Represents a reference to a Python object supporting the sequence protocol.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PySequence(PyObject, Unsendable);
|
pub struct PySequence(PyAny);
|
||||||
pyobject_native_type_named!(PySequence);
|
pyobject_native_type_named!(PySequence);
|
||||||
pyobject_native_type_extract!(PySequence);
|
pyobject_native_type_extract!(PySequence);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
use crate::err::{self, PyErr, PyResult};
|
use crate::err::{self, PyErr, PyResult};
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, AsPyPointer, FromPy, FromPyObject, IntoPy, PyAny, PyNativeType, PyObject, Python,
|
ffi, AsPyPointer, FromPy, FromPyObject, IntoPy, PyAny, PyNativeType, PyObject, Python,
|
||||||
ToBorrowedObject, ToPyObject,
|
ToBorrowedObject, ToPyObject,
|
||||||
|
@ -13,11 +12,11 @@ use std::{collections, hash, ptr};
|
||||||
|
|
||||||
/// Represents a Python `set`
|
/// Represents a Python `set`
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PySet(PyObject, Unsendable);
|
pub struct PySet(PyAny);
|
||||||
|
|
||||||
/// Represents a Python `frozenset`
|
/// Represents a Python `frozenset`
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyFrozenSet(PyObject, Unsendable);
|
pub struct PyFrozenSet(PyAny);
|
||||||
|
|
||||||
pyobject_native_type!(PySet, ffi::PySetObject, ffi::PySet_Type, ffi::PySet_Check);
|
pyobject_native_type!(PySet, ffi::PySetObject, ffi::PySet_Type, ffi::PySet_Check);
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
|
|
|
@ -3,17 +3,14 @@
|
||||||
use crate::err::{PyErr, PyResult};
|
use crate::err::{PyErr, PyResult};
|
||||||
use crate::ffi::{self, Py_ssize_t};
|
use crate::ffi::{self, Py_ssize_t};
|
||||||
use crate::instance::PyNativeType;
|
use crate::instance::PyNativeType;
|
||||||
use crate::internal_tricks::Unsendable;
|
use crate::{AsPyPointer, PyAny, PyObject, Python, ToPyObject};
|
||||||
use crate::object::PyObject;
|
|
||||||
use crate::Python;
|
|
||||||
use crate::{AsPyPointer, ToPyObject};
|
|
||||||
use std::os::raw::c_long;
|
use std::os::raw::c_long;
|
||||||
|
|
||||||
/// Represents a Python `slice`.
|
/// Represents a Python `slice`.
|
||||||
///
|
///
|
||||||
/// Only `c_long` indices supported at the moment by the `PySlice` object.
|
/// Only `c_long` indices supported at the moment by the `PySlice` object.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PySlice(PyObject, Unsendable);
|
pub struct PySlice(PyAny);
|
||||||
|
|
||||||
pyobject_native_type!(
|
pyobject_native_type!(
|
||||||
PySlice,
|
PySlice,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
|
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ffi, gil, AsPyPointer, FromPy, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject,
|
ffi, gil, AsPyPointer, FromPy, FromPyObject, IntoPy, PyAny, PyErr, PyNativeType, PyObject,
|
||||||
PyResult, PyTryFrom, Python, ToPyObject,
|
PyResult, PyTryFrom, Python, ToPyObject,
|
||||||
|
@ -15,7 +14,7 @@ use std::str;
|
||||||
///
|
///
|
||||||
/// This type is immutable.
|
/// This type is immutable.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyString(PyObject, Unsendable);
|
pub struct PyString(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check);
|
pyobject_native_var_type!(PyString, ffi::PyUnicode_Type, ffi::PyUnicode_Check);
|
||||||
|
|
||||||
|
@ -48,7 +47,7 @@ impl PyString {
|
||||||
pub fn as_bytes(&self) -> PyResult<&[u8]> {
|
pub fn as_bytes(&self) -> PyResult<&[u8]> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut size: ffi::Py_ssize_t = 0;
|
let mut size: ffi::Py_ssize_t = 0;
|
||||||
let data = ffi::PyUnicode_AsUTF8AndSize(self.0.as_ptr(), &mut size) as *const u8;
|
let data = ffi::PyUnicode_AsUTF8AndSize(self.as_ptr(), &mut size) as *const u8;
|
||||||
if data.is_null() {
|
if data.is_null() {
|
||||||
Err(PyErr::fetch(self.py()))
|
Err(PyErr::fetch(self.py()))
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,7 +73,7 @@ impl PyString {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
let py_bytes = ffi::PyUnicode_AsEncodedString(
|
let py_bytes = ffi::PyUnicode_AsEncodedString(
|
||||||
self.0.as_ptr(),
|
self.as_ptr(),
|
||||||
CStr::from_bytes_with_nul(b"utf-8\0").unwrap().as_ptr(),
|
CStr::from_bytes_with_nul(b"utf-8\0").unwrap().as_ptr(),
|
||||||
CStr::from_bytes_with_nul(b"surrogatepass\0")
|
CStr::from_bytes_with_nul(b"surrogatepass\0")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
|
|
||||||
use crate::ffi::{self, Py_ssize_t};
|
use crate::ffi::{self, Py_ssize_t};
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
exceptions, AsPyPointer, AsPyRef, FromPy, FromPyObject, IntoPy, IntoPyPointer, Py, PyAny,
|
exceptions, AsPyPointer, AsPyRef, FromPy, FromPyObject, IntoPy, IntoPyPointer, Py, PyAny,
|
||||||
PyErr, PyNativeType, PyObject, PyResult, PyTryFrom, Python, ToPyObject,
|
PyErr, PyNativeType, PyObject, PyResult, PyTryFrom, Python, ToPyObject,
|
||||||
|
@ -12,7 +11,7 @@ use std::slice;
|
||||||
///
|
///
|
||||||
/// This type is immutable.
|
/// This type is immutable.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyTuple(PyObject, Unsendable);
|
pub struct PyTuple(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyTuple, ffi::PyTuple_Type, ffi::PyTuple_Check);
|
pyobject_native_var_type!(PyTuple, ffi::PyTuple_Type, ffi::PyTuple_Check);
|
||||||
|
|
||||||
|
|
|
@ -3,19 +3,15 @@
|
||||||
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
// based on Daniel Grunwald's https://github.com/dgrunwald/rust-cpython
|
||||||
|
|
||||||
use crate::err::{PyErr, PyResult};
|
use crate::err::{PyErr, PyResult};
|
||||||
use crate::ffi;
|
|
||||||
use crate::instance::{Py, PyNativeType};
|
use crate::instance::{Py, PyNativeType};
|
||||||
use crate::internal_tricks::Unsendable;
|
|
||||||
use crate::object::PyObject;
|
|
||||||
use crate::type_object::PyTypeObject;
|
use crate::type_object::PyTypeObject;
|
||||||
use crate::AsPyPointer;
|
use crate::{ffi, AsPyPointer, PyAny, Python};
|
||||||
use crate::Python;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
|
||||||
/// Represents a reference to a Python `type object`.
|
/// Represents a reference to a Python `type object`.
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PyType(PyObject, Unsendable);
|
pub struct PyType(PyAny);
|
||||||
|
|
||||||
pyobject_native_var_type!(PyType, ffi::PyType_Type, ffi::PyType_Check);
|
pyobject_native_var_type!(PyType, ffi::PyType_Type, ffi::PyType_Check);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue