py.init(..) return reference
This commit is contained in:
parent
f0ece6dfde
commit
8238a141ae
|
@ -60,13 +60,23 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
self.#token.py()
|
||||
}
|
||||
}
|
||||
impl _pyo3::ToPyObject for #cls
|
||||
{
|
||||
impl _pyo3::ToPyObject for #cls {
|
||||
#[inline]
|
||||
fn to_object<'p>(&self, py: _pyo3::Python<'p>) -> _pyo3::PyObject {
|
||||
unsafe { _pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
}
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: _pyo3::Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
f(self.as_ptr())
|
||||
}
|
||||
}
|
||||
impl<'a> _pyo3::ToPyObject for &'a mut #cls {
|
||||
#[inline]
|
||||
fn to_object<'p>(&self, py: _pyo3::Python<'p>) -> _pyo3::PyObject {
|
||||
unsafe { _pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_borrowed_ptr<F, R>(&self, _py: _pyo3::Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
|
@ -81,11 +91,24 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
unsafe { _pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
impl<'a> _pyo3::IntoPyObject for &'a mut #cls
|
||||
{
|
||||
#[inline]
|
||||
fn into_object<'p>(self, py: _pyo3::Python) -> _pyo3::PyObject {
|
||||
unsafe { _pyo3::PyObject::from_borrowed_ptr(py, self.as_ptr()) }
|
||||
}
|
||||
}
|
||||
impl std::convert::AsRef<PyInstance> for #cls {
|
||||
fn as_ref(&self) -> &_pyo3::PyInstance {
|
||||
unsafe{std::mem::transmute(self.as_ptr())}
|
||||
}
|
||||
}
|
||||
impl<'a> std::convert::From<&'a mut #cls> for &'a #cls
|
||||
{
|
||||
fn from(ob: &'a mut #cls) -> Self {
|
||||
unsafe{std::mem::transmute(ob)}
|
||||
}
|
||||
}
|
||||
impl _pyo3::ToPyPointer for #cls {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
|
@ -95,7 +118,6 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for #cls {
|
||||
fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
use pyo3::ObjectProtocol;
|
||||
|
|
|
@ -10,7 +10,7 @@ use pointer::PyObject;
|
|||
use objects::PyInstance;
|
||||
use objectprotocol::ObjectProtocol;
|
||||
use conversion::{ToPyObject, IntoPyObject, FromPyObject};
|
||||
use python::{Python, IntoPyPointer, ToPyPointer, PyDowncastInto};
|
||||
use python::{Python, IntoPyPointer, ToPyPointer, PyDowncastInto, PyDowncastFrom};
|
||||
use typeob::{PyTypeInfo, PyObjectAlloc};
|
||||
|
||||
|
||||
|
@ -161,8 +161,37 @@ impl<T> Py<T> {
|
|||
|
||||
impl<T> Py<T> where T: PyTypeInfo,
|
||||
{
|
||||
/// Create new python object and move T instance under python management
|
||||
pub fn new<F>(py: Python, f: F) -> PyResult<Py<T>>
|
||||
/// Create new instance of `T` and move under python management.
|
||||
/// Returns references to `T`
|
||||
pub fn new<'p, F>(py: Python<'p>, f: F) -> PyResult<&'p T>
|
||||
where F: FnOnce(::PyToken) -> T,
|
||||
T: PyObjectAlloc<T> + PyDowncastFrom
|
||||
{
|
||||
let ob = f(PyToken(PhantomData));
|
||||
|
||||
unsafe {
|
||||
let ob = try!(<T as PyObjectAlloc<T>>::alloc(py, ob));
|
||||
Ok(py.cast_from_ptr(ob))
|
||||
}
|
||||
}
|
||||
|
||||
/// Create new instance of `T` and move under python management.
|
||||
/// Returns mutable references to `T`
|
||||
pub fn new_mut<'p, F>(py: Python<'p>, f: F) -> PyResult<&'p mut T>
|
||||
where F: FnOnce(::PyToken) -> T,
|
||||
T: PyObjectAlloc<T> + PyDowncastFrom
|
||||
{
|
||||
let ob = f(PyToken(PhantomData));
|
||||
|
||||
unsafe {
|
||||
let ob = try!(<T as PyObjectAlloc<T>>::alloc(py, ob));
|
||||
Ok(py.mut_cast_from_ptr(ob))
|
||||
}
|
||||
}
|
||||
|
||||
/// Create new instance of T and move under python management
|
||||
/// Returns `Py<T>`.
|
||||
pub fn new_ptr<F>(py: Python, f: F) -> PyResult<Py<T>>
|
||||
where F: FnOnce(::PyToken) -> T,
|
||||
T: PyObjectAlloc<T>
|
||||
{
|
||||
|
|
114
src/python.rs
114
src/python.rs
|
@ -206,6 +206,19 @@ impl<'p> Python<'p> {
|
|||
PyModule::import(self, name)
|
||||
}
|
||||
|
||||
/// Check whether `obj` is an instance of type `T` like Python `isinstance` function
|
||||
pub fn is_instance<T: PyTypeObject, V: ToPyPointer>(self, obj: &V) -> PyResult<bool> {
|
||||
T::type_object(self).is_instance(obj)
|
||||
}
|
||||
|
||||
/// Check whether type `T` is subclass of type `U` like Python `issubclass` function
|
||||
pub fn is_subclass<T, U>(self) -> PyResult<bool>
|
||||
where T: PyTypeObject,
|
||||
U: PyTypeObject
|
||||
{
|
||||
T::type_object(self).is_subclass::<U>()
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `None`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
|
@ -219,78 +232,99 @@ impl<'p> Python<'p> {
|
|||
pub fn NotImplemented(self) -> PyObject {
|
||||
unsafe { PyObject::from_borrowed_ptr(self, ffi::Py_NotImplemented()) }
|
||||
}
|
||||
}
|
||||
|
||||
/// Create new python object and move T instance under python management
|
||||
impl<'p> Python<'p> {
|
||||
|
||||
/// Create new instance of T and move under python management.
|
||||
/// Created object get registered in release pool. Returns references to `T`
|
||||
#[inline]
|
||||
pub fn init<T, F>(self, f: F) -> PyResult<Py<T>>
|
||||
pub fn init<T, F>(self, f: F) -> PyResult<&'p T>
|
||||
where F: FnOnce(PyToken) -> T,
|
||||
T: PyTypeInfo + PyObjectAlloc<T>
|
||||
T: PyTypeInfo + PyObjectAlloc<T> + PyDowncastFrom
|
||||
{
|
||||
Py::new(self, f)
|
||||
}
|
||||
|
||||
/// Check whether `obj` is an instance of type `T` like Python `isinstance` function
|
||||
pub fn is_instance<T: PyTypeObject, V: ToPyPointer>(self, obj: &V) -> PyResult<bool> {
|
||||
T::type_object(self).is_instance(obj)
|
||||
/// Create new instance of T and move under python management.
|
||||
/// Created object get registered in release pool. Returns mutable references to `T`
|
||||
#[inline]
|
||||
pub fn init_mut<T, F>(self, f: F) -> PyResult<&'p mut T>
|
||||
where F: FnOnce(PyToken) -> T,
|
||||
T: PyTypeInfo + PyObjectAlloc<T> + PyDowncastFrom
|
||||
{
|
||||
Py::new_mut(self, f)
|
||||
}
|
||||
|
||||
/// Check whether type `T` is subclass of type `U` like Python `issubclass` function
|
||||
pub fn is_subclass<T, U>(self) -> PyResult<bool>
|
||||
where T: PyTypeObject,
|
||||
U: PyTypeObject
|
||||
/// Create new instance of T and move under python management.
|
||||
/// Returns `Py<T>`.
|
||||
#[inline]
|
||||
pub fn init_ptr<T, F>(self, f: F) -> PyResult<Py<T>>
|
||||
where F: FnOnce(PyToken) -> T,
|
||||
T: PyTypeInfo + PyObjectAlloc<T>
|
||||
{
|
||||
T::type_object(self).is_subclass::<U>()
|
||||
Py::new_ptr(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> Python<'p> {
|
||||
|
||||
/// Register object in release pool, and try to downcast to specific Python object.
|
||||
pub fn checked_cast_as<D>(self, obj: PyObject) -> Result<&'p D, PyDowncastError<'p>>
|
||||
where D: PyDowncastFrom
|
||||
pub fn checked_cast_as<T>(self, obj: PyObject) -> Result<&'p T, PyDowncastError<'p>>
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
unsafe {
|
||||
let p = pythonrun::register_owned(self, obj);
|
||||
<D as PyDowncastFrom>::downcast_from(p)
|
||||
<T as PyDowncastFrom>::downcast_from(p)
|
||||
}
|
||||
}
|
||||
|
||||
/// Register object in release pool, and do unchecked downcast to specific Python object.
|
||||
pub unsafe fn cast_as<D>(self, obj: PyObject) -> &'p D
|
||||
where D: PyDowncastFrom
|
||||
pub unsafe fn cast_as<T>(self, obj: PyObject) -> &'p T
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
let p = pythonrun::register_owned(self, obj);
|
||||
<D as PyDowncastFrom>::unchecked_downcast_from(p)
|
||||
<T as PyDowncastFrom>::unchecked_downcast_from(p)
|
||||
}
|
||||
|
||||
/// Register `ffi::PyObject` pointer in release pool,
|
||||
/// and do unchecked downcast to specific Python object.
|
||||
pub unsafe fn cast_from_ptr<D>(self, ptr: *mut ffi::PyObject) -> &'p D
|
||||
where D: PyDowncastFrom
|
||||
pub unsafe fn cast_from_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
let obj = PyObject::from_owned_ptr_or_panic(self, ptr);
|
||||
let p = pythonrun::register_owned(self, obj);
|
||||
<D as PyDowncastFrom>::unchecked_downcast_from(p)
|
||||
<T as PyDowncastFrom>::unchecked_downcast_from(p)
|
||||
}
|
||||
|
||||
/// Register `ffi::PyObject` pointer in release pool,
|
||||
/// Do unchecked downcast to specific Python object. Returns mutable reference.
|
||||
pub unsafe fn mut_cast_from_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p mut T
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
let obj = PyObject::from_owned_ptr_or_panic(self, ptr);
|
||||
let p = pythonrun::register_owned(self, obj);
|
||||
<T as PyDowncastFrom>::unchecked_mut_downcast_from(p)
|
||||
}
|
||||
|
||||
/// Register owned `ffi::PyObject` pointer in release pool.
|
||||
/// Returns `Err(PyErr)` if the pointer is `null`.
|
||||
/// do unchecked downcast to specific Python object.
|
||||
pub fn cast_from_ptr_or_err<D>(self, ptr: *mut ffi::PyObject) -> PyResult<&'p D>
|
||||
where D: PyDowncastFrom
|
||||
pub fn cast_from_ptr_or_err<T>(self, ptr: *mut ffi::PyObject) -> PyResult<&'p T>
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
let obj = PyObject::from_owned_ptr_or_err(self, ptr)?;
|
||||
unsafe {
|
||||
let p = pythonrun::register_owned(self, obj);
|
||||
Ok(<D as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
Ok(<T as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Register owned `ffi::PyObject` pointer in release pool.
|
||||
/// Returns `None` if the pointer is `null`.
|
||||
/// do unchecked downcast to specific Python object.
|
||||
pub fn cast_from_ptr_or_opt<D>(self, ptr: *mut ffi::PyObject) -> Option<&'p D>
|
||||
where D: PyDowncastFrom
|
||||
pub fn cast_from_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject) -> Option<&'p T>
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
if ptr.is_null() {
|
||||
None
|
||||
|
@ -298,7 +332,7 @@ impl<'p> Python<'p> {
|
|||
unsafe {
|
||||
let obj = PyObject::from_owned_ptr(self, ptr);
|
||||
let p = pythonrun::register_owned(self, obj);
|
||||
Some(<D as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
Some(<T as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -306,51 +340,51 @@ impl<'p> Python<'p> {
|
|||
/// Register borrowed `ffi::PyObject` pointer in release pool.
|
||||
/// Panics if the pointer is `null`.
|
||||
/// do unchecked downcast to specific Python object.
|
||||
pub unsafe fn cast_from_borrowed_ptr<D>(self, ptr: *mut ffi::PyObject) -> &'p D
|
||||
where D: PyDowncastFrom
|
||||
pub unsafe fn cast_from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p T
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
let obj = PyObject::from_borrowed_ptr(self, ptr);
|
||||
let p = pythonrun::register_borrowed(self, obj);
|
||||
<D as PyDowncastFrom>::unchecked_downcast_from(p)
|
||||
<T as PyDowncastFrom>::unchecked_downcast_from(p)
|
||||
}
|
||||
|
||||
/// Register borrowed `ffi::PyObject` pointer in release pool.
|
||||
/// Returns `Err(PyErr)` if the pointer is `null`.
|
||||
/// do unchecked downcast to specific Python object.
|
||||
pub unsafe fn cast_from_borrowed_ptr_or_err<D>(self, ptr: *mut ffi::PyObject)
|
||||
-> PyResult<&'p D>
|
||||
where D: PyDowncastFrom
|
||||
pub unsafe fn cast_from_borrowed_ptr_or_err<T>(self, ptr: *mut ffi::PyObject)
|
||||
-> PyResult<&'p T>
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
let obj = PyObject::from_borrowed_ptr_or_err(self, ptr)?;
|
||||
let p = pythonrun::register_borrowed(self, obj);
|
||||
Ok(<D as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
Ok(<T as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
}
|
||||
|
||||
/// Register borrowed `ffi::PyObject` pointer in release pool.
|
||||
/// Returns `None` if the pointer is `null`.
|
||||
/// do unchecked downcast to specific Python object.
|
||||
pub unsafe fn cast_from_borrowed_ptr_or_opt<D>(self, ptr: *mut ffi::PyObject)
|
||||
-> Option<&'p D>
|
||||
where D: PyDowncastFrom
|
||||
pub unsafe fn cast_from_borrowed_ptr_or_opt<T>(self, ptr: *mut ffi::PyObject)
|
||||
-> Option<&'p T>
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
if ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
let obj = PyObject::from_borrowed_ptr(self, ptr);
|
||||
let p = pythonrun::register_borrowed(self, obj);
|
||||
Some(<D as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
Some(<T as PyDowncastFrom>::unchecked_downcast_from(p))
|
||||
}
|
||||
}
|
||||
|
||||
/// Register borrowed `ffi::PyObject` pointer in release pool.
|
||||
/// Panics if the pointer is `null`.
|
||||
/// do unchecked downcast to specific Python object, returns mutable reference.
|
||||
pub unsafe fn mut_cast_from_borrowed_ptr<D>(self, ptr: *mut ffi::PyObject) -> &'p mut D
|
||||
where D: PyDowncastFrom
|
||||
pub unsafe fn mut_cast_from_borrowed_ptr<T>(self, ptr: *mut ffi::PyObject) -> &'p mut T
|
||||
where T: PyDowncastFrom
|
||||
{
|
||||
let obj = PyObject::from_borrowed_ptr(self, ptr);
|
||||
let p = pythonrun::register_borrowed(self, obj);
|
||||
<D as PyDowncastFrom>::unchecked_mut_downcast_from(p)
|
||||
<T as PyDowncastFrom>::unchecked_mut_downcast_from(p)
|
||||
}
|
||||
|
||||
pub fn track_object(self, obj: PyObject) -> &'p PyInstance
|
||||
|
|
|
@ -106,7 +106,7 @@ struct EmptyClassWithNew {
|
|||
impl EmptyClassWithNew {
|
||||
#[__new__]
|
||||
fn __new__(cls: &PyType) -> PyResult<Py<EmptyClassWithNew>> {
|
||||
Py::new(cls.token(), |t| EmptyClassWithNew{token: t})
|
||||
Ok(Py::new(cls.token(), |t| EmptyClassWithNew{token: t})?.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,8 +127,8 @@ struct NewWithOneArg {
|
|||
#[py::methods]
|
||||
impl NewWithOneArg {
|
||||
#[new]
|
||||
fn __new__(cls: &PyType, arg: i32) -> PyResult<Py<NewWithOneArg>> {
|
||||
Py::new(cls.token(), |t| NewWithOneArg{_data: arg, token: t})
|
||||
fn __new__(cls: &PyType, arg: i32) -> PyResult<&mut NewWithOneArg> {
|
||||
cls.token().init_mut(|t| NewWithOneArg{_data: arg, token: t})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,9 @@ impl NewWithTwoArgs {
|
|||
#[new]
|
||||
fn __new__(cls: &PyType, arg1: i32, arg2: i32) -> PyResult<Py<NewWithTwoArgs>>
|
||||
{
|
||||
Py::new(cls.token(), |t| NewWithTwoArgs{_data1: arg1, _data2: arg2, token: t})
|
||||
Py::new_ptr(
|
||||
cls.token(),
|
||||
|t| NewWithTwoArgs{_data1: arg1, _data2: arg2, token: t})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,12 +180,12 @@ fn class_with_freelist() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst2 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst = Py::new_ptr(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst2 = Py::new_ptr(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let ptr = inst.as_ptr();
|
||||
drop(inst);
|
||||
|
||||
let inst3 = Py::new(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
let inst3 = Py::new_ptr(py, |t| ClassWithFreelist{token: t}).unwrap();
|
||||
assert_eq!(ptr, inst3.as_ptr());
|
||||
}
|
||||
|
||||
|
@ -210,7 +212,7 @@ fn data_is_dropped() {
|
|||
|
||||
let drop_called1 = Arc::new(AtomicBool::new(false));
|
||||
let drop_called2 = Arc::new(AtomicBool::new(false));
|
||||
let inst = Py::new(py, |t| DataIsDropped{
|
||||
let inst = py.init_ptr(|t| DataIsDropped{
|
||||
member1: TestDropCall { drop_called: drop_called1.clone() },
|
||||
member2: TestDropCall { drop_called: drop_called2.clone() },
|
||||
token: t
|
||||
|
@ -243,7 +245,7 @@ fn instance_method() {
|
|||
let py = gil.python();
|
||||
|
||||
let obj = Py::new(py, |t| InstanceMethod{member: 42, token: t}).unwrap();
|
||||
assert!(obj.as_ref(py).method().unwrap() == 42);
|
||||
assert!(obj.method().unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("obj", obj).unwrap();
|
||||
py.run("assert obj.method() == 42", None, Some(d)).unwrap();
|
||||
|
@ -269,7 +271,7 @@ fn instance_method_with_args() {
|
|||
let py = gil.python();
|
||||
|
||||
let obj = Py::new(py, |t| InstanceMethodWithArgs{member: 7, token: t}).unwrap();
|
||||
assert!(obj.as_ref(py).method(6).unwrap() == 42);
|
||||
assert!(obj.method(6).unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("obj", obj).unwrap();
|
||||
py.run("assert obj.method(3) == 21", None, Some(d)).unwrap();
|
||||
|
@ -284,7 +286,7 @@ struct ClassMethod {token: PyToken}
|
|||
impl ClassMethod {
|
||||
#[new]
|
||||
fn __new__(cls: &PyType) -> PyResult<Py<ClassMethod>> {
|
||||
Py::new(cls.token(), |t| ClassMethod{token: t})
|
||||
Py::new_ptr(cls.token(), |t| ClassMethod{token: t})
|
||||
}
|
||||
|
||||
#[classmethod]
|
||||
|
@ -334,8 +336,8 @@ struct StaticMethod {
|
|||
#[py::methods]
|
||||
impl StaticMethod {
|
||||
#[new]
|
||||
fn __new__(cls: &PyType) -> PyResult<Py<StaticMethod>> {
|
||||
Py::new(cls.token(), |t| StaticMethod{token: t})
|
||||
fn __new__(cls: &PyType) -> PyResult<&StaticMethod> {
|
||||
Ok(cls.token().init_mut(|t| StaticMethod{token: t})?.into())
|
||||
}
|
||||
|
||||
#[staticmethod]
|
||||
|
@ -400,18 +402,22 @@ impl PyGCProtocol for GCIntegration {
|
|||
|
||||
#[test]
|
||||
fn gc_integration() {
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
|
||||
{
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let inst = Py::new(py, |t| GCIntegration{
|
||||
self_ref: RefCell::new(py.None().into()),
|
||||
dropped: TestDropCall { drop_called: drop_called.clone() },
|
||||
token: t}).unwrap();
|
||||
|
||||
*inst.self_ref.borrow_mut() = inst.into();
|
||||
drop(inst);
|
||||
}
|
||||
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
let inst = Py::new(py, |t| GCIntegration{
|
||||
self_ref: RefCell::new(py.None().into()),
|
||||
dropped: TestDropCall { drop_called: drop_called.clone() },
|
||||
token: t}).unwrap();
|
||||
|
||||
*inst.as_mut(py).self_ref.borrow_mut() = inst.clone_ref(py).into();
|
||||
drop(inst);
|
||||
|
||||
py.run("import gc; gc.collect()", None, None).unwrap();
|
||||
assert!(drop_called.load(Ordering::Relaxed));
|
||||
}
|
||||
|
@ -638,8 +644,8 @@ fn setitem() {
|
|||
|
||||
let c = py.init(|t| SetItem{key: 0, val: 0, token: t}).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
assert_eq!(c.as_ref(py).key, 1);
|
||||
assert_eq!(c.as_ref(py).val, 2);
|
||||
assert_eq!(c.key, 1);
|
||||
assert_eq!(c.val, 2);
|
||||
py_expect_exception!(py, c, "del c[1]", NotImplementedError);
|
||||
}
|
||||
|
||||
|
@ -664,7 +670,7 @@ fn delitem() {
|
|||
|
||||
let c = py.init(|t| DelItem{key:0, token:t}).unwrap();
|
||||
py_run!(py, c, "del c[1]");
|
||||
assert_eq!(c.as_ref(py).key, 1);
|
||||
assert_eq!(c.key, 1);
|
||||
py_expect_exception!(py, c, "c[1] = 2", NotImplementedError);
|
||||
}
|
||||
|
||||
|
@ -694,9 +700,9 @@ fn setdelitem() {
|
|||
|
||||
let c = py.init(|t| SetDelItem{val: None, token: t}).unwrap();
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
assert_eq!(c.as_ref(py).val, Some(2));
|
||||
assert_eq!(c.val, Some(2));
|
||||
py_run!(py, c, "del c[1]");
|
||||
assert_eq!(c.as_ref(py).val, None);
|
||||
assert_eq!(c.val, None);
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
|
@ -1064,19 +1070,18 @@ fn context_manager() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(|t| ContextManager{exit_called: false, token: t}).unwrap();
|
||||
let mut c = py.init_mut(|t| ContextManager{exit_called: false, token: t}).unwrap();
|
||||
py_run!(py, c, "with c as x:\n assert x == 42");
|
||||
assert!(c.as_ref(py).exit_called);
|
||||
assert!(c.exit_called);
|
||||
|
||||
c.as_mut(py).exit_called = false;
|
||||
c.exit_called = false;
|
||||
py_run!(py, c, "with c as x:\n raise ValueError");
|
||||
assert!(c.as_ref(py).exit_called);
|
||||
assert!(c.exit_called);
|
||||
|
||||
c.as_mut(py).exit_called = false;
|
||||
c.exit_called = false;
|
||||
py_expect_exception!(
|
||||
py, c, "with c as x:\n raise NotImplementedError",
|
||||
NotImplementedError);
|
||||
assert!(c.as_ref(py).exit_called);
|
||||
py, c, "with c as x:\n raise NotImplementedError", NotImplementedError);
|
||||
assert!(c.exit_called);
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
|
|
Loading…
Reference in New Issue