simplify Py and PyPtr objects

This commit is contained in:
Nikolay Kim 2017-05-30 18:57:36 -07:00
parent 3040ac12b9
commit 5d25c7deea
11 changed files with 87 additions and 407 deletions

View File

@ -1,9 +1,10 @@
use ffi;
use err::PyResult;
use pointers::pptr;
use python::{Python, ToPythonPointer};
use python::{Python, ToPythonPointer, PyDowncastFrom};
use objects::{PyObject, PyTuple};
use native::PyNativeObject;
use typeob::PyTypeInfo;
/// Conversion trait that allows various objects to be converted into PyObject
@ -147,7 +148,6 @@ impl<T> IntoPyObject for Option<T> where T: IntoPyObject {
}
}
/// `()` is converted to Python `None`.
impl ToPyObject for () {
fn to_object<'p>(&self, py: Python<'p>) -> PyObject<'p> {
@ -155,6 +155,16 @@ impl ToPyObject for () {
}
}
/// Extract reference to instance from PyObject
impl<'source, T> ::FromPyObject<'source> for &'source T
where T: PyTypeInfo + PyDowncastFrom<'source>
{
#[inline]
default fn extract(py: &'source PyObject<'source>) -> PyResult<&'source T>
{
Ok(py.cast_as()?)
}
}
impl <'source, T> FromPyObject<'source> for Option<T> where T: FromPyObject<'source> {
fn extract(obj: &'source PyObject) -> PyResult<Self>

View File

@ -19,7 +19,6 @@
use std::ptr;
use ffi;
use pointers::Py;
use python::Python;
use objects::PyObject;
@ -140,6 +139,6 @@ macro_rules! py_fn_impl {
#[allow(dead_code)]
pub unsafe fn py_fn_impl<'p>(py: Python<'p>,
method_def: *mut ffi::PyMethodDef) -> Py<'p, PyObject> {
Py::from_owned_ptr_or_panic(py, ffi::PyCFunction_New(method_def, ptr::null_mut()))
method_def: *mut ffi::PyMethodDef) -> PyObject<'p> {
PyObject::from_owned_ptr_or_panic(py, ffi::PyCFunction_New(method_def, ptr::null_mut()))
}

View File

@ -216,7 +216,7 @@ pub unsafe fn py_module_init_impl(
return module;
}
let module = match Py::<PyModule>::cast_from_owned_ptr(py, module) {
let module = match PyObject::from_owned_ptr(py, module).cast_into::<PyModule>(py) {
Ok(m) => m,
Err(e) => {
PyErr::from(e).restore(py);

View File

@ -408,7 +408,7 @@ impl<'p, T> fmt::Debug for PyPtr<T> where T: ObjectProtocol<'p> + PyTypeInfo {
let py = gil.python();
// TODO: we shouldn't use fmt::Error when repr() fails
let r = self.as_ref(py);
let r = self.as_object(py);
let repr_obj = try!(r.repr().map_err(|_| fmt::Error));
f.write_str(&repr_obj.to_string_lossy())
}
@ -420,8 +420,8 @@ impl<'p, T> fmt::Display for PyPtr<T> where T: ObjectProtocol<'p> + PyTypeInfo {
let py = gil.python();
// TODO: we shouldn't use fmt::Error when repr() fails
let r = self.as_ref(py);
let repr_obj = try!(r.as_ref().str().map_err(|_| fmt::Error));
let r = self.as_object(py);
let repr_obj = try!(r.str().map_err(|_| fmt::Error));
f.write_str(&repr_obj.to_string_lossy())
}
}

View File

@ -28,8 +28,9 @@ impl<'p> PyDict<'p> {
}
/// Construct a new dict with the given raw pointer
pub fn from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> PyDict<'p> {
unsafe { PyDict(pyptr::from_borrowed_ptr(py, ptr)) }
/// Undefined behavior if the pointer is NULL or invalid.
pub unsafe fn from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject) -> PyDict<'p> {
PyDict(pyptr::from_borrowed_ptr(py, ptr))
}
/// Return a new dictionary that contains the same key-value pairs as self.

