update tests
This commit is contained in:
parent
6205be98b8
commit
bfb01f65d3
|
@ -79,5 +79,31 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for #cls {
|
||||
fn fmt(&self, f : &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
unsafe {
|
||||
let py = _pyo3::Python::assume_gil_acquired();
|
||||
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||
let repr = try!(_pyo3::Py::<_pyo3::PyString>::cast_from_owned_nullptr(
|
||||
py, _pyo3::ffi::PyObject_Repr(ptr)).map_err(|_| std::fmt::Error));
|
||||
|
||||
f.write_str(&repr.to_string_lossy())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for #cls {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
|
||||
unsafe {
|
||||
let py = _pyo3::Python::assume_gil_acquired();
|
||||
let ptr = <#cls as _pyo3::python::ToPythonPointer>::as_ptr(self);
|
||||
let s = try!(_pyo3::Py::<_pyo3::PyString>::cast_from_owned_nullptr(
|
||||
py, _pyo3::ffi::PyObject_Str(ptr)).map_err(|_| std::fmt::Error));
|
||||
|
||||
f.write_str(&s.to_string_lossy())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
src/pyptr.rs
18
src/pyptr.rs
|
@ -2,7 +2,7 @@
|
|||
|
||||
use std;
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Deref;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::convert::{AsRef, AsMut};
|
||||
|
||||
use ffi;
|
||||
|
@ -82,6 +82,15 @@ impl<T> IntoPythonPointer for PyPtr<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoPyObject for PyPtr<T> {
|
||||
|
||||
#[inline]
|
||||
fn into_object<'a>(self, py: Python<'a>) -> Py<'a, PyObject> {
|
||||
self.into_ref(py).into_object()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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> {}
|
||||
|
@ -427,6 +436,13 @@ impl<'p, T> Deref for Py<'p, T> where T: PyTypeInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p, T> DerefMut for Py<'p, T> where T: PyTypeInfo {
|
||||
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
self.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p, T> AsRef<T> for Py<'p, T> where T: PyTypeInfo {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &T {
|
||||
|
|
|
@ -222,14 +222,14 @@ impl<T> PythonToken<T> {
|
|||
/// Gets the Python builtin value `None`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn None(self) -> PyPtr<PyObject> {
|
||||
pub fn None(&self) -> PyPtr<PyObject> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_None()) }
|
||||
}
|
||||
|
||||
/// Gets the Python builtin value `True`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn True(self) -> PyPtr<PyBool> {
|
||||
pub fn True(&self) -> PyPtr<PyBool> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_True()) }
|
||||
}
|
||||
|
||||
|
@ -243,24 +243,24 @@ impl<T> PythonToken<T> {
|
|||
/// Gets the Python builtin value `NotImplemented`.
|
||||
#[allow(non_snake_case)] // the Python keyword starts with uppercase
|
||||
#[inline]
|
||||
pub fn NotImplemented(self) -> PyPtr<PyObject> {
|
||||
pub fn NotImplemented(&self) -> PyPtr<PyObject> {
|
||||
unsafe { PyPtr::from_borrowed_ptr(ffi::Py_NotImplemented()) }
|
||||
}
|
||||
|
||||
/// Gets the Python type object for type T.
|
||||
pub fn get_type<U>(self) -> PyPtr<PyType> where U: PyTypeObject {
|
||||
pub fn get_type<U>(&self) -> PyPtr<PyType> where U: PyTypeObject {
|
||||
U::type_object(Python(PhantomData)).into_pptr()
|
||||
}
|
||||
|
||||
/// Execute closure `F` with Python instance.
|
||||
/// Retrieve Python instance under the assumption that the GIL is already acquired
|
||||
/// at this point, and stays acquired during closure call.
|
||||
pub fn with_py<'p, F>(self, f: F) where F: FnOnce(Python<'p>)
|
||||
pub fn with<'p, F>(&self, f: F) where F: FnOnce(Python<'p>)
|
||||
{
|
||||
f(Python(PhantomData))
|
||||
}
|
||||
|
||||
pub fn with_token<P, F>(self, f: F) -> PyPtr<P>
|
||||
pub fn with_token<P, F>(&self, f: F) -> PyPtr<P>
|
||||
where F: FnOnce(PythonToken<P>) -> P,
|
||||
P: PyTypeInfo + PyObjectAlloc<Type=P>
|
||||
{
|
||||
|
|
|
@ -109,6 +109,8 @@ impl<T> PyObjectAlloc for T where T : PyTypeInfo {
|
|||
/// `ty` must be derived from the Self type, and the resulting object
|
||||
/// must be of type `ty`.
|
||||
unsafe fn alloc(_py: Python, value: T::Type) -> PyResult<*mut ffi::PyObject> {
|
||||
let _ = <T as PyTypeObject>::type_object(_py);
|
||||
|
||||
let obj = ffi::PyType_GenericAlloc(
|
||||
<Self as PyTypeInfo>::type_object(), 0);
|
||||
|
||||
|
@ -329,24 +331,24 @@ fn py_class_method_defs<T>() -> (Option<ffi::newfunc>,
|
|||
}
|
||||
}
|
||||
|
||||
//for def in <T as class::basic::PyObjectProtocolImpl>::methods() {
|
||||
// defs.push(def.as_method_def())
|
||||
//}
|
||||
//for def in <T as class::async::PyAsyncProtocolImpl>::methods() {
|
||||
// defs.push(def.as_method_def())
|
||||
//}
|
||||
//for def in <T as class::context::PyContextProtocolImpl>::methods() {
|
||||
// defs.push(def.as_method_def())
|
||||
//}
|
||||
//for def in <T as class::mapping::PyMappingProtocolImpl>::methods() {
|
||||
//defs.push(def.as_method_def())
|
||||
//}
|
||||
//for def in <T as class::number::PyNumberProtocolImpl>::methods() {
|
||||
// defs.push(def.as_method_def())
|
||||
//}
|
||||
//for def in <T as class::descr::PyDescrProtocolImpl>::methods() {
|
||||
// defs.push(def.as_method_def())
|
||||
//}
|
||||
for def in <T as class::basic::PyObjectProtocolImpl>::methods() {
|
||||
defs.push(def.as_method_def())
|
||||
}
|
||||
for def in <T as class::async::PyAsyncProtocolImpl>::methods() {
|
||||
defs.push(def.as_method_def())
|
||||
}
|
||||
for def in <T as class::context::PyContextProtocolImpl>::methods() {
|
||||
defs.push(def.as_method_def())
|
||||
}
|
||||
for def in <T as class::mapping::PyMappingProtocolImpl>::methods() {
|
||||
defs.push(def.as_method_def())
|
||||
}
|
||||
for def in <T as class::number::PyNumberProtocolImpl>::methods() {
|
||||
defs.push(def.as_method_def())
|
||||
}
|
||||
for def in <T as class::descr::PyDescrProtocolImpl>::methods() {
|
||||
defs.push(def.as_method_def())
|
||||
}
|
||||
|
||||
(new, call, defs)
|
||||
}
|
||||
|
|
|
@ -68,13 +68,13 @@ fn empty_class_in_module() {
|
|||
}
|
||||
|
||||
#[py::class]
|
||||
struct EmptyClassWithNew { }
|
||||
struct EmptyClassWithNew {token: PythonToken<EmptyClassWithNew> }
|
||||
|
||||
#[py::methods]
|
||||
impl EmptyClassWithNew {
|
||||
#[__new__]
|
||||
fn __new__(cls: &PyType, py: Python) -> PyResult<EmptyClassWithNew> {
|
||||
Ok(EmptyClassWithNew{})
|
||||
fn __new__(cls: &PyType, py: Python) -> PyResult<PyPtr<EmptyClassWithNew>> {
|
||||
Ok(py.with_token(|t| EmptyClassWithNew{token: t}).into_pptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,12 +89,13 @@ fn empty_class_with_new() {
|
|||
#[py::class]
|
||||
struct NewWithOneArg {
|
||||
_data: i32,
|
||||
token: PythonToken<NewWithOneArg>
|
||||
}
|
||||
#[py::methods]
|
||||
impl NewWithOneArg {
|
||||
#[new]
|
||||
fn __new__(_cls: &PyType, py: Python, arg: i32) -> PyResult<NewWithOneArg> {
|
||||
Ok(NewWithOneArg{_data: arg})
|
||||
fn __new__(_cls: &PyType, py: Python, arg: i32) -> PyResult<PyPtr<NewWithOneArg>> {
|
||||
Ok(py.with_token(|t| NewWithOneArg{_data: arg, token: t}).into_pptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,13 +112,15 @@ fn new_with_one_arg() {
|
|||
struct NewWithTwoArgs {
|
||||
_data1: i32,
|
||||
_data2: i32,
|
||||
token: PythonToken<NewWithTwoArgs>
|
||||
}
|
||||
|
||||
#[py::methods]
|
||||
impl NewWithTwoArgs {
|
||||
#[new]
|
||||
fn __new__(_cls: &PyType, py: Python, arg1: i32, arg2: i32) -> PyResult<NewWithTwoArgs> {
|
||||
Ok(NewWithTwoArgs{_data1: arg1, _data2: arg2})
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,6 +147,7 @@ impl Drop for TestDropCall {
|
|||
struct DataIsDropped {
|
||||
member1: TestDropCall,
|
||||
member2: TestDropCall,
|
||||
token: PythonToken<DataIsDropped>,
|
||||
}
|
||||
|
||||
//#[test]
|
||||
|
@ -153,9 +157,11 @@ fn data_is_dropped() {
|
|||
|
||||
let drop_called1 = Arc::new(AtomicBool::new(false));
|
||||
let drop_called2 = Arc::new(AtomicBool::new(false));
|
||||
let inst = DataIsDropped{
|
||||
let inst = py.with_token(|t| DataIsDropped{
|
||||
member1: TestDropCall { drop_called: drop_called1.clone() },
|
||||
member2: TestDropCall { drop_called: drop_called2.clone() }}.into_object(py);
|
||||
member2: TestDropCall { drop_called: drop_called2.clone() },
|
||||
token: t
|
||||
});
|
||||
assert!(drop_called1.load(Ordering::Relaxed) == false);
|
||||
assert!(drop_called2.load(Ordering::Relaxed) == false);
|
||||
drop(inst);
|
||||
|
@ -167,6 +173,7 @@ fn data_is_dropped() {
|
|||
#[py::class]
|
||||
struct InstanceMethod {
|
||||
member: i32,
|
||||
token: PythonToken<InstanceMethod>
|
||||
}
|
||||
|
||||
#[py::methods]
|
||||
|
@ -181,7 +188,7 @@ fn instance_method() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let obj = py.init(InstanceMethod{member: 42});
|
||||
let obj = py.with_token(|t| InstanceMethod{member: 42, token: t});
|
||||
assert!(obj.method(py).unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("obj", obj).unwrap();
|
||||
|
@ -190,7 +197,8 @@ fn instance_method() {
|
|||
|
||||
#[py::class]
|
||||
struct InstanceMethodWithArgs {
|
||||
member: i32
|
||||
member: i32,
|
||||
token: PythonToken<InstanceMethodWithArgs>
|
||||
}
|
||||
#[py::methods]
|
||||
impl InstanceMethodWithArgs {
|
||||
|
@ -204,7 +212,7 @@ fn instance_method_with_args() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let obj = py.init(InstanceMethodWithArgs{member: 7});
|
||||
let obj = py.with_token(|t| InstanceMethodWithArgs{member: 7, token: t});
|
||||
assert!(obj.method(py, 6).unwrap() == 42);
|
||||
let d = PyDict::new(py);
|
||||
d.set_item("obj", obj).unwrap();
|
||||
|
@ -257,13 +265,13 @@ fn class_method() {
|
|||
}*/
|
||||
|
||||
#[py::class]
|
||||
struct StaticMethod {}
|
||||
struct StaticMethod {token: PythonToken<StaticMethod>}
|
||||
|
||||
#[py::methods]
|
||||
impl StaticMethod {
|
||||
#[new]
|
||||
fn __new__(cls: &PyType, py: Python) -> PyResult<StaticMethod> {
|
||||
Ok(StaticMethod{}.into_object(py))
|
||||
fn __new__(cls: &PyType, py: Python) -> PyResult<PyPtr<StaticMethod>> {
|
||||
Ok(py.with_token(|t| StaticMethod{token: t}).into_pptr())
|
||||
}
|
||||
|
||||
//#[staticmethod]
|
||||
|
@ -307,6 +315,7 @@ impl StaticMethod {
|
|||
struct GCIntegration {
|
||||
self_ref: RefCell<PyPtr<PyObject>>,
|
||||
dropped: TestDropCall,
|
||||
token: PythonToken<GCIntegration>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
|
@ -316,9 +325,7 @@ impl PyGCProtocol for GCIntegration {
|
|||
}
|
||||
|
||||
fn __clear__(&mut self, py: Python) {
|
||||
let old_ref = mem::replace(&mut *self.self_ref.borrow_mut(), py.None());
|
||||
// Release reference only after the mutable borrow has expired.
|
||||
old_ref.release_ref(py);
|
||||
*self.self_ref.borrow_mut() = self.token.None();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,9 +335,10 @@ fn gc_integration() {
|
|||
let py = gil.python();
|
||||
|
||||
let drop_called = Arc::new(AtomicBool::new(false));
|
||||
let inst = py.init(GCIntegration{
|
||||
self_ref: RefCell::new(py.None()),
|
||||
dropped: TestDropCall { drop_called: drop_called.clone() }});
|
||||
let mut inst = py.with_token(|t| GCIntegration{
|
||||
self_ref: RefCell::new(t.None()),
|
||||
dropped: TestDropCall { drop_called: drop_called.clone() },
|
||||
token: t});
|
||||
|
||||
*inst.self_ref.borrow_mut() = inst.clone_ref().into_object().into_pptr();
|
||||
drop(inst);
|
||||
|
@ -341,7 +349,8 @@ fn gc_integration() {
|
|||
|
||||
#[py::class]
|
||||
pub struct Len {
|
||||
l: usize
|
||||
l: usize,
|
||||
token: PythonToken<Len>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
|
@ -356,14 +365,14 @@ fn len() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = Len{l: 10}.into_object(py);
|
||||
let inst = py.with_token(|t| Len{l: 10, token: t});
|
||||
py_assert!(py, inst, "len(inst) == 10");
|
||||
unsafe {
|
||||
assert_eq!(ffi::PyObject_Size(inst.as_ptr()), 10);
|
||||
assert_eq!(ffi::PyMapping_Size(inst.as_ptr()), 10);
|
||||
}
|
||||
|
||||
let inst = Len{l: (isize::MAX as usize) + 1}.into_object(py);
|
||||
let inst = py.with_token(|t| Len{l: (isize::MAX as usize) + 1, token: t});
|
||||
py_expect_exception!(py, inst, "len(inst)", OverflowError);
|
||||
}
|
||||
|
||||
|
@ -390,7 +399,7 @@ fn iterator() {
|
|||
}*/
|
||||
|
||||
#[py::class]
|
||||
struct StringMethods {}
|
||||
struct StringMethods {token: PythonToken<StringMethods>}
|
||||
|
||||
#[py::proto]
|
||||
impl<'p> PyObjectProtocol<'p> for StringMethods {
|
||||
|
@ -420,7 +429,7 @@ fn string_methods() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let obj = StringMethods{}.into_object(py);
|
||||
let obj = py.with_token(|t| StringMethods{token: t});
|
||||
py_assert!(py, obj, "str(obj) == 'str'");
|
||||
py_assert!(py, obj, "repr(obj) == 'repr'");
|
||||
py_assert!(py, obj, "'{0:x}'.format(obj) == 'format(x)'");
|
||||
|
@ -431,6 +440,7 @@ fn string_methods() {
|
|||
#[py::class]
|
||||
struct Comparisons {
|
||||
val: i32,
|
||||
token: PythonToken<Comparisons>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
|
@ -450,10 +460,10 @@ fn comparisons() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let zero = Comparisons{val: 0}.into_object(py);
|
||||
let one = Comparisons{val: 1}.into_object(py);
|
||||
let ten = Comparisons{val: 10}.into_object(py);
|
||||
let minus_one = Comparisons{val: -1}.into_object(py);
|
||||
let zero = py.with_token(|t| Comparisons{val: 0, token: t});
|
||||
let one = py.with_token(|t| Comparisons{val: 1, token: t});
|
||||
let ten = py.with_token(|t| Comparisons{val: 10, token: t});
|
||||
let minus_one = py.with_token(|t| Comparisons{val: -1, token: t});
|
||||
py_assert!(py, one, "hash(one) == 1");
|
||||
py_assert!(py, ten, "hash(ten) == 10");
|
||||
py_assert!(py, minus_one, "hash(minus_one) == -2");
|
||||
|
@ -464,7 +474,7 @@ fn comparisons() {
|
|||
|
||||
|
||||
#[py::class]
|
||||
struct Sequence {}
|
||||
struct Sequence {token: PythonToken<Sequence>}
|
||||
|
||||
#[py::proto]
|
||||
impl PySequenceProtocol for Sequence {
|
||||
|
@ -485,14 +495,14 @@ fn sequence() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = Sequence{}.into_object(py);
|
||||
let c = py.with_token(|t| Sequence{token: t});
|
||||
py_assert!(py, c, "list(c) == [0, 1, 2, 3, 4]");
|
||||
py_expect_exception!(py, c, "c['abc']", TypeError);
|
||||
}
|
||||
|
||||
|
||||
#[py::class]
|
||||
struct Callable {}
|
||||
struct Callable {token: PythonToken<Callable>}
|
||||
|
||||
#[py::methods]
|
||||
impl Callable {
|
||||
|
@ -508,11 +518,11 @@ fn callable() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = Callable{}.into_object(py);
|
||||
let c = py.with_token(|t| Callable{token: t});
|
||||
py_assert!(py, c, "callable(c)");
|
||||
py_assert!(py, c, "c(7) == 42");
|
||||
|
||||
let nc = Comparisons{val: 0}.into_object(py);
|
||||
let nc = py.with_token(|t| Comparisons{val: 0, token: t});
|
||||
py_assert!(py, nc, "not callable(nc)");
|
||||
}
|
||||
|
||||
|
@ -520,6 +530,7 @@ fn callable() {
|
|||
struct SetItem {
|
||||
key: i32,
|
||||
val: i32,
|
||||
token: PythonToken<SetItem>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
|
@ -536,7 +547,7 @@ fn setitem() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(SetItem{key: 0, val: 0});
|
||||
let c = py.with_token(|t| SetItem{key: 0, val: 0, token: t});
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
assert_eq!(c.key, 1);
|
||||
assert_eq!(c.val, 2);
|
||||
|
@ -546,6 +557,7 @@ fn setitem() {
|
|||
#[py::class]
|
||||
struct DelItem {
|
||||
key: i32,
|
||||
token: PythonToken<DelItem>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
|
@ -561,7 +573,7 @@ fn delitem() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(DelItem{key:0});
|
||||
let c = py.with_token(|t| DelItem{key:0, token:t});
|
||||
py_run!(py, c, "del c[1]");
|
||||
assert_eq!(c.key, 1);
|
||||
py_expect_exception!(py, c, "c[1] = 2", NotImplementedError);
|
||||
|
@ -570,6 +582,7 @@ fn delitem() {
|
|||
#[py::class]
|
||||
struct SetDelItem {
|
||||
val: Option<i32>,
|
||||
token: PythonToken<SetDelItem>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
|
@ -590,7 +603,7 @@ fn setdelitem() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(SetDelItem{val: None});
|
||||
let c = py.with_token(|t| SetDelItem{val: None, token: t});
|
||||
py_run!(py, c, "c[1] = 2");
|
||||
assert_eq!(c.val, Some(2));
|
||||
py_run!(py, c, "del c[1]");
|
||||
|
@ -598,7 +611,7 @@ fn setdelitem() {
|
|||
}
|
||||
|
||||
#[py::class]
|
||||
struct Reversed {}
|
||||
struct Reversed {token: PythonToken<Reversed>}
|
||||
|
||||
#[py::proto]
|
||||
impl PyMappingProtocol for Reversed{
|
||||
|
@ -613,12 +626,12 @@ fn reversed() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = Reversed{}.into_object(py);
|
||||
let c = py.with_token(|t| Reversed{token: t});
|
||||
py_run!(py, c, "assert reversed(c) == 'I am reversed'");
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
struct Contains {}
|
||||
struct Contains {token: PythonToken<Contains>}
|
||||
|
||||
#[py::proto]
|
||||
impl PySequenceProtocol for Contains {
|
||||
|
@ -632,7 +645,7 @@ fn contains() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = Contains{}.into_object(py);
|
||||
let c = py.with_token(|t| Contains{token: t});
|
||||
py_run!(py, c, "assert 1 in c");
|
||||
py_run!(py, c, "assert -1 not in c");
|
||||
py_expect_exception!(py, c, "assert 'wrong type' not in c", TypeError);
|
||||
|
@ -641,7 +654,7 @@ fn contains() {
|
|||
|
||||
|
||||
#[py::class]
|
||||
struct UnaryArithmetic {}
|
||||
struct UnaryArithmetic {token: PythonToken<UnaryArithmetic>}
|
||||
|
||||
#[py::proto]
|
||||
impl PyNumberProtocol for UnaryArithmetic {
|
||||
|
@ -668,7 +681,7 @@ fn unary_arithmetic() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = UnaryArithmetic{}.into_object(py);
|
||||
let c = py.with_token(|t| UnaryArithmetic{token: t});
|
||||
py_run!(py, c, "assert -c == 'neg'");
|
||||
py_run!(py, c, "assert +c == 'pos'");
|
||||
py_run!(py, c, "assert abs(c) == 'abs'");
|
||||
|
@ -677,7 +690,7 @@ fn unary_arithmetic() {
|
|||
|
||||
|
||||
#[py::class]
|
||||
struct BinaryArithmetic {}
|
||||
struct BinaryArithmetic {token: PythonToken<BinaryArithmetic>}
|
||||
|
||||
#[py::proto]
|
||||
impl PyObjectProtocol for BinaryArithmetic {
|
||||
|
@ -726,7 +739,7 @@ fn binary_arithmetic() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = BinaryArithmetic{}.into_object(py);
|
||||
let c = py.with_token(|t| BinaryArithmetic{token: t});
|
||||
py_run!(py, c, "assert c + c == 'BA + BA'");
|
||||
py_run!(py, c, "assert c + 1 == 'BA + 1'");
|
||||
py_run!(py, c, "assert 1 + c == '1 + BA'");
|
||||
|
@ -749,7 +762,9 @@ fn binary_arithmetic() {
|
|||
|
||||
|
||||
#[py::class]
|
||||
struct RichComparisons {}
|
||||
struct RichComparisons {
|
||||
token: PythonToken<RichComparisons>
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
impl PyObjectProtocol for RichComparisons {
|
||||
|
@ -795,7 +810,7 @@ fn rich_comparisons() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = RichComparisons{}.into_object(py);
|
||||
let c = py.with_token(|t| RichComparisons{token: t});
|
||||
py_run!(py, c, "assert (c < c) == 'RC < RC'");
|
||||
py_run!(py, c, "assert (c < 1) == 'RC < 1'");
|
||||
py_run!(py, c, "assert (1 < c) == 'RC > 1'");
|
||||
|
@ -821,7 +836,7 @@ fn rich_comparisons_python_3_type_error() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c2 = RichComparisons2{}.into_object(py);
|
||||
let c2 = py.with_token(|t| RichComparisons2{py: t});
|
||||
py_expect_exception!(py, c2, "c2 < c2", TypeError);
|
||||
py_expect_exception!(py, c2, "c2 < 1", TypeError);
|
||||
py_expect_exception!(py, c2, "1 < c2", TypeError);
|
||||
|
@ -844,7 +859,8 @@ fn rich_comparisons_python_3_type_error() {
|
|||
|
||||
#[py::class]
|
||||
struct InPlaceOperations {
|
||||
value: u32
|
||||
value: u32,
|
||||
token: PythonToken<InPlaceOperations>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
|
@ -902,36 +918,38 @@ fn inplace_operations() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = InPlaceOperations{value: 0}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value: 0, token: t});
|
||||
py_run!(py, c, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'");
|
||||
|
||||
let c = InPlaceOperations{value:10}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value:10, token: t});
|
||||
py_run!(py, c, "d = c; c -= 1; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
|
||||
let c = InPlaceOperations{value: 3}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value: 3, token: t});
|
||||
py_run!(py, c, "d = c; c *= 3; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
|
||||
let c = InPlaceOperations{value: 3}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value: 3, token: t});
|
||||
py_run!(py, c, "d = c; c <<= 2; assert repr(c) == repr(d) == 'IPO(12)'");
|
||||
|
||||
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value: 12, token: t});
|
||||
py_run!(py, c, "d = c; c >>= 2; assert repr(c) == repr(d) == 'IPO(3)'");
|
||||
|
||||
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value: 12, token: t});
|
||||
py_run!(py, c, "d = c; c &= 10; assert repr(c) == repr(d) == 'IPO(8)'");
|
||||
|
||||
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value: 12, token: t});
|
||||
py_run!(py, c, "d = c; c |= 3; assert repr(c) == repr(d) == 'IPO(15)'");
|
||||
|
||||
let c = InPlaceOperations{value: 12}.into_object(py);
|
||||
let c = py.with_token(|t| InPlaceOperations{value: 12, token: t});
|
||||
py_run!(py, c, "d = c; c ^= 5; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
}
|
||||
|
||||
#[py::class]
|
||||
struct ContextManager {
|
||||
exit_called: bool
|
||||
exit_called: bool,
|
||||
token: PythonToken<ContextManager>,
|
||||
}
|
||||
|
||||
/*
|
||||
#[py::proto]
|
||||
impl<'p> PyContextProtocol<'p> for ContextManager {
|
||||
|
||||
|
@ -950,14 +968,14 @@ impl<'p> PyContextProtocol<'p> for ContextManager {
|
|||
Ok(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
#[test]
|
||||
/*#[test]
|
||||
fn context_manager() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = py.init(ContextManager{exit_called: false});
|
||||
let mut c = py.with_token(|t| ContextManager{exit_called: false, token: t});
|
||||
py_run!(py, c, "with c as x:\n assert x == 42");
|
||||
assert!(c.exit_called);
|
||||
|
||||
|
@ -970,12 +988,13 @@ fn context_manager() {
|
|||
py, c, "with c as x:\n raise NotImplementedError",
|
||||
NotImplementedError);
|
||||
assert!(c.exit_called);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
#[py::class]
|
||||
struct ClassWithProperties {
|
||||
num: i32
|
||||
num: i32,
|
||||
token: PythonToken<ClassWithProperties>,
|
||||
}
|
||||
|
||||
#[py::methods]
|
||||
|
@ -990,7 +1009,7 @@ impl ClassWithProperties {
|
|||
Ok(self.num)
|
||||
}
|
||||
#[setter(DATA)]
|
||||
fn set(&self, py: Python, value: i32) -> PyResult<()> {
|
||||
fn set(&mut self, py: Python, value: i32) -> PyResult<()> {
|
||||
self.num = value;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1002,7 +1021,7 @@ fn class_with_properties() {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let inst = ClassWithProperties{num: 10}.into_object(py);
|
||||
let inst = py.with_token(|t| ClassWithProperties{num: 10, token: t});
|
||||
|
||||
py_run!(py, inst, "assert inst.get_num() == 10");
|
||||
py_run!(py, inst, "assert inst.get_num() == inst.DATA");
|
||||
|
|
Loading…
Reference in New Issue