better gil token scope
This commit is contained in:
parent
ea8ccf190a
commit
51ac8c9c78
|
@ -52,8 +52,8 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident, token: Option<syn::Ident>) ->
|
|||
let extra = if let Some(token) = token {
|
||||
Some(quote! {
|
||||
impl _pyo3::PythonObjectWithToken for #cls {
|
||||
fn token<'p>(&'p self) -> _pyo3::python::Python<'p> {
|
||||
self.#token.token()
|
||||
fn token<'p>(&'p self) -> _pyo3::python::Python<'p> {
|
||||
self.#token.token()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,12 +127,16 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident, token: Option<syn::Ident>) ->
|
|||
let ptr = (py.as_ptr() as *mut u8).offset(offset) as *mut #cls;
|
||||
Ok(ptr.as_ref().unwrap())
|
||||
} else {
|
||||
Err(_pyo3::PyDowncastError(py.token(), None))
|
||||
Err(_pyo3::PyDowncastError(py.gil(), None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl _pyo3::class::PyCustomObject for #cls {
|
||||
|
||||
}
|
||||
|
||||
#extra
|
||||
}
|
||||
}
|
||||
|
|
|
@ -331,7 +331,7 @@ macro_rules! py_argparse_impl {
|
|||
// We'll have to generate a bunch of nested `match` statements
|
||||
// (at least until we can use ? + catch, assuming that will be hygienic wrt. macros),
|
||||
// so use a recursive helper macro for that:
|
||||
py_argparse_extract!( py, _iter, $body,
|
||||
py_argparse_extract!(py, _iter, $body,
|
||||
[ $( { $pname : $ptype = $detail } )* ])
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
|
@ -344,11 +344,9 @@ macro_rules! py_argparse_impl {
|
|||
#[doc(hidden)]
|
||||
macro_rules! py_argparse_raw {
|
||||
($py:ident, $fname:expr, $args:expr, $kwargs:expr, $plist:tt $body:block) => {{
|
||||
let args: $crate::PyTuple = $crate::PyObject::from_borrowed_ptr($py, $args).unchecked_cast_into();
|
||||
let args: $crate::PyTuple = $crate::PyTuple::from_borrowed_ptr($py, $args);
|
||||
let kwargs: Option<$crate::PyDict> = $crate::argparse::get_kwargs($py, $kwargs);
|
||||
let ret = py_argparse_impl!($py, $fname, &args, kwargs.as_ref(), $body, $plist);
|
||||
$crate::PyDrop::release_ref(args, $py);
|
||||
$crate::PyDrop::release_ref(kwargs, $py);
|
||||
ret
|
||||
}};
|
||||
}
|
||||
|
@ -363,7 +361,7 @@ pub unsafe fn get_kwargs<'p>(py: Python<'p>, ptr: *mut ffi::PyObject) -> Option<
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! py_argparse_param_description {
|
||||
|
@ -394,7 +392,8 @@ macro_rules! py_argparse_extract {
|
|||
) => {
|
||||
// First unwrap() asserts the iterated sequence is long enough (which should be guaranteed);
|
||||
// second unwrap() asserts the parameter was not missing (which fn parse_args already checked for).
|
||||
match <$ptype as $crate::FromPyObject>::extract($py, $iter.next().unwrap().as_ref().unwrap()) {
|
||||
match <$ptype as $crate::FromPyObject>::extract(
|
||||
$iter.next().unwrap().as_ref().unwrap()) {
|
||||
Ok($pname) => py_argparse_extract!($py, $iter, $body, [$($tail)*]),
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
|
@ -405,8 +404,8 @@ macro_rules! py_argparse_extract {
|
|||
) => {
|
||||
// First unwrap() asserts the iterated sequence is long enough (which should be guaranteed);
|
||||
// second unwrap() asserts the parameter was not missing (which fn parse_args already checked for).
|
||||
match <$rtype as $crate::RefFromPyObject>::with_extracted($py,
|
||||
$iter.next().unwrap().as_ref().unwrap(),
|
||||
match <$rtype as $crate::RefFromPyObject>::with_extracted(
|
||||
$iter.next().unwrap().as_ref().unwrap(),
|
||||
|$pname: $ptype| py_argparse_extract!($py, $iter, $body, [$($tail)*])
|
||||
) {
|
||||
Ok(v) => v,
|
||||
|
@ -417,7 +416,7 @@ macro_rules! py_argparse_extract {
|
|||
( $py:expr, $iter:expr, $body:block,
|
||||
[ { $pname:ident : $ptype:ty = [ {} {$default:expr} {} ] } $($tail:tt)* ]
|
||||
) => {
|
||||
match $iter.next().unwrap().as_ref().map(|obj| obj.extract::<_>($py)).unwrap_or(Ok($default)) {
|
||||
match $iter.next().unwrap().as_ref().map(|obj| obj.extract::<_>()).unwrap_or(Ok($default)) {
|
||||
Ok($pname) => py_argparse_extract!($py, $iter, $body, [$($tail)*]),
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
|
@ -427,8 +426,7 @@ macro_rules! py_argparse_extract {
|
|||
[ { $pname:ident : $ptype:ty = [ {} {$default:expr} {$rtype:ty} ] } $($tail:tt)* ]
|
||||
) => {
|
||||
//unwrap() asserts the iterated sequence is long enough (which should be guaranteed);
|
||||
$crate::argparse::with_extracted_or_default($py,
|
||||
$iter.next().unwrap().as_ref(),
|
||||
$crate::argparse::with_extracted_or_default($iter.next().unwrap().as_ref(),
|
||||
|$pname: $ptype| py_argparse_extract!($py, $iter, $body, [$($tail)*]),
|
||||
$default)
|
||||
};
|
||||
|
@ -436,24 +434,22 @@ macro_rules! py_argparse_extract {
|
|||
|
||||
#[doc(hidden)] // used in py_argparse_extract!() macro
|
||||
pub fn with_extracted_or_default<'p, P: ?Sized, R, F>(
|
||||
py: Python<'p>,
|
||||
obj: Option<&'p Py<'p,PyObject>>,
|
||||
f: F, default: &'static P) -> PyResult<R>
|
||||
obj: Option<&'p PyObject>, f: F, default: &'static P) -> PyResult<R>
|
||||
where F: FnOnce(&P) -> PyResult<R>,
|
||||
P: RefFromPyObject<'p>
|
||||
{
|
||||
match obj {
|
||||
Some(obj) => match P::with_extracted(py, obj, f) {
|
||||
Some(obj) => match P::with_extracted(obj, f) {
|
||||
Ok(result) => result,
|
||||
Err(e) => Err(e)
|
||||
},
|
||||
None => f(default)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
mod test {
|
||||
use python::{Python};
|
||||
use objects::PyTuple;
|
||||
use conversion::{ToPyTuple};
|
||||
|
@ -480,7 +476,7 @@ mod test {
|
|||
let mut called = false;
|
||||
let tuple = ("abc",).to_py_tuple(py);
|
||||
py_argparse!(py, None, &tuple, None, (x) {
|
||||
assert_eq!(*x, tuple.get_item(py, 0));
|
||||
assert_eq!(*x, tuple.get_item(0));
|
||||
called = true;
|
||||
Ok(())
|
||||
}).unwrap();
|
||||
|
|
|
@ -139,7 +139,7 @@ fn validate(b: &ffi::Py_buffer) {
|
|||
|
||||
impl PyBuffer {
|
||||
/// Get the underlying buffer from the specified python object.
|
||||
pub fn get<'p>(obj: Py<'p, PyObject>) -> PyResult<PyBuffer> {
|
||||
pub fn get<'p>(obj: &PyObject<'p>) -> PyResult<PyBuffer> {
|
||||
unsafe {
|
||||
let mut buf = Box::new(mem::zeroed::<ffi::Py_buffer>());
|
||||
err::error_on_minusone(
|
||||
|
@ -565,12 +565,13 @@ impl_element!(isize, SignedInteger);
|
|||
impl_element!(f32, Float);
|
||||
impl_element!(f64, Float);
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
//#[cfg(test)]
|
||||
mod test {
|
||||
use std;
|
||||
use python::{Python, PythonObject, PyDrop};
|
||||
use python::{Python};
|
||||
use conversion::ToPyObject;
|
||||
use objects::{PySequence, PyList, PyTuple, PyIterator};
|
||||
use objects::{PyList, PyTuple};//, PySequence, PyIterator};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
use super::PyBuffer;
|
||||
|
||||
|
@ -585,7 +586,7 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let bytes = py.eval("b'abcde'", None, None).unwrap();
|
||||
let buffer = PyBuffer::get(py, &bytes).unwrap();
|
||||
let buffer = PyBuffer::get(&bytes).unwrap();
|
||||
assert_eq!(buffer.dimensions(), 1);
|
||||
assert_eq!(buffer.item_count(), 5);
|
||||
assert_eq!(buffer.format().to_str().unwrap(), "B");
|
||||
|
@ -620,8 +621,9 @@ mod test {
|
|||
fn test_array_buffer() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let array = py.import("array").unwrap().as_object().call_method(py, "array", ("f", (1.0, 1.5, 2.0, 2.5)), None).unwrap();
|
||||
let buffer = PyBuffer::get(py, &array).unwrap();
|
||||
let array = py.import("array").unwrap().call_method(
|
||||
"array", ("f", (1.0, 1.5, 2.0, 2.5)), None).unwrap();
|
||||
let buffer = PyBuffer::get(&array).unwrap();
|
||||
assert_eq!(buffer.dimensions(), 1);
|
||||
assert_eq!(buffer.item_count(), 4);
|
||||
assert_eq!(buffer.format().to_str().unwrap(), "f");
|
||||
|
|
|
@ -32,6 +32,8 @@ pub static NO_METHODS: &'static [&'static str] = &[];
|
|||
pub static NO_PY_METHODS: &'static [PyMethodDefType] = &[];
|
||||
|
||||
use ffi;
|
||||
use typeob::PyTypeInfo;
|
||||
use python::ToPythonPointer;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum CompareOp {
|
||||
|
@ -43,4 +45,14 @@ pub enum CompareOp {
|
|||
Ge = ffi::Py_GE as isize
|
||||
}
|
||||
|
||||
pub trait PyCustomObject : Sized {}
|
||||
pub trait PyCustomObject : PyTypeInfo + Sized {}
|
||||
|
||||
impl<'p, T> ToPythonPointer for T where T: PyCustomObject {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
let offset = <T as PyTypeInfo>::offset();
|
||||
unsafe {
|
||||
{self as *const _ as *mut u8}.offset(-offset) as *mut ffi::PyObject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ffi;
|
||||
use err::PyResult;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use pyptr::PyPtr;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use objects::{PyObject, PyTuple};
|
||||
use token::PyObjectMarker;
|
||||
|
@ -21,7 +21,7 @@ pub trait ToPyObject {
|
|||
fn with_borrowed_ptr<F, R>(&self, py: Python, f: F) -> R
|
||||
where F: FnOnce(*mut ffi::PyObject) -> R
|
||||
{
|
||||
let obj = self.to_object(py).into_object();
|
||||
let obj = self.to_object(py).park();
|
||||
f(obj.as_ptr())
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ pub trait FromPyObject<'source> : Sized {
|
|||
}
|
||||
|
||||
pub trait RefFromPyObject<'p> {
|
||||
fn with_extracted<F, R>(obj: &'p Py<'p, PyObject>, f: F) -> PyResult<R>
|
||||
fn with_extracted<F, R>(obj: &'p PyObject, f: F) -> PyResult<R>
|
||||
where F: FnOnce(&Self) -> R;
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ impl <'p, T: ?Sized> RefFromPyObject<'p> for T
|
|||
where for<'a> &'a T: FromPyObject<'p> + Sized
|
||||
{
|
||||
#[inline]
|
||||
fn with_extracted<F, R>(obj: &'p Py<'p, PyObject>, f: F) -> PyResult<R>
|
||||
fn with_extracted<F, R>(obj: &'p PyObject, f: F) -> PyResult<R>
|
||||
where F: FnOnce(&Self) -> R
|
||||
{
|
||||
match FromPyObject::extract(obj) {
|
||||
|
|
|
@ -179,7 +179,7 @@ impl PyErr {
|
|||
ptype: if ptype.is_null() {
|
||||
py.get_type::<exc::SystemError>().into_object()
|
||||
} else {
|
||||
PyPtr::<PyObjectMarker>::from_owned_ptr(ptype).into_object()
|
||||
PyPtr::<PyObjectMarker>::from_owned_ptr(ptype).park()
|
||||
},
|
||||
pvalue: PyPtr::from_owned_ptr_or_opt(py, pvalue),
|
||||
ptraceback: PyPtr::from_owned_ptr_or_opt(py, ptraceback)
|
||||
|
@ -386,12 +386,12 @@ pub fn error_on_minusone(py: Python, result: libc::c_int) -> PyResult<()> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use {Python, PyErr};
|
||||
use ::{Python, PyErr};
|
||||
use objects::exc;
|
||||
|
||||
#[test]
|
||||
fn set_typeerror() {
|
||||
let gil = Python::acqduire_gil();
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
PyErr::new_lazy_init(py.get_type::<exc::TypeError>(), None).restore(py);
|
||||
assert!(PyErr::occurred(py));
|
||||
|
|
|
@ -115,7 +115,7 @@ macro_rules! py_fn_impl {
|
|||
kwargs: *mut $crate::ffi::PyObject)
|
||||
-> *mut $crate::ffi::PyObject
|
||||
{
|
||||
$crate::callback::handle_callback(
|
||||
$crate::callback::handle(
|
||||
stringify!($f), $crate::callback::PyObjectCallbackConverter,
|
||||
|py| {
|
||||
py_argparse_raw!(py, Some(stringify!($f)), args, kwargs,
|
||||
|
|
|
@ -71,7 +71,7 @@ mod ppptr;
|
|||
pub use ppptr::pptr;
|
||||
|
||||
mod token;
|
||||
pub use token::{PyObjectMarker, PythonToken, PythonObjectWithToken};
|
||||
pub use token::{PyObjectMarker, PythonToken, PythonObjectWithToken, PythonObjectWithGilToken};
|
||||
|
||||
pub use err::{PyErr, PyResult, PyDowncastError};
|
||||
pub use objects::*;
|
||||
|
@ -82,6 +82,7 @@ pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, To
|
|||
pub use class::{CompareOp};
|
||||
pub mod class;
|
||||
pub use class::*;
|
||||
pub use native::PyNativeObject;
|
||||
pub use self::typeob::PyTypeObject;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
|
@ -112,7 +113,7 @@ macro_rules! py_replace_expr {
|
|||
}
|
||||
|
||||
pub mod python;
|
||||
pub mod native;
|
||||
mod native;
|
||||
mod err;
|
||||
mod conversion;
|
||||
mod objects;
|
||||
|
@ -122,7 +123,7 @@ pub mod callback;
|
|||
pub mod typeob;
|
||||
pub mod argparse;
|
||||
pub mod function;
|
||||
pub mod buffer;
|
||||
// pub mod buffer;
|
||||
|
||||
// re-export for simplicity
|
||||
pub use std::os::raw::*;
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
use ffi;
|
||||
use ppptr::pptr;
|
||||
use pyptr::PyPtr;
|
||||
use token::PyObjectMarker;
|
||||
use typeob::PyTypeInfo;
|
||||
use objects::PyObject;
|
||||
use python::ToPythonPointer;
|
||||
|
||||
pub trait PyBaseObject : PyTypeInfo + Sized {}
|
||||
|
||||
pub trait PyNativeObject : PyTypeInfo {
|
||||
pub trait PyNativeObject<'p> : PyBaseObject {
|
||||
|
||||
fn as_object(self) -> PyObject<'p>;
|
||||
|
||||
fn into_object(self) -> PyPtr<PyObjectMarker>;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*impl<'a, T: Sized> FromPyObject<'a> for T
|
||||
where T: PyNativeObject + PythonObjectWithCheckedDowncast
|
||||
{
|
||||
|
|
|
@ -7,15 +7,15 @@ use std::cmp::Ordering;
|
|||
use ffi;
|
||||
use libc;
|
||||
use pyptr::{Py, PyPtr};
|
||||
use python::{Python, ToPythonPointer};
|
||||
use python::{Python, PyDowncastInto, ToPythonPointer};
|
||||
use objects::{PyObject, PyDict, PyString};
|
||||
use token::PythonObjectWithToken;
|
||||
use token::PythonObjectWithGilToken;
|
||||
use conversion::{ToPyObject, ToPyTuple};
|
||||
use typeob::PyTypeInfo;
|
||||
use err::{PyErr, PyResult, self};
|
||||
|
||||
|
||||
pub trait ObjectProtocol {
|
||||
pub trait ObjectProtocol<'p> {
|
||||
|
||||
/// Determines whether this object has the given attribute.
|
||||
/// This is equivalent to the Python expression 'hasattr(self, attr_name)'.
|
||||
|
@ -23,7 +23,7 @@ pub trait ObjectProtocol {
|
|||
|
||||
/// Retrieves an attribute value.
|
||||
/// This is equivalent to the Python expression 'self.attr_name'.
|
||||
fn getattr<N>(&self, attr_name: N) -> PyResult<Py<PyObject>> where N: ToPyObject;
|
||||
fn getattr<N>(&self, attr_name: N) -> PyResult<PyObject<'p>> where N: ToPyObject;
|
||||
|
||||
/// Sets an attribute value.
|
||||
/// This is equivalent to the Python expression 'self.attr_name = value'.
|
||||
|
@ -61,29 +61,29 @@ pub trait ObjectProtocol {
|
|||
/// * CompareOp::Gt: `self > other`
|
||||
/// * CompareOp::Ge: `self >= other`
|
||||
fn rich_compare<O>(&self, other: O, compare_op: ::CompareOp)
|
||||
-> PyResult<Py<PyObject>> where O: ToPyObject;
|
||||
-> PyResult<PyObject<'p>> where O: ToPyObject;
|
||||
|
||||
/// Compute the string representation of self.
|
||||
/// This is equivalent to the Python expression 'repr(self)'.
|
||||
fn repr(&self) -> PyResult<Py<PyString>>;
|
||||
fn repr(&self) -> PyResult<PyString<'p>>;
|
||||
|
||||
/// Compute the string representation of self.
|
||||
/// This is equivalent to the Python expression 'str(self)'.
|
||||
fn str(&self) -> PyResult<Py<PyString>>;
|
||||
fn str(&self) -> PyResult<PyString<'p>>;
|
||||
|
||||
/// Determines whether this object is callable.
|
||||
fn is_callable(&self) -> bool;
|
||||
|
||||
/// Calls the object.
|
||||
/// This is equivalent to the Python expression: 'self(*args, **kwargs)'
|
||||
fn call<A>(&self, args: A, kwargs: Option<&PyDict>) -> PyResult<Py<PyObject>>
|
||||
fn call<A>(&self, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject<'p>>
|
||||
where A: ToPyTuple;
|
||||
|
||||
/// Calls a method on the object.
|
||||
/// This is equivalent to the Python expression: 'self.name(*args, **kwargs)'
|
||||
fn call_method<A>(&self,
|
||||
name: &str, args: A,
|
||||
kwargs: Option<&PyDict>) -> PyResult<Py<PyObject>>
|
||||
kwargs: Option<&PyDict>) -> PyResult<PyObject<'p>>
|
||||
where A: ToPyTuple;
|
||||
|
||||
/// Retrieves the hash code of the object.
|
||||
|
@ -104,7 +104,7 @@ pub trait ObjectProtocol {
|
|||
fn len(&self) -> PyResult<usize>;
|
||||
|
||||
/// This is equivalent to the Python expression: 'self[key]'
|
||||
fn get_item<K>(&self, key: K) -> PyResult<Py<PyObject>> where K: ToPyObject;
|
||||
fn get_item<K>(&self, key: K) -> PyResult<PyObject<'p>> where K: ToPyObject;
|
||||
|
||||
/// Sets an item value.
|
||||
/// This is equivalent to the Python expression 'self[key] = value'.
|
||||
|
@ -122,13 +122,13 @@ pub trait ObjectProtocol {
|
|||
}
|
||||
|
||||
|
||||
impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
||||
impl<'p, T> ObjectProtocol<'p> for T where T: PythonObjectWithGilToken<'p> + ToPythonPointer {
|
||||
|
||||
/// Determines whether this object has the given attribute.
|
||||
/// This is equivalent to the Python expression 'hasattr(self, attr_name)'.
|
||||
#[inline]
|
||||
fn hasattr<N>(&self, attr_name: N) -> PyResult<bool> where N: ToPyObject {
|
||||
attr_name.with_borrowed_ptr(self.token(), |attr_name| unsafe {
|
||||
attr_name.with_borrowed_ptr(self.gil(), |attr_name| unsafe {
|
||||
Ok(ffi::PyObject_HasAttr(self.as_ptr(), attr_name) != 0)
|
||||
})
|
||||
}
|
||||
|
@ -136,11 +136,11 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
/// Retrieves an attribute value.
|
||||
/// This is equivalent to the Python expression 'self.attr_name'.
|
||||
#[inline]
|
||||
fn getattr<N>(&self, attr_name: N) -> PyResult<Py<PyObject>> where N: ToPyObject
|
||||
fn getattr<N>(&self, attr_name: N) -> PyResult<PyObject<'p>> where N: ToPyObject
|
||||
{
|
||||
attr_name.with_borrowed_ptr(self.token(), |attr_name| unsafe {
|
||||
Py::from_owned_ptr_or_err(
|
||||
self.token(), ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
|
||||
attr_name.with_borrowed_ptr(self.gil(), |attr_name| unsafe {
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
self.gil(), ffi::PyObject_GetAttr(self.as_ptr(), attr_name))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -151,10 +151,10 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
where N: ToPyObject, V: ToPyObject
|
||||
{
|
||||
attr_name.with_borrowed_ptr(
|
||||
self.token(), move |attr_name|
|
||||
value.with_borrowed_ptr(self.token(), |value| unsafe {
|
||||
self.gil(), move |attr_name|
|
||||
value.with_borrowed_ptr(self.gil(), |value| unsafe {
|
||||
err::error_on_minusone(
|
||||
self.token(), ffi::PyObject_SetAttr(self.as_ptr(), attr_name, value))
|
||||
self.gil(), ffi::PyObject_SetAttr(self.as_ptr(), attr_name, value))
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -162,8 +162,8 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
/// This is equivalent to the Python expression 'del self.attr_name'.
|
||||
#[inline]
|
||||
fn delattr<N>(&self, attr_name: N) -> PyResult<()> where N: ToPyObject {
|
||||
attr_name.with_borrowed_ptr(self.token(), |attr_name| unsafe {
|
||||
err::error_on_minusone(self.token(),
|
||||
attr_name.with_borrowed_ptr(self.gil(), |attr_name| unsafe {
|
||||
err::error_on_minusone(self.gil(),
|
||||
ffi::PyObject_DelAttr(self.as_ptr(), attr_name))
|
||||
})
|
||||
}
|
||||
|
@ -208,8 +208,8 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
return Err(PyErr::new::<::exc::TypeError, _>(py, "ObjectProtocol::compare(): All comparisons returned false"));
|
||||
}
|
||||
|
||||
other.with_borrowed_ptr(self.token(), |other| unsafe {
|
||||
do_compare(self.token(), self.as_ptr(), other)
|
||||
other.with_borrowed_ptr(self.gil(), |other| unsafe {
|
||||
do_compare(self.gil(), self.as_ptr(), other)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -223,11 +223,11 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
/// * CompareOp::Gt: `self > other`
|
||||
/// * CompareOp::Ge: `self >= other`
|
||||
fn rich_compare<O>(&self, other: O, compare_op: ::CompareOp)
|
||||
-> PyResult<Py<PyObject>> where O: ToPyObject {
|
||||
-> PyResult<PyObject<'p>> where O: ToPyObject {
|
||||
unsafe {
|
||||
other.with_borrowed_ptr(self.token(), |other| {
|
||||
Py::cast_from_owned_or_err(
|
||||
self.token(), ffi::PyObject_RichCompare(
|
||||
other.with_borrowed_ptr(self.gil(), |other| {
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
self.gil(), ffi::PyObject_RichCompare(
|
||||
self.as_ptr(), other, compare_op as libc::c_int))
|
||||
})
|
||||
}
|
||||
|
@ -236,15 +236,17 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
/// Compute the string representation of self.
|
||||
/// This is equivalent to the Python expression 'repr(self)'.
|
||||
#[inline]
|
||||
fn repr(&self) -> PyResult<Py<PyString>> {
|
||||
unsafe { Py::cast_from_owned_or_err(self.token(), ffi::PyObject_Repr(self.as_ptr())) }
|
||||
fn repr(&self) -> PyResult<PyString<'p>> {
|
||||
Ok(PyString::downcast_from_owned_ptr(
|
||||
self.gil(), unsafe{ffi::PyObject_Repr(self.as_ptr())})?)
|
||||
}
|
||||
|
||||
/// Compute the string representation of self.
|
||||
/// This is equivalent to the Python expression 'str(self)'.
|
||||
#[inline]
|
||||
fn str(&self) -> PyResult<Py<PyString>> {
|
||||
unsafe { Py::cast_from_owned_or_err(self.token(), ffi::PyObject_Str(self.as_ptr())) }
|
||||
fn str(&self) -> PyResult<PyString<'p>> {
|
||||
Ok(PyString::downcast_from_owned_ptr(
|
||||
self.gil(), unsafe{ffi::PyObject_Str(self.as_ptr())})?)
|
||||
}
|
||||
|
||||
/// Determines whether this object is callable.
|
||||
|
@ -258,13 +260,13 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
/// Calls the object.
|
||||
/// This is equivalent to the Python expression: 'self(*args, **kwargs)'
|
||||
#[inline]
|
||||
fn call<A>(&self, args: A, kwargs: Option<&PyDict>) -> PyResult<Py<PyObject>>
|
||||
fn call<A>(&self, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject<'p>>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
let t = args.to_py_tuple(self.token());
|
||||
let t = args.to_py_tuple(self.gil());
|
||||
unsafe {
|
||||
Py::from_owned_ptr_or_err(
|
||||
self.token(),
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
self.gil(),
|
||||
ffi::PyObject_Call(self.as_ptr(), t.as_ptr(), kwargs.as_ptr()))
|
||||
}
|
||||
}
|
||||
|
@ -274,14 +276,14 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
#[inline]
|
||||
fn call_method<A>(&self,
|
||||
name: &str, args: A,
|
||||
kwargs: Option<&PyDict>) -> PyResult<Py<PyObject>>
|
||||
kwargs: Option<&PyDict>) -> PyResult<PyObject<'p>>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
name.with_borrowed_ptr(self.token(), |name| unsafe {
|
||||
let t = args.to_py_tuple(self.token());
|
||||
name.with_borrowed_ptr(self.gil(), |name| unsafe {
|
||||
let t = args.to_py_tuple(self.gil());
|
||||
let ptr = ffi::PyObject_GetAttr(self.as_ptr(), name);
|
||||
Py::from_owned_ptr_or_err(
|
||||
self.token(),
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
self.gil(),
|
||||
ffi::PyObject_Call(ptr, t.as_ptr(), kwargs.as_ptr()))
|
||||
})
|
||||
}
|
||||
|
@ -292,7 +294,7 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
fn hash(&self) -> PyResult<::Py_hash_t> {
|
||||
let v = unsafe { ffi::PyObject_Hash(self.as_ptr()) };
|
||||
if v == -1 {
|
||||
Err(PyErr::fetch(self.token()))
|
||||
Err(PyErr::fetch(self.gil()))
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
|
@ -304,7 +306,7 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
fn is_true(&self) -> PyResult<bool> {
|
||||
let v = unsafe { ffi::PyObject_IsTrue(self.as_ptr()) };
|
||||
if v == -1 {
|
||||
Err(PyErr::fetch(self.token()))
|
||||
Err(PyErr::fetch(self.gil()))
|
||||
} else {
|
||||
Ok(v != 0)
|
||||
}
|
||||
|
@ -323,7 +325,7 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
fn len(&self) -> PyResult<usize> {
|
||||
let v = unsafe { ffi::PyObject_Size(self.as_ptr()) };
|
||||
if v == -1 {
|
||||
Err(PyErr::fetch(self.token()))
|
||||
Err(PyErr::fetch(self.gil()))
|
||||
} else {
|
||||
Ok(v as usize)
|
||||
}
|
||||
|
@ -331,10 +333,10 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
|
||||
/// This is equivalent to the Python expression: 'self[key]'
|
||||
#[inline]
|
||||
fn get_item<K>(&self, key: K) -> PyResult<Py<PyObject>> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
Py::from_owned_ptr_or_err(
|
||||
self.token(), ffi::PyObject_GetItem(self.as_ptr(), key))
|
||||
fn get_item<K>(&self, key: K) -> PyResult<PyObject<'p>> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.gil(), |key| unsafe {
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
self.gil(), ffi::PyObject_GetItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -345,9 +347,9 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
where K: ToPyObject, V: ToPyObject
|
||||
{
|
||||
key.with_borrowed_ptr(
|
||||
self.token(), move |key|
|
||||
value.with_borrowed_ptr(self.token(), |value| unsafe {
|
||||
err::error_on_minusone(self.token(),
|
||||
self.gil(), move |key|
|
||||
value.with_borrowed_ptr(self.gil(), |value| unsafe {
|
||||
err::error_on_minusone(self.gil(),
|
||||
ffi::PyObject_SetItem(self.as_ptr(), key, value))
|
||||
}))
|
||||
}
|
||||
|
@ -356,8 +358,8 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
/// This is equivalent to the Python expression 'del self[key]'.
|
||||
#[inline]
|
||||
fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
err::error_on_minusone(self.token(),
|
||||
key.with_borrowed_ptr(self.gil(), |key| unsafe {
|
||||
err::error_on_minusone(self.gil(),
|
||||
ffi::PyObject_DelItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
@ -372,7 +374,7 @@ impl<T> ObjectProtocol for T where T: PythonObjectWithToken + ToPythonPointer {
|
|||
}
|
||||
|
||||
|
||||
impl<'p, T> fmt::Debug for Py<'p, T> where T: ObjectProtocol + PyTypeInfo {
|
||||
impl<'p, T> fmt::Debug for Py<'p, T> where T: ObjectProtocol<'p> + PyTypeInfo {
|
||||
fn fmt(&self, f : &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
// TODO: we shouldn't use fmt::Error when repr() fails
|
||||
let repr_obj = try!(self.repr().map_err(|_| fmt::Error));
|
||||
|
@ -380,7 +382,7 @@ impl<'p, T> fmt::Debug for Py<'p, T> where T: ObjectProtocol + PyTypeInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p, T> fmt::Display for Py<'p, T> where T: ObjectProtocol + PyTypeInfo {
|
||||
impl<'p, T> fmt::Display for Py<'p, T> where T: ObjectProtocol<'p> + PyTypeInfo {
|
||||
fn fmt(&self, f : &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
// TODO: we shouldn't use fmt::Error when str() fails
|
||||
let str_obj = try!(self.str().map_err(|_| fmt::Error));
|
||||
|
@ -388,7 +390,7 @@ impl<'p, T> fmt::Display for Py<'p, T> where T: ObjectProtocol + PyTypeInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p, T> fmt::Debug for PyPtr<T> where T: ObjectProtocol + PyTypeInfo {
|
||||
impl<'p, T> fmt::Debug for PyPtr<T> where T: ObjectProtocol<'p> + PyTypeInfo {
|
||||
default fn fmt(&self, f : &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
@ -400,7 +402,7 @@ impl<'p, T> fmt::Debug for PyPtr<T> where T: ObjectProtocol + PyTypeInfo {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p, T> fmt::Display for PyPtr<T> where T: ObjectProtocol + PyTypeInfo {
|
||||
impl<'p, T> fmt::Display for PyPtr<T> where T: ObjectProtocol<'p> + PyTypeInfo {
|
||||
default fn fmt(&self, f : &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
@ -414,17 +416,16 @@ impl<'p, T> fmt::Display for PyPtr<T> where T: ObjectProtocol + PyTypeInfo {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std;
|
||||
use python::{Python, PythonObject};
|
||||
use python::{Python};
|
||||
use conversion::ToPyObject;
|
||||
use objects::{PyList, PyTuple};
|
||||
//use objects::{PyTuple}; //PyList,
|
||||
use super::ObjectProtocol;
|
||||
|
||||
#[test]
|
||||
fn test_debug_string() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = "Hello\n".to_py_object(py).into_object();
|
||||
let v = "Hello\n".to_object(py);
|
||||
assert_eq!(format!("{:?}", v), "'Hello\\n'");
|
||||
}
|
||||
|
||||
|
@ -432,7 +433,7 @@ mod test {
|
|||
fn test_display_string() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = "Hello\n".to_py_object(py).into_object();
|
||||
let v = "Hello\n".to_object(py);
|
||||
assert_eq!(format!("{}", v), "Hello\n");
|
||||
}
|
||||
|
||||
|
@ -441,10 +442,9 @@ mod test {
|
|||
use std::cmp::Ordering;
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let one = 1i32.to_py_object(py).into_object();
|
||||
assert_eq!(one.compare(py, 1).unwrap(), Ordering::Equal);
|
||||
assert_eq!(one.compare(py, 2).unwrap(), Ordering::Less);
|
||||
assert_eq!(one.compare(py, 0).unwrap(), Ordering::Greater);
|
||||
let one = 1i32.to_object(py).into_object(py);
|
||||
assert_eq!(one.compare(1).unwrap(), Ordering::Equal);
|
||||
assert_eq!(one.compare(2).unwrap(), Ordering::Less);
|
||||
assert_eq!(one.compare(0).unwrap(), Ordering::Greater);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,16 +52,17 @@ pyobject_extract!(obj to bool => {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use python::{Python, PythonObject};
|
||||
use python::{Python};
|
||||
use conversion::ToPyObject;
|
||||
use ::PyNativeObject;
|
||||
|
||||
#[test]
|
||||
fn test_true() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
assert!(py.True().is_true());
|
||||
assert_eq!(true, py.True().as_object().extract(py).unwrap());
|
||||
assert!(true.to_py_object(py).as_object() == py.True().as_object());
|
||||
assert_eq!(true, py.True().as_object().extract().unwrap());
|
||||
assert!(true.to_object(py).into_object(py) == py.True().as_object());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -69,7 +70,7 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
assert!(!py.False().is_true());
|
||||
assert_eq!(false, py.False().as_object().extract(py).unwrap());
|
||||
assert!(false.to_py_object(py).as_object() == py.False().as_object());
|
||||
assert_eq!(false, py.False().as_object().extract().unwrap());
|
||||
assert!(false.to_object(py).into_object(py) == py.False().as_object());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ use ffi;
|
|||
use python::{Python, ToPythonPointer};
|
||||
use objects::PyObject;
|
||||
use err::{PyResult, PyErr};
|
||||
use pyptr::Py;
|
||||
use ppptr::pptr;
|
||||
use token::PythonObjectWithGilToken;
|
||||
|
||||
|
||||
/// Represents a Python bytearray.
|
||||
|
@ -31,13 +31,13 @@ impl<'p> PyByteArray<'p> {
|
|||
|
||||
/// Creates a new Python bytearray object
|
||||
/// from other PyObject, that implements the buffer protocol.
|
||||
pub fn from(src: Py<'p, PyObject>) -> PyResult<PyByteArray<'p>> {
|
||||
pub fn from(src: &'p PyObject<'p>) -> PyResult<PyByteArray<'p>> {
|
||||
let res = unsafe {ffi::PyByteArray_FromObject(src.as_ptr())};
|
||||
if res != ptr::null_mut() {
|
||||
Ok(unsafe{ PyByteArray(
|
||||
pptr::cast_from_owned_ptr_or_panic::<PyByteArray>(src.token(), res))})
|
||||
pptr::cast_from_owned_ptr_or_panic::<PyByteArray>(src.gil(), res))})
|
||||
} else {
|
||||
Err(PyErr::fetch(src.token()))
|
||||
Err(PyErr::fetch(src.gil()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -75,9 +75,10 @@ impl<'p> PyByteArray<'p> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use ::ToPyObject;
|
||||
use exc;
|
||||
use class::PyTypeObject;
|
||||
use python::Python;
|
||||
use typeob::PyTypeObject;
|
||||
use objects::PyByteArray;
|
||||
|
||||
#[test]
|
||||
|
@ -90,17 +91,20 @@ mod test {
|
|||
assert_eq!(src.len(), bytearray.len());
|
||||
assert_eq!(src, bytearray.data());
|
||||
|
||||
//let bytearray = PyByteArray::from(py, bytearray.into_object()).unwrap();
|
||||
//assert_eq!(src.len(), bytearray.len(py));
|
||||
//assert_eq!(src, bytearray.data(py));
|
||||
let ba = bytearray.to_object(py);
|
||||
let bytearray = PyByteArray::from(ba.as_object(py)).unwrap();
|
||||
assert_eq!(src.len(), bytearray.len());
|
||||
assert_eq!(src, bytearray.data());
|
||||
|
||||
bytearray.resize(20).unwrap();
|
||||
assert_eq!(20, bytearray.len());
|
||||
|
||||
//if let Err(mut err) = PyByteArray::from(py, py.None()) {
|
||||
// assert!(exc::TypeError::type_object(py).is_instance(py, &err.instance(py)))
|
||||
//} else {
|
||||
// panic!("error");
|
||||
//}
|
||||
let none = py.None();
|
||||
if let Err(mut err) = PyByteArray::from(none.as_object(py)) {
|
||||
assert!(exc::TypeError::type_object(py).is_instance(&err.instance(py)))
|
||||
} else {
|
||||
panic!("error");
|
||||
}
|
||||
drop(none);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use pyptr::PyPtr;
|
|||
use python::{Python, ToPythonPointer};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use objects::PyObject;
|
||||
use token::{PyObjectMarker, PythonObjectWithToken}; //, PyList};
|
||||
use token::{PyObjectMarker, PythonObjectWithGilToken}; //, PyList};
|
||||
use err::{self, PyResult, PyErr};
|
||||
use std::{mem, collections, hash, cmp};
|
||||
|
||||
|
@ -36,7 +36,7 @@ impl<'p> PyDict<'p> {
|
|||
pub fn copy(&'p self) -> PyResult<PyDict<'p>> {
|
||||
unsafe {
|
||||
Ok(PyDict(
|
||||
pptr::from_owned_ptr_or_err(self.token(), ffi::PyDict_Copy(self.0.as_ptr()))?
|
||||
pptr::from_owned_ptr_or_err(self.gil(), ffi::PyDict_Copy(self.0.as_ptr()))?
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -57,11 +57,11 @@ impl<'p> PyDict<'p> {
|
|||
/// Determine if the dictionary contains the specified key.
|
||||
/// This is equivalent to the Python expression `key in self`.
|
||||
pub fn contains<K>(&self, key: K) -> PyResult<bool> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
key.with_borrowed_ptr(self.gil(), |key| unsafe {
|
||||
match ffi::PyDict_Contains(self.as_ptr(), key) {
|
||||
1 => Ok(true),
|
||||
0 => Ok(false),
|
||||
_ => Err(PyErr::fetch(self.token()))
|
||||
_ => Err(PyErr::fetch(self.gil()))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -69,9 +69,9 @@ impl<'p> PyDict<'p> {
|
|||
/// Gets an item from the dictionary.
|
||||
/// Returns None if the item is not present, or if an error occurs.
|
||||
pub fn get_item<K>(&self, key: K) -> Option<PyObject> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
key.with_borrowed_ptr(self.gil(), |key| unsafe {
|
||||
PyObject::from_borrowed_ptr_or_opt(
|
||||
self.token(), ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
self.gil(), ffi::PyDict_GetItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -80,19 +80,19 @@ impl<'p> PyDict<'p> {
|
|||
pub fn set_item<K, V>(&self, key: K, value: V)
|
||||
-> PyResult<()> where K: ToPyObject, V: ToPyObject {
|
||||
key.with_borrowed_ptr(
|
||||
self.token(), move |key|
|
||||
value.with_borrowed_ptr(self.token(), |value| unsafe {
|
||||
self.gil(), move |key|
|
||||
value.with_borrowed_ptr(self.gil(), |value| unsafe {
|
||||
err::error_on_minusone(
|
||||
self.token(), ffi::PyDict_SetItem(self.as_ptr(), key, value))
|
||||
self.gil(), ffi::PyDict_SetItem(self.as_ptr(), key, value))
|
||||
}))
|
||||
}
|
||||
|
||||
/// Deletes an item.
|
||||
/// This is equivalent to the Python expression `del self[key]`.
|
||||
pub fn del_item<K>(&self, key: K) -> PyResult<()> where K: ToPyObject {
|
||||
key.with_borrowed_ptr(self.token(), |key| unsafe {
|
||||
key.with_borrowed_ptr(self.gil(), |key| unsafe {
|
||||
err::error_on_minusone(
|
||||
self.token(), ffi::PyDict_DelItem(self.as_ptr(), key))
|
||||
self.gil(), ffi::PyDict_DelItem(self.as_ptr(), key))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ impl<'p> PyDict<'p> {
|
|||
// Note that we don't provide an iterator because
|
||||
// PyDict_Next() is unsafe to use when the dictionary might be changed
|
||||
// by other python code.
|
||||
let token = self.token();
|
||||
let token = self.gil();
|
||||
let mut vec = Vec::with_capacity(self.len());
|
||||
unsafe {
|
||||
let mut pos = 0;
|
||||
|
@ -151,21 +151,25 @@ impl <K, V> ToPyObject for collections::BTreeMap<K, V>
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use python::{Python, PythonObjectWithCheckedDowncast};
|
||||
use conversion::ToPyObject;
|
||||
use objects::{PyDict, PyTuple};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use python::{Python};
|
||||
use conversion::ToPyObject;
|
||||
use objects::{PyDict}; //, PyTuple};
|
||||
use ::PyDowncastFrom;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_len() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert_eq!(0, dict.len(py));
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert_eq!(0, dict.len());
|
||||
v.insert(7, 32);
|
||||
let dict2 = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert_eq!(1, dict2.len(py));
|
||||
let ob = v.to_object(py);
|
||||
let dict2 = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert_eq!(1, dict2.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -174,9 +178,10 @@ mod test {
|
|||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert_eq!(true, dict.contains(py, 7i32).unwrap());
|
||||
assert_eq!(false, dict.contains(py, 8i32).unwrap());
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert_eq!(true, dict.contains(7i32).unwrap());
|
||||
assert_eq!(false, dict.contains(8i32).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -185,9 +190,10 @@ mod test {
|
|||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert_eq!(32, dict.get_item(py, 7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(None, dict.get_item(py, 8i32));
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert_eq!(32, dict.get_item(7i32).unwrap().extract::<i32>().unwrap());
|
||||
assert_eq!(None, dict.get_item(8i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -196,11 +202,12 @@ mod test {
|
|||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert!(dict.set_item(py, 7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(py, 8i32, 123i32).is_ok()); // insert
|
||||
assert_eq!(42i32, dict.get_item(py, 7i32).unwrap().extract::<i32>(py).unwrap());
|
||||
assert_eq!(123i32, dict.get_item(py, 8i32).unwrap().extract::<i32>(py).unwrap());
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert!(dict.set_item(7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(8i32, 123i32).is_ok()); // insert
|
||||
assert_eq!(42i32, dict.get_item(7i32).unwrap().extract::<i32>().unwrap());
|
||||
assert_eq!(123i32, dict.get_item(8i32).unwrap().extract::<i32>().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -209,9 +216,10 @@ mod test {
|
|||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert!(dict.set_item(py, 7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(py, 8i32, 123i32).is_ok()); // insert
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert!(dict.set_item(7i32, 42i32).is_ok()); // change
|
||||
assert!(dict.set_item(8i32, 123i32).is_ok()); // insert
|
||||
assert_eq!(32i32, *v.get(&7i32).unwrap()); // not updated!
|
||||
assert_eq!(None, v.get(&8i32));
|
||||
}
|
||||
|
@ -223,10 +231,11 @@ mod test {
|
|||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert!(dict.del_item(py, 7i32).is_ok());
|
||||
assert_eq!(0, dict.len(py));
|
||||
assert_eq!(None, dict.get_item(py, 7i32));
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert!(dict.del_item(7i32).is_ok());
|
||||
assert_eq!(0, dict.len());
|
||||
assert_eq!(None, dict.get_item(7i32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -235,12 +244,13 @@ mod test {
|
|||
let py = gil.python();
|
||||
let mut v = HashMap::new();
|
||||
v.insert(7, 32);
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
assert!(dict.del_item(py, 7i32).is_ok()); // change
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
assert!(dict.del_item(7i32).is_ok()); // change
|
||||
assert_eq!(32i32, *v.get(&7i32).unwrap()); // not updated!
|
||||
}
|
||||
|
||||
#[test]
|
||||
/*#[test]
|
||||
fn test_items_list() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
@ -259,7 +269,7 @@ mod test {
|
|||
}
|
||||
assert_eq!(7 + 8 + 9, key_sum);
|
||||
assert_eq!(32 + 42 + 123, value_sum);
|
||||
}
|
||||
}*/
|
||||
|
||||
#[test]
|
||||
fn test_items() {
|
||||
|
@ -269,13 +279,14 @@ mod test {
|
|||
v.insert(7, 32);
|
||||
v.insert(8, 42);
|
||||
v.insert(9, 123);
|
||||
let dict = PyDict::downcast_from(py, v.to_py_object(py)).unwrap();
|
||||
let ob = v.to_object(py);
|
||||
let dict = PyDict::downcast_from(ob.as_object(py)).unwrap();
|
||||
// Can't just compare against a vector of tuples since we don't have a guaranteed ordering.
|
||||
let mut key_sum = 0;
|
||||
let mut value_sum = 0;
|
||||
for (key, value) in dict.items(py) {
|
||||
key_sum += key.extract::<i32>(py).unwrap();
|
||||
value_sum += value.extract::<i32>(py).unwrap();
|
||||
for (key, value) in dict.items() {
|
||||
key_sum += key.extract::<i32>().unwrap();
|
||||
value_sum += value.extract::<i32>().unwrap();
|
||||
}
|
||||
assert_eq!(7 + 8 + 9, key_sum);
|
||||
assert_eq!(32 + 42 + 123, value_sum);
|
||||
|
@ -289,12 +300,14 @@ mod test {
|
|||
let mut map = HashMap::<i32, i32>::new();
|
||||
map.insert(1, 1);
|
||||
|
||||
let py_map = PyDict::downcast_from(py, map.to_py_object(py)).unwrap();
|
||||
let m = map.to_object(py);
|
||||
let py_map = PyDict::downcast_from(m.as_object(py)).unwrap();
|
||||
|
||||
assert!(py_map.len(py) == 1);
|
||||
assert!( py_map.get_item(py, 1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
assert!(py_map.len() == 1);
|
||||
assert!( py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_btreemap_to_python() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
@ -302,9 +315,10 @@ mod test {
|
|||
let mut map = BTreeMap::<i32, i32>::new();
|
||||
map.insert(1, 1);
|
||||
|
||||
let py_map = PyDict::downcast_from(py, map.to_py_object(py)).unwrap();
|
||||
let m = map.to_object(py);
|
||||
let py_map = PyDict::downcast_from(m.as_object(py)).unwrap();
|
||||
|
||||
assert!(py_map.len(py) == 1);
|
||||
assert!( py_map.get_item(py, 1).unwrap().extract::<i32>(py).unwrap() == 1);
|
||||
assert!(py_map.len() == 1);
|
||||
assert!( py_map.get_item(1).unwrap().extract::<i32>().unwrap() == 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,6 @@ pub use self::slice::PySlice;
|
|||
macro_rules! pyobject_nativetype(
|
||||
($name: ident, $checkfunction: ident, $typeobject: ident) => (
|
||||
|
||||
impl<'p> $crate::native::PyNativeObject for $name<'p> {
|
||||
fn into_object(self) -> $crate::PyPtr<$crate::PyObjectMarker> {
|
||||
unsafe { $crate::std::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> $crate::typeob::PyTypeInfo for $name<'p> {
|
||||
type Type = ();
|
||||
|
||||
|
@ -49,8 +43,19 @@ macro_rules! pyobject_nativetype(
|
|||
}
|
||||
}
|
||||
|
||||
impl<'p> $crate::token::PythonObjectWithToken for $name<'p> {
|
||||
fn token<'a>(&'a self) -> $crate::python::Python<'a> {
|
||||
impl<'p> $crate::native::PyBaseObject for $name<'p> {}
|
||||
|
||||
impl<'p> $crate::native::PyNativeObject<'p> for $name<'p> {
|
||||
fn as_object(self) -> $crate::PyObject<'p> {
|
||||
unsafe { $crate::std::mem::transmute(self) }
|
||||
}
|
||||
fn into_object(self) -> $crate::PyPtr<$crate::PyObjectMarker> {
|
||||
unsafe { $crate::std::mem::transmute(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'p> $crate::token::PythonObjectWithGilToken<'p> for $name<'p> {
|
||||
fn gil(&self) -> $crate::python::Python<'p> {
|
||||
self.0.token()
|
||||
}
|
||||
}
|
||||
|
@ -60,14 +65,14 @@ macro_rules! pyobject_nativetype(
|
|||
fn downcast_from(py: &'p $crate::PyObject<'p>)
|
||||
-> Result<&'p $name<'p>, $crate::PyDowncastError<'p>>
|
||||
{
|
||||
use $crate::{ToPythonPointer, PythonObjectWithToken};
|
||||
use $crate::{ToPythonPointer, PythonObjectWithGilToken};
|
||||
|
||||
unsafe {
|
||||
if $crate::ffi::$checkfunction(py.as_ptr()) > 0 {
|
||||
let ptr = py as *const _ as *mut u8 as *mut $name;
|
||||
Ok(ptr.as_ref().unwrap())
|
||||
} else {
|
||||
Err($crate::PyDowncastError(py.token(), None))
|
||||
Err($crate::PyDowncastError(py.gil(), None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,12 +121,11 @@ macro_rules! pyobject_nativetype(
|
|||
{
|
||||
/// Extracts `Self` from the source `Py<PyObject>`.
|
||||
fn extract(py: &'a $crate::PyObject<'a>) -> $crate::PyResult<Self>
|
||||
//where S: $crate::typeob::PyTypeInfo
|
||||
{
|
||||
use $crate::token::PythonObjectWithToken;
|
||||
use $crate::token::PythonObjectWithGilToken;
|
||||
|
||||
Ok($name(
|
||||
$crate::pptr::cast_from_borrowed_ptr::<$name>(py.token(), py.as_ptr())?))
|
||||
$crate::pptr::cast_from_borrowed_ptr::<$name>(py.gil(), py.as_ptr())?))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -129,14 +133,13 @@ macro_rules! pyobject_nativetype(
|
|||
{
|
||||
/// Extracts `Self` from the source `PyObject`.
|
||||
fn extract(py: &'a $crate::PyObject<'a>) -> $crate::PyResult<Self>
|
||||
//where S: $crate::typeob::PyTypeInfo
|
||||
{
|
||||
unsafe {
|
||||
if ffi::$checkfunction(py.as_ptr()) != 0 {
|
||||
Ok($crate::std::mem::transmute(py))
|
||||
} else {
|
||||
Err($crate::PyDowncastError(
|
||||
$crate::token::PythonObjectWithToken::token(py), None).into())
|
||||
$crate::token::PythonObjectWithGilToken::gil(py), None).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -145,8 +148,8 @@ macro_rules! pyobject_nativetype(
|
|||
impl<'a> $crate::ToPyObject for $name<'a>
|
||||
{
|
||||
#[inline]
|
||||
default fn to_object<'p>(&self, _py: $crate::Python<'p>)
|
||||
-> $crate::PyPtr<$crate::PyObjectMarker> {
|
||||
fn to_object<'p>(&self, _py: $crate::Python<'p>)
|
||||
-> $crate::PyPtr<$crate::PyObjectMarker> {
|
||||
unsafe { $crate::PyPtr::from_borrowed_ptr(self.0.as_ptr()) }
|
||||
}
|
||||
|
||||
|
@ -168,12 +171,12 @@ macro_rules! pyobject_nativetype(
|
|||
}
|
||||
|
||||
impl<'p> $crate::std::fmt::Debug for $name<'p> {
|
||||
default fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||
-> Result<(), $crate::std::fmt::Error>
|
||||
fn fmt(&self, f: &mut $crate::std::fmt::Formatter)
|
||||
-> Result<(), $crate::std::fmt::Error>
|
||||
{
|
||||
use $crate::python::PyDowncastInto;
|
||||
|
||||
let py = <$name as $crate::token::PythonObjectWithToken>::token(self);
|
||||
let py = <$name as $crate::token::PythonObjectWithGilToken>::gil(self);
|
||||
let s = unsafe { $crate::PyString::downcast_from_owned_ptr(
|
||||
py, $crate::ffi::PyObject_Repr(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
|
@ -188,7 +191,7 @@ macro_rules! pyobject_nativetype(
|
|||
{
|
||||
use $crate::python::PyDowncastInto;
|
||||
|
||||
let py = <$name as $crate::token::PythonObjectWithToken>::token(self);
|
||||
let py = <$name as $crate::token::PythonObjectWithGilToken>::gil(self);
|
||||
let s = unsafe { $crate::PyString::downcast_from_owned_ptr(
|
||||
py, $crate::ffi::PyObject_Str(
|
||||
$crate::python::ToPythonPointer::as_ptr(self))) };
|
||||
|
|
|
@ -10,7 +10,7 @@ use std::ffi::{CStr, CString};
|
|||
use ::pptr;
|
||||
use pyptr::PyPtr;
|
||||
use python::{ToPythonPointer, Python};
|
||||
use token::PythonObjectWithToken;
|
||||
use token::PythonObjectWithGilToken;
|
||||
use objects::{PyDict, PyType, exc};
|
||||
use objectprotocol::ObjectProtocol;
|
||||
use err::{PyResult, PyErr};
|
||||
|
@ -53,14 +53,14 @@ impl<'p> PyModule<'p> {
|
|||
|
||||
unsafe fn str_from_ptr<'a>(&'a self, ptr: *const c_char) -> PyResult<&'a str> {
|
||||
if ptr.is_null() {
|
||||
Err(PyErr::fetch(self.token()))
|
||||
Err(PyErr::fetch(self.gil()))
|
||||
} else {
|
||||
let slice = CStr::from_ptr(ptr).to_bytes();
|
||||
match std::str::from_utf8(slice) {
|
||||
Ok(s) => Ok(s),
|
||||
Err(e) => Err(PyErr::from_instance(
|
||||
self.token(),
|
||||
try!(exc::UnicodeDecodeError::new_utf8(self.token(), slice, e))))
|
||||
self.gil(),
|
||||
try!(exc::UnicodeDecodeError::new_utf8(self.gil(), slice, e))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,15 +91,15 @@ impl<'p> PyModule<'p> {
|
|||
let type_name = <T as ::typeob::PyTypeInfo>::type_name();
|
||||
|
||||
let ty = if (ty.tp_flags & ffi::Py_TPFLAGS_READY) != 0 {
|
||||
unsafe { PyType::from_type_ptr(self.token(), ty) }
|
||||
unsafe { PyType::from_type_ptr(self.gil(), ty) }
|
||||
} else {
|
||||
// automatically initialize the class
|
||||
let name = self.name()?;
|
||||
::typeob::initialize_type::<T>(self.token(), Some(name), type_name, ty)
|
||||
::typeob::initialize_type::<T>(self.gil(), Some(name), type_name, ty)
|
||||
.expect(
|
||||
format!("An error occurred while initializing class {}",
|
||||
<T as ::typeob::PyTypeInfo>::type_name()).as_ref());
|
||||
unsafe { PyType::from_type_ptr(self.token(), ty) }
|
||||
unsafe { PyType::from_type_ptr(self.gil(), ty) }
|
||||
};
|
||||
|
||||
self.setattr(type_name, ty)
|
||||
|
|
|
@ -11,7 +11,7 @@ use ::{PyPtr, pptr};
|
|||
use ffi;
|
||||
use super::exc;
|
||||
use objects::PyObject;
|
||||
use token::{PyObjectMarker, PythonObjectWithToken};
|
||||
use token::{PyObjectMarker, PythonObjectWithGilToken};
|
||||
use python::{ToPythonPointer, Python};
|
||||
use err::{PyResult, PyErr};
|
||||
use conversion::{ToPyObject, FromPyObject, IntoPyObject};
|
||||
|
@ -62,12 +62,12 @@ macro_rules! int_fits_c_long(
|
|||
|
||||
pyobject_extract!(obj to $rust_type => {
|
||||
let val = unsafe { ffi::PyLong_AsLong(obj.as_ptr()) };
|
||||
if val == -1 && PyErr::occurred(obj.token()) {
|
||||
return Err(PyErr::fetch(obj.token()));
|
||||
if val == -1 && PyErr::occurred(obj.gil()) {
|
||||
return Err(PyErr::fetch(obj.gil()));
|
||||
}
|
||||
match cast::<c_long, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
None => Err(overflow_error(obj.token()))
|
||||
None => Err(overflow_error(obj.gil()))
|
||||
}
|
||||
});
|
||||
)
|
||||
|
@ -84,7 +84,7 @@ macro_rules! int_fits_larger_int(
|
|||
}
|
||||
|
||||
pyobject_extract!(obj to $rust_type => {
|
||||
let py = obj.token();
|
||||
let py = obj.gil();
|
||||
let val = try!(obj.extract::<$larger_type>());
|
||||
match cast::<$larger_type, $rust_type>(val) {
|
||||
Some(v) => Ok(v),
|
||||
|
@ -123,13 +123,13 @@ macro_rules! int_convert_u64_or_i64 (
|
|||
let ptr = py.as_ptr();
|
||||
unsafe {
|
||||
if ffi::PyLong_Check(ptr) != 0 {
|
||||
err_if_invalid_value(py.token(), !0, $pylong_as_ull_or_ull(ptr))
|
||||
err_if_invalid_value(py.gil(), !0, $pylong_as_ull_or_ull(ptr))
|
||||
} else {
|
||||
let num = ffi::PyNumber_Long(ptr);
|
||||
if num.is_null() {
|
||||
Err(PyErr::fetch(py.token()))
|
||||
Err(PyErr::fetch(py.gil()))
|
||||
} else {
|
||||
err_if_invalid_value(py.token(), !0, $pylong_as_ull_or_ull(num))
|
||||
err_if_invalid_value(py.gil(), !0, $pylong_as_ull_or_ull(num))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -176,8 +176,8 @@ impl ToPyObject for f64 {
|
|||
|
||||
pyobject_extract!(obj to f64 => {
|
||||
let v = unsafe { ffi::PyFloat_AsDouble(obj.as_ptr()) };
|
||||
if v == -1.0 && PyErr::occurred(obj.token()) {
|
||||
Err(PyErr::fetch(obj.token()))
|
||||
if v == -1.0 && PyErr::occurred(obj.gil()) {
|
||||
Err(PyErr::fetch(obj.gil()))
|
||||
} else {
|
||||
Ok(v)
|
||||
}
|
||||
|
@ -210,8 +210,8 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let val = 123 as $t1;
|
||||
let obj = val.to_object(py).into_object();
|
||||
assert_eq!(obj.extract::<$t2>(py).unwrap(), val as $t2);
|
||||
let obj = val.to_object(py).into_object(py);
|
||||
assert_eq!(obj.extract::<$t2>().unwrap(), val as $t2);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -239,10 +239,10 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = std::u32::MAX;
|
||||
let obj = v.to_py_object(py).into_object();
|
||||
assert_eq!(v, obj.extract::<u32>(py).unwrap());
|
||||
assert_eq!(v as u64, obj.extract::<u64>(py).unwrap());
|
||||
assert!(obj.extract::<i32>(py).is_err());
|
||||
let obj = v.to_object(py).into_object(py);
|
||||
assert_eq!(v, obj.extract::<u32>().unwrap());
|
||||
assert_eq!(v as u64, obj.extract::<u64>().unwrap());
|
||||
assert!(obj.extract::<i32>().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -250,10 +250,10 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = std::i64::MAX;
|
||||
let obj = v.to_py_object(py).into_object();
|
||||
assert_eq!(v, obj.extract::<i64>(py).unwrap());
|
||||
assert_eq!(v as u64, obj.extract::<u64>(py).unwrap());
|
||||
assert!(obj.extract::<u32>(py).is_err());
|
||||
let obj = v.to_object(py).into_object(py);
|
||||
assert_eq!(v, obj.extract::<i64>().unwrap());
|
||||
assert_eq!(v as u64, obj.extract::<u64>().unwrap());
|
||||
assert!(obj.extract::<u32>().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -261,10 +261,10 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = std::i64::MIN;
|
||||
let obj = v.to_py_object(py).into_object();
|
||||
assert_eq!(v, obj.extract::<i64>(py).unwrap());
|
||||
assert!(obj.extract::<i32>(py).is_err());
|
||||
assert!(obj.extract::<u64>(py).is_err());
|
||||
let obj = v.to_object(py).into_object(py);
|
||||
assert_eq!(v, obj.extract::<i64>().unwrap());
|
||||
assert!(obj.extract::<i32>().is_err());
|
||||
assert!(obj.extract::<u64>().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -272,9 +272,8 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let v = std::u64::MAX;
|
||||
let obj = v.to_py_object(py).into_object();
|
||||
println!("{:?}", obj);
|
||||
assert_eq!(v, obj.extract::<u64>(py).unwrap());
|
||||
assert!(obj.extract::<i64>(py).is_err());
|
||||
let obj = v.to_object(py).into_object(py);
|
||||
assert_eq!(v, obj.extract::<u64>().unwrap());
|
||||
assert!(obj.extract::<i64>().is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@ use ::pptr;
|
|||
use ffi;
|
||||
use err::{PyResult, PyDowncastError};
|
||||
use python::{Python, ToPythonPointer};
|
||||
use token::PythonObjectWithToken;
|
||||
use typeob::PyTypeInfo;
|
||||
|
||||
|
||||
pub struct PyObject<'p>(pptr<'p>);
|
||||
|
@ -69,8 +67,6 @@ impl<'p> PyObject<'p> {
|
|||
/// 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
|
||||
//{
|
||||
where D: ::PyDowncastFrom<'p>
|
||||
{
|
||||
<D as ::PyDowncastFrom>::downcast_from(&self)
|
||||
|
|
|
@ -8,7 +8,7 @@ use python::{ToPythonPointer, Python};
|
|||
use err::{PyErr, PyResult};
|
||||
use ffi::{self, Py_ssize_t};
|
||||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use token::{PyObjectMarker, PythonObjectWithToken};
|
||||
use token::{PyObjectMarker, PythonObjectWithGilToken};
|
||||
|
||||
/// Represents a Python `slice` indices
|
||||
pub struct PySliceIndices {
|
||||
|
@ -71,7 +71,7 @@ impl<'p> PySlice<'p> {
|
|||
slicelength: slicelen,
|
||||
})
|
||||
} else {
|
||||
Err(PyErr::fetch(self.token()))
|
||||
Err(PyErr::fetch(self.gil()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,11 +8,11 @@ use std::ascii::AsciiExt;
|
|||
use std::borrow::Cow;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use ::{Py, PyPtr, pptr};
|
||||
use ::{PyPtr, pptr};
|
||||
use ffi;
|
||||
use python::{ToPythonPointer, Python};
|
||||
use super::{exc, PyObject};
|
||||
use token::{PyObjectMarker, PythonObjectWithToken};
|
||||
use token::{PyObjectMarker, PythonObjectWithGilToken};
|
||||
use err::{PyResult, PyErr};
|
||||
use conversion::{ToPyObject, IntoPyObject, RefFromPyObject};
|
||||
|
||||
|
@ -153,7 +153,7 @@ impl<'p> PyString<'p> {
|
|||
unsafe {
|
||||
Ok(PyString(
|
||||
pptr::from_owned_ptr_or_err(
|
||||
src.token(), ffi::PyUnicode_FromEncodedObject(
|
||||
src.gil(), ffi::PyUnicode_FromEncodedObject(
|
||||
src.as_ptr(),
|
||||
encoding.as_ptr() as *const i8,
|
||||
errors.as_ptr() as *const i8))?))
|
||||
|
@ -168,7 +168,7 @@ impl<'p> PyString<'p> {
|
|||
let mut size : ffi::Py_ssize_t = mem::uninitialized();
|
||||
let data = ffi::PyUnicode_AsUTF8AndSize(self.0.as_ptr(), &mut size) as *const u8;
|
||||
if data.is_null() {
|
||||
PyErr::fetch(self.token()).print(self.token());
|
||||
PyErr::fetch(self.gil()).print(self.gil());
|
||||
panic!("PyUnicode_AsUTF8AndSize failed");
|
||||
}
|
||||
PyStringData::Utf8(std::slice::from_raw_parts(data, size as usize))
|
||||
|
@ -180,7 +180,7 @@ impl<'p> PyString<'p> {
|
|||
/// Returns a `UnicodeDecodeError` if the input is not valid unicode
|
||||
/// (containing unpaired surrogates).
|
||||
pub fn to_string(&self) -> PyResult<Cow<str>> {
|
||||
self.data().to_string(self.token())
|
||||
self.data().to_string(self.gil())
|
||||
}
|
||||
|
||||
/// Convert the `PyString` into a Rust string.
|
||||
|
@ -259,10 +259,10 @@ pyobject_extract!(obj to String => {
|
|||
|
||||
|
||||
impl<'p> RefFromPyObject<'p> for str {
|
||||
fn with_extracted<F, R>(obj: &'p Py<'p, PyObject>, f: F) -> PyResult<R>
|
||||
fn with_extracted<F, R>(obj: &'p PyObject, f: F) -> PyResult<R>
|
||||
where F: FnOnce(&str) -> R
|
||||
{
|
||||
let p = PyObject::from_borrowed_ptr(obj.token(), obj.as_ptr());
|
||||
let p = PyObject::from_borrowed_ptr(obj.gil(), obj.as_ptr());
|
||||
let s = try!(p.extract::<Cow<str>>());
|
||||
Ok(f(&s))
|
||||
}
|
||||
|
@ -278,8 +278,8 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let s = "\u{1F30F}";
|
||||
let py_string = s.to_py_object(py).into_object();
|
||||
assert_eq!(s, py_string.extract::<String>(py).unwrap());
|
||||
let py_string = s.to_object(py);
|
||||
assert_eq!(s, py_string.as_object(py).extract::<String>().unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -287,9 +287,9 @@ mod test {
|
|||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let s = "Hello Python";
|
||||
let py_string = s.to_py_object(py).into_object();
|
||||
let py_string = s.to_object(py);
|
||||
let mut called = false;
|
||||
RefFromPyObject::with_extracted(py, &py_string,
|
||||
RefFromPyObject::with_extracted(&py_string.as_object(py),
|
||||
|s2: &str| {
|
||||
assert_eq!(s, s2);
|
||||
called = true;
|
||||
|
|
|
@ -10,7 +10,7 @@ use err::{PyErr, PyResult};
|
|||
use python::{Python, ToPythonPointer, IntoPythonPointer};
|
||||
use conversion::{FromPyObject, ToPyObject, ToPyTuple, IntoPyObject};
|
||||
use objects::PyObject;
|
||||
use token::{PyObjectMarker, PythonObjectWithToken};
|
||||
use token::{PyObjectMarker, PythonObjectWithGilToken};
|
||||
use super::exc;
|
||||
|
||||
/// Represents a Python tuple object.
|
||||
|
@ -63,7 +63,7 @@ impl<'p> PyTuple<'p> {
|
|||
assert!(index < self.len());
|
||||
unsafe {
|
||||
PyObject::from_owned_ptr(
|
||||
self.token(), ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t))
|
||||
self.gil(), ffi::PyTuple_GET_ITEM(self.as_ptr(), index as Py_ssize_t))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +134,7 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
|
|||
$( try!(slice[$n].extract::<$T>()), )+
|
||||
))
|
||||
} else {
|
||||
Err(wrong_tuple_length(obj.token(), t, $length))
|
||||
Err(wrong_tuple_length(obj.gil(), t, $length))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ pyobject_extract!(obj to NoArgs => {
|
|||
if t.len() == 0 {
|
||||
Ok(NoArgs)
|
||||
} else {
|
||||
Err(wrong_tuple_length(obj.token(), t, 0))
|
||||
Err(wrong_tuple_length(obj.gil(), t, 0))
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -210,16 +210,17 @@ pyobject_extract!(obj to NoArgs => {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use PyTuple;
|
||||
use python::{Python, PythonObjectWithCheckedDowncast};
|
||||
use python::{Python, PyDowncastInto};
|
||||
use conversion::IntoPyObject;
|
||||
use conversion::ToPyObject;
|
||||
|
||||
#[test]
|
||||
fn test_len() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
let tuple = PyTuple::downcast_from(py, (1, 2, 3).to_py_object(py)).unwrap();
|
||||
assert_eq!(3, tuple.len(py));
|
||||
assert_eq!((1, 2, 3), tuple.into_object().extract(py).unwrap());
|
||||
let tuple = PyTuple::downcast_into(py, (1, 2, 3).to_object(py).into_object(py)).unwrap();
|
||||
assert_eq!(3, tuple.len());
|
||||
assert_eq!((1, 2, 3), tuple.into_object(py).as_object(py).extract().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::borrow::Cow;
|
|||
|
||||
use ::pptr;
|
||||
use ffi;
|
||||
use token::PythonObjectWithToken;
|
||||
use token::PythonObjectWithGilToken;
|
||||
use python::{Python, ToPythonPointer};
|
||||
use conversion::ToPyTuple;
|
||||
use objects::{PyObject, PyDict};
|
||||
|
@ -59,10 +59,10 @@ impl<'p> PyType<'p> {
|
|||
pub fn call<A>(&'p self, args: A, kwargs: Option<&PyDict>) -> PyResult<PyObject<'p>>
|
||||
where A: ToPyTuple
|
||||
{
|
||||
let args = args.to_py_tuple(self.token());
|
||||
let args = args.to_py_tuple(self.gil());
|
||||
unsafe {
|
||||
PyObject::from_owned_ptr_or_err(
|
||||
self.token(), ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs.as_ptr()))
|
||||
self.gil(), ffi::PyObject_Call(self.as_ptr(), args.as_ptr(), kwargs.as_ptr()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use err::{PyErr, PyResult};
|
|||
use python::{Python, ToPythonPointer};
|
||||
use typeob::{PyTypeInfo, PyObjectAlloc};
|
||||
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct pptr<'p>(Python<'p>, *mut ffi::PyObject);
|
||||
|
||||
|
||||
|
|
35
src/pyptr.rs
35
src/pyptr.rs
|
@ -10,7 +10,7 @@ use err::{PyErr, PyResult, PyDowncastError};
|
|||
use conversion::{ToPyObject, IntoPyObject};
|
||||
use objects::PyObject;
|
||||
use python::{Python, ToPythonPointer, IntoPythonPointer};
|
||||
use token::{PyObjectMarker, PythonObjectWithToken};
|
||||
use token::{PyObjectMarker, PythonObjectWithGilToken};
|
||||
use typeob::{PyTypeInfo, PyObjectAlloc};
|
||||
|
||||
|
||||
|
@ -104,12 +104,25 @@ impl<T> PyPtr<T> {
|
|||
/// Converts PyPtr<T> -> PyPtr<PyObject>
|
||||
/// Consumes `self` without calling `Py_INCREF()`
|
||||
#[inline]
|
||||
pub fn into_object(self) -> PyPtr<PyObjectMarker> {
|
||||
pub fn park(self) -> PyPtr<PyObjectMarker> {
|
||||
let p = PyPtr {inner: self.inner, _t: PhantomData};
|
||||
std::mem::forget(self);
|
||||
p
|
||||
}
|
||||
|
||||
/// Converts PyPtr<T> -> &PyObject<'p>.
|
||||
#[inline]
|
||||
pub fn as_object<'p>(&self, _py: Python<'p>) -> &PyObject<'p> {
|
||||
unsafe { std::mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Converts PyPtr<T> -> PyObject<'p>
|
||||
/// Consumes `self` without calling `Py_DECREF()`
|
||||
#[inline]
|
||||
pub fn into_object<'p>(self, _py: Python<'p>) -> PyObject<'p> {
|
||||
unsafe { std::mem::transmute(self) }
|
||||
}
|
||||
|
||||
/// Gets the reference count of this PyPtr object.
|
||||
#[inline]
|
||||
pub fn get_refcnt(&self) -> usize {
|
||||
|
@ -171,7 +184,7 @@ impl<T> IntoPyObject for PyPtr<T> {
|
|||
|
||||
#[inline]
|
||||
fn into_object<'a>(self, _py: Python) -> PyPtr<PyObjectMarker> {
|
||||
self.into_object()
|
||||
self.park()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -326,12 +339,14 @@ impl<'p, T> Py<'p, T>
|
|||
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}
|
||||
}
|
||||
|
||||
pub fn token<'a>(&'a self) -> Python<'p> {
|
||||
#[inline]
|
||||
pub fn gil(&self) -> Python<'p> {
|
||||
self.py
|
||||
}
|
||||
}
|
||||
|
@ -375,6 +390,7 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn cast_from_owned_or_err(py: Python<'p>, ptr: *mut ffi::PyObject)
|
||||
-> PyResult<Py<'p, T>>
|
||||
{
|
||||
|
@ -460,7 +476,7 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
let ptr = (self.inner as *mut u8).offset(offset) as *mut D;
|
||||
ptr.as_ref().unwrap() })
|
||||
} else {
|
||||
Err(PyDowncastError(self.token(), None))
|
||||
Err(PyDowncastError(self.py, None))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -483,8 +499,8 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
|
|||
}
|
||||
}
|
||||
|
||||
//impl<'p, T> PythonObjectWithToken for Py<'p, T> {
|
||||
// fn token(&self) -> Token {
|
||||
//impl<'p, T> PythonObjectWithGilToken<'p> for Py<'p, T> {
|
||||
// fn gil(&self) -> Python<'p> {
|
||||
// self.py
|
||||
// }
|
||||
//}
|
||||
|
@ -575,14 +591,13 @@ impl<'source, T> ::FromPyObject<'source> for Py<'source, T> where T: PyTypeInfo
|
|||
{
|
||||
#[inline]
|
||||
default fn extract(py: &'source PyObject<'source>) -> PyResult<Py<'source, T>>
|
||||
// where S: PyTypeInfo
|
||||
{
|
||||
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.token(), ptr) })
|
||||
Ok( unsafe { Py::<T>::from_borrowed_ptr(py.gil(), ptr) })
|
||||
} else {
|
||||
Err(PyDowncastError(py.token(), None).into())
|
||||
Err(PyDowncastError(py.gil(), None).into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::os::raw::c_int;
|
|||
|
||||
use ffi;
|
||||
use typeob::{PyTypeInfo, PyTypeObject, PyObjectAlloc};
|
||||
use token::{PyObjectMarker, PythonToken, PythonObjectWithToken};
|
||||
use token::{PyObjectMarker, PythonToken, PythonObjectWithGilToken};
|
||||
use objects::{PyObject, PyType, PyBool, PyDict, PyModule};
|
||||
use err::{PyErr, PyResult, PyDowncastError};
|
||||
use pyptr::{Py, PyPtr};
|
||||
|
@ -73,16 +73,6 @@ pub trait ToPythonPointer {
|
|||
|
||||
}
|
||||
|
||||
impl<'p, T> ToPythonPointer for T where T: PyTypeInfo + PythonObjectWithToken {
|
||||
#[inline]
|
||||
default fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
let offset = <T as PyTypeInfo>::offset();
|
||||
unsafe {
|
||||
{self as *const _ as *mut u8}.offset(-offset) as *mut ffi::PyObject
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait allows retrieving the underlying FFI pointer from Python objects.
|
||||
pub trait IntoPythonPointer {
|
||||
/// Retrieves the underlying FFI pointer. Whether pointer owned or borrowed
|
||||
|
@ -94,7 +84,7 @@ pub trait IntoPythonPointer {
|
|||
/// Convert None into a null pointer.
|
||||
/*impl <T> ToPythonPointer for Option<T> where T: ToPythonPointer {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
default fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
match *self {
|
||||
Some(ref t) => t.as_ptr(),
|
||||
None => std::ptr::null_mut()
|
||||
|
@ -105,7 +95,7 @@ pub trait IntoPythonPointer {
|
|||
/// Convert None into a null pointer.
|
||||
impl<'p, T> ToPythonPointer for Option<&'p T> where T: ToPythonPointer {
|
||||
#[inline]
|
||||
fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
default fn as_ptr(&self) -> *mut ffi::PyObject {
|
||||
match *self {
|
||||
Some(ref t) => t.as_ptr(),
|
||||
None => std::ptr::null_mut()
|
||||
|
@ -303,18 +293,18 @@ mod test {
|
|||
let py = gil.python();
|
||||
|
||||
// Make sure builtin names are accessible
|
||||
let v: i32 = py.eval("min(1, 2)", None, None).unwrap().extract(py).unwrap();
|
||||
let v: i32 = py.eval("min(1, 2)", None, None).unwrap().extract().unwrap();
|
||||
assert_eq!(v, 1);
|
||||
|
||||
let d = PyDict::new(py);
|
||||
d.set_item(py, "foo", 13).unwrap();
|
||||
d.set_item("foo", 13).unwrap();
|
||||
|
||||
// Inject our own local namespace
|
||||
let v: i32 = py.eval("foo + 29", None, Some(&d)).unwrap().extract(py).unwrap();
|
||||
let v: i32 = py.eval("foo + 29", None, Some(&d)).unwrap().extract().unwrap();
|
||||
assert_eq!(v, 42);
|
||||
|
||||
// Make sure builtin names are still accessible when using a local namespace
|
||||
let v: i32 = py.eval("min(foo, 2)", None, Some(&d)).unwrap().extract(py).unwrap();
|
||||
let v: i32 = py.eval("min(foo, 2)", None, Some(&d)).unwrap().extract().unwrap();
|
||||
assert_eq!(v, 2);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,15 +33,16 @@ pub fn with_token<'p, T, F>(py: Python<'p>, f: F) -> Py<'p, T>
|
|||
}
|
||||
|
||||
|
||||
pub trait PythonObjectWithGilToken<'p> : Sized {
|
||||
fn gil(&self) -> Python<'p>;
|
||||
}
|
||||
|
||||
pub trait PythonObjectWithToken : Sized {
|
||||
fn token<'p>(&'p self) -> Python<'p>;
|
||||
}
|
||||
|
||||
|
||||
pub struct PyObjectMarker;
|
||||
|
||||
//pyobject_newtype!(PyObject, PyObject_Check, PyBaseObject_Type);
|
||||
|
||||
|
||||
impl PyObjectMarker {
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(dead_code, unused_variables)]
|
||||
#![feature(proc_macro, specialization)]
|
||||
|
||||
#[macro_use] extern crate pyo3;
|
||||
extern crate pyo3;
|
||||
|
||||
use std::ptr;
|
||||
use std::os::raw::{c_int, c_void};
|
||||
|
|
|
@ -804,8 +804,8 @@ impl PyObjectProtocol for RichComparisons2 {
|
|||
fn __richcmp__(&self, py: Python,
|
||||
other: &'p PyObject<'p>, op: CompareOp) -> PyResult<PyPtr<PyObjectMarker>> {
|
||||
match op {
|
||||
CompareOp::Eq => Ok(true.to_object(py).into_object()),
|
||||
CompareOp::Ne => Ok(false.to_object(py).into_object()),
|
||||
CompareOp::Eq => Ok(true.to_object(py).park()),
|
||||
CompareOp::Ne => Ok(false.to_object(py).park()),
|
||||
_ => Ok(py.NotImplemented())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,16 +17,16 @@ fn no_args() {
|
|||
let obj = py_fn!(py, f());
|
||||
|
||||
assert_eq!(CALL_COUNT.load(Relaxed), 0);
|
||||
assert_eq!(obj.call(py, NoArgs, None).unwrap().extract::<i32>(py).unwrap(), 0);
|
||||
assert_eq!(obj.call(py, NoArgs, None).unwrap().extract::<i32>(py).unwrap(), 1);
|
||||
assert_eq!(obj.call(NoArgs, None).unwrap().extract::<i32>().unwrap(), 0);
|
||||
assert_eq!(obj.call(NoArgs, None).unwrap().extract::<i32>().unwrap(), 1);
|
||||
assert_eq!(CALL_COUNT.load(Relaxed), 2);
|
||||
assert!(obj.call(py, (1,), None).is_err());
|
||||
assert!(obj.call((1,), None).is_err());
|
||||
assert_eq!(CALL_COUNT.load(Relaxed), 2);
|
||||
assert_eq!(obj.call(py, NoArgs, Some(&PyDict::new(py))).unwrap().extract::<i32>(py).unwrap(), 2);
|
||||
assert_eq!(obj.call(NoArgs, Some(&PyDict::new(py))).unwrap().extract::<i32>().unwrap(), 2);
|
||||
assert_eq!(CALL_COUNT.load(Relaxed), 3);
|
||||
let dict = PyDict::new(py);
|
||||
dict.set_item(py, "param", 42).unwrap();
|
||||
assert!(obj.call(py, NoArgs, Some(&dict)).is_err());
|
||||
dict.set_item("param", 42).unwrap();
|
||||
assert!(obj.call(NoArgs, Some(&dict)).is_err());
|
||||
assert_eq!(CALL_COUNT.load(Relaxed), 3);
|
||||
}
|
||||
|
||||
|
@ -40,16 +40,16 @@ fn one_arg() {
|
|||
let py = gil.python();
|
||||
let obj = py_fn!(py, f(i: usize));
|
||||
|
||||
assert!(obj.call(py, NoArgs, None).is_err());
|
||||
assert_eq!(obj.call(py, (1,), None).unwrap().extract::<i32>(py).unwrap(), 2);
|
||||
assert!(obj.call(py, (1, 2), None).is_err());
|
||||
assert!(obj.call(NoArgs, None).is_err());
|
||||
assert_eq!(obj.call((1,), None).unwrap().extract::<i32>().unwrap(), 2);
|
||||
assert!(obj.call((1, 2), None).is_err());
|
||||
|
||||
let dict = PyDict::new(py);
|
||||
dict.set_item(py, "i", 42).unwrap();
|
||||
assert_eq!(obj.call(py, NoArgs, Some(&dict)).unwrap().extract::<i32>(py).unwrap(), 84);
|
||||
assert!(obj.call(py, (1,), Some(&dict)).is_err());
|
||||
dict.set_item(py, "j", 10).unwrap();
|
||||
assert!(obj.call(py, NoArgs, Some(&dict)).is_err());
|
||||
dict.set_item("i", 42).unwrap();
|
||||
assert_eq!(obj.call(NoArgs, Some(&dict)).unwrap().extract::<i32>().unwrap(), 84);
|
||||
assert!(obj.call((1,), Some(&dict)).is_err());
|
||||
dict.set_item("j", 10).unwrap();
|
||||
assert!(obj.call(NoArgs, Some(&dict)).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -61,8 +61,8 @@ fn inline_two_args() {
|
|||
Ok(a * b)
|
||||
});
|
||||
|
||||
assert!(obj.call(py, NoArgs, None).is_err());
|
||||
assert_eq!(obj.call(py, (6, 7), None).unwrap().extract::<i32>(py).unwrap(), 42);
|
||||
assert!(obj.call(NoArgs, None).is_err());
|
||||
assert_eq!(obj.call((6, 7), None).unwrap().extract::<i32>().unwrap(), 42);
|
||||
}
|
||||
|
||||
/* TODO: reimplement flexible sig support
|
||||
|
|
Loading…
Reference in a new issue