View File

@ -9,7 +9,7 @@ use std::{self, mem, ops};
use std::ffi::CStr;
use ffi;
use pointers::PyPtr;
use pointers::pptr;
use python::{Python, ToPythonPointer};
use err::PyResult;
use native::PyNativeObject;
@ -86,10 +86,10 @@ exc_type!(UnicodeTranslateError, PyExc_UnicodeTranslateError);
impl UnicodeDecodeError {
pub fn new(py: Python, encoding: &CStr, input: &[u8], range: ops::Range<usize>, reason: &CStr)
-> PyResult<PyPtr<UnicodeDecodeError>> {
-> PyResult<pptr> {
unsafe {
let input: &[c_char] = mem::transmute(input);
PyPtr::from_owned_ptr_or_err(
pptr::from_owned_ptr_or_err(
py, ffi::PyUnicodeDecodeError_Create(
encoding.as_ptr(),
input.as_ptr(),
@ -101,7 +101,7 @@ impl UnicodeDecodeError {
}
pub fn new_utf8<'p>(py: Python, input: &[u8], err: std::str::Utf8Error)
-> PyResult<PyPtr<UnicodeDecodeError>>
-> PyResult<pptr>
{
let pos = err.valid_up_to();
UnicodeDecodeError::new(py, cstr!("utf-8"), input, pos .. pos+1, cstr!("invalid utf-8"))

View File

@ -55,7 +55,10 @@ macro_rules! pyobject_nativetype(
unsafe { $crate::std::mem::transmute(self) }
}
fn as_object(self) -> $crate::PyObject<'p> {
unsafe { $crate::std::mem::transmute(self) }
unsafe {
$crate::ffi::Py_INCREF(self.as_ptr());
$crate::std::mem::transmute(self)
}
}
fn clone_object(&self) -> $name<'p> {
use $crate::{ToPythonPointer, PythonObjectWithGilToken};

View File

@ -9,7 +9,6 @@ use std::ffi::{CStr, CString};
use ::pyptr;
use conversion::{ToPyObject, ToPyTuple};
use pointers::PyPtr;
use python::{ToPythonPointer, Python};
use token::PythonObjectWithGilToken;
use objects::{PyObject, PyDict, PyType, exc};
@ -46,9 +45,9 @@ impl<'p> PyModule<'p> {
/// Return the dictionary object that implements module's namespace;
/// this object is the same as the `__dict__` attribute of the module object.
pub fn dict(&self) -> PyPtr<PyDict> {
pub fn dict(&self) -> PyDict<'p> {
unsafe {
PyPtr::from_borrowed_ptr(ffi::PyModule_GetDict(self.as_ptr()))
PyDict::from_borrowed_ptr(self.gil(), ffi::PyModule_GetDict(self.as_ptr()))
}
}

View File

@ -196,104 +196,28 @@ impl Drop for pptr {
}
pub struct PyPtr<T> {
inner: *mut ffi::PyObject,
_t: PhantomData<T>,
}
impl<T> PyPtr<T> {
/// Creates a PyPtr instance for the given FFI pointer.
/// This moves ownership over the pointer into the Py.
/// Undefined behavior if the pointer is NULL or invalid.
#[inline]
pub unsafe fn from_owned_ptr(ptr: *mut ffi::PyObject) -> PyPtr<T> {
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
PyPtr {inner: ptr, _t: PhantomData}
}
/// Creates a PyObject instance for the given FFI pointer.
/// This moves ownership over the pointer into the PyObject.
/// Returns None for null pointers; undefined behavior if the pointer is invalid.
#[inline]
pub unsafe fn from_owned_ptr_or_opt(_py: Python, ptr: *mut ffi::PyObject)
-> Option<PyPtr<T>> {
if ptr.is_null() {
None
} else {
Some(PyPtr::from_owned_ptr(ptr))
}
}
/// Construct PyPtr<PyObject> from the result of a Python FFI call that
/// returns a new reference (owned pointer).
/// Returns `Err(PyErr)` if the pointer is `null`.
/// Unsafe because the pointer might be invalid.
pub unsafe fn from_owned_ptr_or_err(py: Python, ptr: *mut ffi::PyObject) -> PyResult<PyPtr<T>>
{
if ptr.is_null() {
Err(PyErr::fetch(py))
} else {
Ok(PyPtr::from_owned_ptr(ptr))
}
}
/// Cast from ffi::PyObject ptr to PyPtr pointer
#[inline]
pub unsafe fn from_owned_ptr_or_panic(ptr: *mut ffi::PyObject) -> PyPtr<T>
{
if ptr.is_null() {
::err::panic_after_error();
} else {
PyPtr::from_owned_ptr(ptr)
}
}
/// Creates a PyPtr instance for the given FFI pointer.
/// Calls Py_INCREF() on the ptr.
/// Undefined behavior if the pointer is NULL or invalid.
/// Caller of this method has to have valid Python object.
#[inline]
pub unsafe fn from_borrowed_ptr(ptr: *mut ffi::PyObject) -> PyPtr<T> {
debug_assert!(!ptr.is_null() && ffi::Py_REFCNT(ptr) > 0);
ffi::Py_INCREF(ptr);
PyPtr {inner: ptr, _t: PhantomData}
}
/// Creates a Py instance for the given FFI pointer.
/// Calls Py_INCREF() on the ptr.
#[inline]
pub unsafe fn from_borrowed_ptr_opt(_py: Python,
ptr: *mut ffi::PyObject) -> Option<PyPtr<T>> {
if ptr.is_null() {
None
} else {
debug_assert!(ffi::Py_REFCNT(ptr) > 0);
ffi::Py_INCREF(ptr);
Some(PyPtr{inner: ptr, _t: PhantomData})
}
}
pub fn as_ref<'p>(&self, py: Python<'p>) -> Py<'p, T> {
unsafe { Py::from_borrowed_ptr(py, self.inner) }
}
pub fn into_ref<'p>(self, py: Python<'p>) -> Py<'p, T> {
let p = Py{inner: self.inner, _t: PhantomData, py: py};
std::mem::forget(self);
p
}
/// Converts PyPtr<T> -> PyPtr<PyObject>
/// Converts PyPtr<T> -> pptr
/// Consumes `self` without calling `Py_INCREF()`
#[inline]
pub fn park(self) -> pptr {
unsafe { std::mem::transmute(self) }
}
/// Converts PyPtr<T> -> &PyObject<'p>.
/// Converts PyPtr<T> -> Py<'p, T>
/// Consumes `self` without calling `Py_INCREF()`
#[inline]
pub fn unpark<'p>(self, _py: Python<'p>) -> Py<'p, T> {
unsafe { std::mem::transmute(self) }
}
/// Returns PyObject reference.
#[inline]
pub fn as_object<'p>(&self, _py: Python<'p>) -> &PyObject<'p> {
unsafe { std::mem::transmute(self) }
@ -306,39 +230,32 @@ impl<T> PyPtr<T> {
unsafe { std::mem::transmute(self) }
}
/// Gets the reference count of this PyPtr object.
#[inline]
pub fn get_refcnt(&self) -> usize {
unsafe { ffi::Py_REFCNT(self.inner) as usize }
}
#[inline]
pub fn clone_ref(&self, _py: Python) -> PyPtr<T> {
unsafe { PyPtr::from_borrowed_ptr(self.inner) }
unsafe {
ffi::Py_INCREF(self.inner);
PyPtr {inner: self.inner, _t: PhantomData}
}
}
}
impl<T> PyPtr<T> where T: PyTypeInfo
{
#[inline]
pub fn as_ref(&self, _py: Python) -> &T {
let offset = <T as PyTypeInfo>::offset();
unsafe {
let ptr = (self.inner as *mut u8).offset(offset) as *mut T;
ptr.as_ref().unwrap()
}
}
/// Unchecked downcast from other PyPtr<S> to PyPtr<S>.
/// Undefined behavior if the input object does not have the expected type.
#[inline]
pub unsafe fn unchecked_downcast_from<S>(py: PyPtr<S>) -> PyPtr<T>
{
let res = PyPtr {inner: py.inner, _t: PhantomData};
std::mem::forget(py);
res
}
/// Casts the PyPtr to a concrete Python object type.
/// Fails with `PyDowncastError` if the object is not of the expected type.
#[inline]
pub fn cast_into<'p, D>(self, py: Python<'p>) -> Result<D, PyDowncastError<'p>>
where D: ::PyDowncastInto<'p>
{
match <D as ::PyDowncastInto>::downcast_from_owned_ptr(py, self.inner) {
Ok(ptr) => {
std::mem::forget(self);
Ok(ptr)
}
Err(e) => Err(e)
pub fn as_mut(&self, _py: Python) -> &mut T {
let offset = <T as PyTypeInfo>::offset();
unsafe {
let ptr = (self.inner as *mut u8).offset(offset) as *mut T;
ptr.as_mut().unwrap()
}
}
}
@ -363,6 +280,21 @@ impl<T> IntoPythonPointer for PyPtr<T> {
}
}
impl<T> ToPyObject for PyPtr<T> {
#[inline]
fn to_object<'p>(&self, py: Python<'p>) -> PyObject<'p> {
PyObject::from_borrowed_ptr(py, self.inner)
}
#[inline]
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R
{
f(self.inner)
}
}
impl<T> IntoPyObject for PyPtr<T> {
#[inline]
@ -371,7 +303,6 @@ impl<T> IntoPyObject for PyPtr<T> {
}
}
// PyPtr is thread-safe, because all operations on it require a Python<'p> token.
unsafe impl<T> Send for PyPtr<T> {}
unsafe impl<T> Sync for PyPtr<T> {}
@ -406,42 +337,6 @@ impl<'p, T> Py<'p, T>
Py {inner: ptr, _t: PhantomData, py: py}
}
/// Cast from ffi::PyObject ptr to a concrete object.
#[inline]
pub unsafe fn from_owned_ptr_or_panic(py: Python<'p>, ptr: *mut ffi::PyObject) -> Py<'p, T>
{
if ptr.is_null() {
::err::panic_after_error();
} else {
Py::from_owned_ptr(py, ptr)
}
}
#[inline]
pub unsafe fn from_owned_ptr_or_opt(py: Python<'p>, ptr: *mut ffi::PyObject)
-> Option<Py<'p, T>>
{
if ptr.is_null() {
None
} else {
Some(Py::from_owned_ptr(py, ptr))
}
}
/// Construct Py<'p, PyObj> from the result of a Python FFI call that
/// returns a new reference (owned pointer).
/// Returns `Err(PyErr)` if the pointer is `null`.
/// Unsafe because the pointer might be invalid.
pub unsafe fn from_owned_ptr_or_err(py: Python<'p>, ptr: *mut ffi::PyObject)
-> PyResult<Py<'p, T>>
{
if ptr.is_null() {
Err(PyErr::fetch(py))
} else {
Ok(Py::from_owned_ptr(py, ptr))
}
}
/// Creates a Py instance for the given FFI pointer.
/// Calls Py_INCREF() on the ptr.
/// Undefined behavior if the pointer is NULL or invalid.
@ -452,79 +347,25 @@ impl<'p, T> Py<'p, T>
Py {inner: ptr, _t: PhantomData, py: py}
}
/// Creates a Py instance for the given FFI pointer.
/// Calls Py_INCREF() on the ptr.
/// Convert tp `PyPtr<T>` pointer
#[inline]
pub unsafe fn from_borrowed_ptr_opt(py: Python<'p>,
ptr: *mut ffi::PyObject) -> Option<Py<'p, T>> {
if ptr.is_null() {
None
} else {
debug_assert!(ffi::Py_REFCNT(ptr) > 0);
ffi::Py_INCREF(ptr);
Some(Py {inner: ptr, _t: PhantomData, py: py})
}
}
/// Gets the reference count of this Py object.
#[inline]
pub fn get_refcnt(&self) -> usize {
unsafe { ffi::Py_REFCNT(self.inner) as usize }
}
/// Convert tp `pptr` pointer
#[inline]
pub fn park(self) -> pptr {
pub fn park(self) -> PyPtr<T> {
unsafe { std::mem::transmute(self) }
}
/// Creates a PyPtr instance. Calls Py_INCREF() on the ptr.
/// Returns owned PyObject<'p> reference
#[inline]
pub fn as_pptr(&self) -> PyPtr<T> {
unsafe {
ffi::Py_INCREF(self.inner);
}
PyPtr { inner: self.inner, _t: PhantomData }
}
/// Consumes a Py<T> instance and creates a PyPtr instance.
/// Ownership moves over to the PyPtr<T> instance, Does not call Py_INCREF() on the ptr.
#[inline]
pub fn into_pptr(self) -> PyPtr<T> {
let ptr = PyPtr { inner: self.inner, _t: PhantomData };
std::mem::forget(self);
ptr
}
/// Converts Py<'p, T> -> PyObject<'p>. Calls Py_INCREF() on the ptr.
#[inline]
pub fn as_pyobject(&self) -> &PyObject<'p> {
pub fn as_object(&self) -> &'p PyObject<'p> {
unsafe { std::mem::transmute(self) }
}
/// Converts Py<'p, T> -> PyObject<'p>
/// Consumes `self` without calling `Py_DECREF()`
#[inline]
pub fn into_pyobject(self) -> PyObject<'p> {
pub fn into_object(self) -> PyObject<'p> {
unsafe { std::mem::transmute(self) }
}
/// Unchecked downcast from other Py<S> to Py<S>.
/// Undefined behavior if the input object does not have the expected type.
#[inline]
pub unsafe fn unchecked_downcast_from<'a, S>(ob: Py<'a, S>) -> Py<'a, T>
{
let res = Py {inner: ob.inner, _t: PhantomData, py: ob.py};
std::mem::forget(ob);
res
}
#[inline]
pub fn clone_ref(&self) -> Py<'p, T> {
unsafe { ffi::Py_INCREF(self.inner) };
Py {inner: self.inner, _t: self._t, py: self.py}
}
#[inline]
pub fn gil(&self) -> Python<'p> {
self.py
@ -542,61 +383,9 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
Ok(Py{inner: ob, _t: PhantomData, py: py})
}
/// Cast from ffi::PyObject ptr to a concrete object.
#[inline]
pub fn cast_from_borrowed_ptr(py: Python<'p>, ptr: *mut ffi::PyObject)
-> Result<Py<'p, T>, ::PyDowncastError<'p>>
{
let checked = unsafe { ffi::PyObject_TypeCheck(ptr, T::type_object()) != 0 };
if checked {
Ok( unsafe { Py::from_borrowed_ptr(py, ptr) })
} else {
Err(::PyDowncastError(py, None))
}
}
/// Cast from ffi::PyObject ptr to a concrete object.
#[inline]
pub fn cast_from_owned_ptr(py: Python<'p>, ptr: *mut ffi::PyObject)
-> Result<Py<'p, T>, ::PyDowncastError<'p>>
{
let checked = unsafe { ffi::PyObject_TypeCheck(ptr, T::type_object()) != 0 };
if checked {
Ok( unsafe { Py::from_owned_ptr(py, ptr) })
} else {
Err(::PyDowncastError(py, None))
}
}
#[inline]
pub fn cast_from_owned_or_err(py: Python<'p>, ptr: *mut ffi::PyObject)
-> PyResult<Py<'p, T>>
{
if ptr.is_null() {
Err(PyErr::fetch(py))
} else {
Py::cast_from_owned_ptr(py, ptr).map_err(|e| e.into())
}
}
/// Cast from ffi::PyObject ptr to a concrete object.
#[inline]
pub unsafe fn cast_from_owned_ptr_or_panic(py: Python<'p>,
ptr: *mut ffi::PyObject) -> Py<'p, T>
{
if ffi::PyObject_TypeCheck(ptr, T::type_object()) != 0 {
Py::from_owned_ptr(py, ptr)
} else {
::err::panic_after_error();
}
}
#[inline]
pub fn as_ref(&self) -> &T {
let offset = <T as PyTypeInfo>::offset();
unsafe {
let ptr = (self.inner as *mut u8).offset(offset) as *mut T;
ptr.as_ref().unwrap()
@ -606,77 +395,11 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
#[inline]
pub fn as_mut(&self) -> &mut T {
let offset = <T as PyTypeInfo>::offset();
unsafe {
let ptr = (self.inner as *mut u8).offset(offset) as *mut T;
ptr.as_mut().unwrap()
}
}
/// Casts the PyObject to a concrete Python object type.
/// Fails with `PyDowncastError` if the object is not of the expected type.
#[inline]
pub fn cast<D>(&self) -> Result<Py<'p, D>, PyDowncastError<'p>>
where D: PyTypeInfo
{
let checked = unsafe { ffi::PyObject_TypeCheck(self.inner, D::type_object()) != 0 };
if checked {
Ok( unsafe { Py::<D>::unchecked_downcast_from(self.clone_ref()) })
} else {
Err(PyDowncastError(self.py, None))
}
}
/// Casts the PyObject to a concrete Python object type.
/// Fails with `PyDowncastError` if the object is not of the expected type.
#[inline]
pub fn cast_into<D>(self) -> Result<Py<'p, D>, PyDowncastError<'p>>
where D: 'p + PyTypeInfo
{
let checked = unsafe { ffi::PyObject_TypeCheck(self.inner, D::type_object()) != 0 };
if checked {
Ok( unsafe { Py::<D>::unchecked_downcast_from(self) })
} else {
Err(PyDowncastError(self.py, None))
}
}
/// Casts the PyObject to a concrete Python object type.
/// Fails with `PyDowncastError` if the object is not of the expected type.
#[inline]
pub fn cast_as<D>(&'p self) -> Result<&'p D, PyDowncastError<'p>>
where D: PyTypeInfo
{
let checked = unsafe { ffi::PyObject_TypeCheck(self.inner, D::type_object()) != 0 };
if checked {
Ok(
unsafe {
let offset = <D as PyTypeInfo>::offset();
let ptr = (self.inner as *mut u8).offset(offset) as *mut D;
ptr.as_ref().unwrap() })
} else {
Err(PyDowncastError(self.py, None))
}
}
/// Unchecked downcast from Py<'p, S> to &'p S.
/// Undefined behavior if the input object does not have the expected type.
#[inline]
pub unsafe fn unchecked_downcast_borrow_from<'a, S>(py: &'a Py<'a, S>) -> &'a T {
let offset = <T as PyTypeInfo>::offset();
let ptr = (py.inner as *mut u8).offset(offset) as *mut T;
ptr.as_ref().unwrap()
}
/// Extracts some type from the Python object.
/// This is a wrapper function around `FromPyObject::extract()`.
#[inline]
pub fn extract<D>(&'p self) -> PyResult<D> where D: ::conversion::FromPyObject<'p>
{
::conversion::FromPyObject::extract(&self.as_pyobject())
}
}
impl<'p, T> PythonObjectWithGilToken<'p> for Py<'p, T> {
@ -757,31 +480,6 @@ impl<'p, T> AsMut<T> for Py<'p, T> where T: PyTypeInfo {
}
}
impl<'source, T> ::FromPyObject<'source> for &'source T
where T: PyTypeInfo + ::PyDowncastFrom<'source>
{
#[inline]
default fn extract(py: &'source PyObject<'source>) -> PyResult<&'source T>
{
Ok(py.cast_as()?)
}
}
impl<'source, T> ::FromPyObject<'source> for Py<'source, T> where T: PyTypeInfo
{
#[inline]
default fn extract(py: &'source PyObject<'source>) -> PyResult<Py<'source, T>>
{
let ptr = py.as_ptr();
let checked = unsafe { ffi::PyObject_TypeCheck(ptr, T::type_object()) != 0 };
if checked {
Ok( unsafe { Py::<T>::from_borrowed_ptr(py.gil(), ptr) })
} else {
Err(PyDowncastError(py.gil(), None).into())
}
}
}
impl <'a, T> ToPyObject for Py<'a, T> {
#[inline]
@ -797,21 +495,6 @@ impl <'a, T> ToPyObject for Py<'a, T> {
}
}
impl<T> ToPyObject for PyPtr<T> {
#[inline]
fn to_object<'p>(&self, py: Python<'p>) -> PyObject<'p> {
PyObject::from_borrowed_ptr(py, self.inner)
}
#[inline]
fn with_borrowed_ptr<F, R>(&self, _py: Python, f: F) -> R
where F: FnOnce(*mut ffi::PyObject) -> R
{
f(self.inner)
}
}
impl<'p, T> IntoPyObject for Py<'p, T> {
#[inline]

View File

@ -12,7 +12,7 @@ use typeob::{PyTypeInfo, PyTypeObject, PyObjectAlloc};
use token::{PythonToken};
use objects::{PyObject, PyType, PyBool, PyDict, PyModule};
use err::{PyErr, PyResult, PyDowncastError};
use pointers::{Py, PyPtr, pptr};
use pointers::{Py, pptr};
use pythonrun::GILGuard;
@ -52,21 +52,6 @@ pub trait PyDowncastInto<'p> : Sized {
}
pub trait PyClone : Sized {
fn clone_ref(&self) -> PyPtr<Self>;
}
impl<T> PyClone for T where T: ToPythonPointer {
#[inline]
fn clone_ref(&self) -> PyPtr<T> {
unsafe {
let ptr = <T as ToPythonPointer>::as_ptr(self);
PyPtr::from_borrowed_ptr(ptr)
}
}
}
/// This trait allows retrieving the underlying FFI pointer from Python objects.
pub trait ToPythonPointer {
/// Retrieves the underlying FFI pointer (as a borrowed pointer).

View File

@ -74,7 +74,7 @@ struct EmptyClassWithNew {token: PythonToken<EmptyClassWithNew> }
impl EmptyClassWithNew {
#[__new__]
fn __new__(cls: &PyType, py: Python) -> PyResult<PyPtr<EmptyClassWithNew>> {
Ok(py.with_token(|t| EmptyClassWithNew{token: t}).into_pptr())
Ok(py.with_token(|t| EmptyClassWithNew{token: t}).park())
}
}
@ -96,7 +96,7 @@ struct NewWithOneArg {
impl NewWithOneArg {
#[new]
fn __new__(_cls: &PyType, py: Python, arg: i32) -> PyResult<PyPtr<NewWithOneArg>> {
Ok(py.with_token(|t| NewWithOneArg{_data: arg, token: t}).into_pptr())
Ok(py.with_token(|t| NewWithOneArg{_data: arg, token: t}).park())
}
}
@ -122,7 +122,7 @@ impl NewWithTwoArgs {
#[new]
fn __new__(_cls: &PyType, py: Python, arg1: i32, arg2: i32)
-> PyResult<PyPtr<NewWithTwoArgs>> {
Ok(py.with_token(|t| NewWithTwoArgs{_data1: arg1, _data2: arg2, token: t}).into_pptr())
Ok(py.with_token(|t| NewWithTwoArgs{_data1: arg1, _data2: arg2, token: t}).park())
}
}
@ -274,7 +274,7 @@ struct StaticMethod {token: PythonToken<StaticMethod>}
impl StaticMethod {
#[new]
fn __new__(cls: &PyType, py: Python) -> PyResult<PyPtr<StaticMethod>> {
Ok(py.with_token(|t| StaticMethod{token: t}).into_pptr())
Ok(py.with_token(|t| StaticMethod{token: t}).park())
}
//#[staticmethod]
@ -343,7 +343,7 @@ fn gc_integration() {
dropped: TestDropCall { drop_called: drop_called.clone() },
token: t});
*inst.self_ref.borrow_mut() = inst.clone_ref().park();
*inst.self_ref.borrow_mut() = inst.clone().park().park();
drop(inst);
py.run("import gc; gc.collect()", None, None).unwrap();