fixed gil lifetime; pass py object into protocol methods

This commit is contained in:
Nikolay Kim 2017-05-26 14:43:28 -07:00
parent 48329a793d
commit d165dbe4d4
25 changed files with 769 additions and 492 deletions

View file

@ -69,12 +69,12 @@ fn impl_class(cls: &syn::Ident, base: &syn::Ident) -> Tokens {
}
}
//impl<'p> _pyo3::python::AsPy<'p> for &'p #cls {
// #[inline]
// fn py<'a>(&'a self) -> _pyo3::Python<'p> {
// unsafe { _pyo3::python::Python::assume_gil_acquired() }
// }
//}
impl<'p> _pyo3::python::AsPy<'p> for &'p #cls {
#[inline]
fn py<'a>(&'a self) -> _pyo3::Python<'p> {
unsafe { _pyo3::python::Python::assume_gil_acquired() }
}
}
impl<'p> _pyo3::python::AsPy<'p> for &'p mut #cls {
#[inline]

View file

@ -23,7 +23,7 @@ use ffi;
use pyptr::{Py};
use python::Python;
use objects::{PyObject, PyTuple, PyDict, PyString, exc};
use conversion::RefFromPyObject;
//use conversion::RefFromPyObject;
use err::{self, PyResult};
/// Description of a python parameter; used for `parse_args()`.
@ -103,7 +103,7 @@ pub fn parse_args<'p>(py: Python<'p>,
}
Ok(())
}
/*
/// This macro is used to parse a parameter list into a set of variables.
///
/// Syntax: `py_argparse!(py, fname, args, kwargs, (parameter-list) { body })`
@ -335,7 +335,7 @@ macro_rules! py_argparse_impl {
Err(e) => Err(e)
}
}};
}
}*/
// Like py_argparse_impl!(), but accepts `*mut ffi::PyObject` for $args and $kwargs.
#[macro_export]
@ -361,6 +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 {
@ -447,6 +448,7 @@ pub fn with_extracted_or_default<'p, P: ?Sized, R, F>(
None => f(default)
}
}
*/
#[cfg(test)]
mod test {

View file

@ -6,7 +6,7 @@ use libc;
use pyptr::Py;
use python::{Python, IntoPythonPointer};
use objects::exc;
use objects::{exc, PyObject};
use conversion::IntoPyObject;
use ffi::{self, Py_hash_t};
use err::{PyErr, PyResult};
@ -163,14 +163,6 @@ impl <T> CallbackConverter<T> for HashConverter
}
// very unsafe util for callbacks, maybe bug un rust compiler?
pub unsafe fn unref<'p, T>(p: Py<'p, T>) -> &Py<T> {
{&p as *const _}.as_ref().unwrap()
}
pub unsafe fn unref_r<'p, T>(p: &'p Py<'p, T>) -> &'p Py<T> {
{p as *const _}.as_ref().unwrap()
}
pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
where F: FnOnce(Python<'p>) -> PyResult<T>,
F: panic::UnwindSafe,
@ -200,15 +192,20 @@ pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
ret
}
pub unsafe fn handle_cb<F, T, C>(location: &str, _c: C, f: F) -> C::R
where F: FnOnce(Python) -> PyResult<T>,
#[allow(unused_mut)]
pub unsafe fn cb_unary<Slf, F, T, C>(location: &str,
slf: *mut ffi::PyObject, _c: C, f: F) -> C::R
where F: for<'p> FnOnce(Python<'p>, &'p mut Slf) -> PyResult<T>,
F: panic::UnwindSafe,
Slf: ::typeob::PyTypeInfo,
C: CallbackConverter<T>
{
let guard = AbortOnDrop(location);
let ret = panic::catch_unwind(|| {
let py = Python::assume_gil_acquired();
match f(py) {
let mut slf: Py<Slf> = Py::from_borrowed_ptr(py, slf);
match f(py, slf.as_mut()) {
Ok(val) => {
C::convert(val, py)
}
@ -229,7 +226,44 @@ pub unsafe fn handle_cb<F, T, C>(location: &str, _c: C, f: F) -> C::R
ret
}
fn handle_panic(_py: Python, _panic: &any::Any) {
#[allow(unused_mut)]
pub unsafe fn cb_binary<Slf, F, T, C>(location: &str,
slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject,
_c: C, f: F) -> C::R
where F: for<'p> FnOnce(Python<'p>, &'p mut Slf, Py<'p, PyObject>) -> PyResult<T>,
F: panic::UnwindSafe,
Slf: ::typeob::PyTypeInfo,
C: CallbackConverter<T>
{
let guard = AbortOnDrop(location);
let ret = panic::catch_unwind(|| {
let py = Python::assume_gil_acquired();
let mut slf: Py<Slf> = Py::from_borrowed_ptr(py, slf);
let arg = PyObject::from_borrowed_ptr(py, arg);
match f(py, slf.as_mut(), arg) {
Ok(val) => {
C::convert(val, py)
}
Err(e) => {
e.restore(py);
C::error_value()
}
}
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
handle_panic(Python::assume_gil_acquired(), err);
C::error_value()
}
};
mem::forget(guard);
ret
}
pub fn handle_panic(_py: Python, _panic: &any::Any) {
unsafe {
ffi::PyErr_SetString(ffi::PyExc_SystemError, "Rust panic\0".as_ptr() as *const i8);
}

View file

@ -8,6 +8,7 @@
use ffi;
use err::PyResult;
use python::Python;
use callback::PyObjectCallbackConverter;
use typeob::PyTypeInfo;
use class::methods::PyMethodDef;
@ -17,15 +18,19 @@ use class::methods::PyMethodDef;
#[allow(unused_variables)]
pub trait PyAsyncProtocol<'p>: PyTypeInfo + Sized + 'static {
fn __await__(&self) -> Self::Result where Self: PyAsyncAwaitProtocol<'p> {unimplemented!()}
fn __await__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyAsyncAwaitProtocol<'p> { unimplemented!() }
fn __aiter__(&self) -> Self::Result where Self: PyAsyncAiterProtocol<'p> {unimplemented!()}
fn __aiter__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyAsyncAiterProtocol<'p> { unimplemented!() }
fn __anext__(&self) -> Self::Result where Self: PyAsyncAnextProtocol<'p> {unimplemented!()}
fn __anext__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyAsyncAnextProtocol<'p> { unimplemented!() }
fn __aenter__(&self) -> Self::Result where Self: PyAsyncAenterProtocol<'p> {unimplemented!()}
fn __aenter__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyAsyncAenterProtocol<'p> { unimplemented!() }
fn __aexit__(&self,
fn __aexit__(&'p self, py: Python<'p>,
exc_type: Option<Self::ExcType>,
exc_value: Option<Self::ExcValue>,
traceback: Option<Self::Traceback>)
@ -119,11 +124,12 @@ impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncProtocol<'p>
}
}
impl<'p, T> PyAsyncAwaitProtocolImpl for T where T: PyAsyncAwaitProtocol<'p>
impl<T> PyAsyncAwaitProtocolImpl for T where T: for<'p> PyAsyncAwaitProtocol<'p>
{
#[inline]
fn am_await() -> Option<ffi::unaryfunc> {
py_unary_func!(PyAsyncAwaitProtocol, T::__await__, PyObjectCallbackConverter)
py_unary_func!(PyAsyncAwaitProtocol, T::__await__,
<T as PyAsyncAwaitProtocol>::Success, PyObjectCallbackConverter)
}
}
@ -139,11 +145,13 @@ impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncProtocol<'p>
}
}
impl<'p, T> PyAsyncAiterProtocolImpl for T where T: PyAsyncAiterProtocol<'p>
impl<T> PyAsyncAiterProtocolImpl for T where T: for<'p> PyAsyncAiterProtocol<'p>
{
#[inline]
fn am_aiter() -> Option<ffi::unaryfunc> {
py_unary_func!(PyAsyncAiterProtocol, T::__aiter__, PyObjectCallbackConverter)
py_unary_func!(PyAsyncAiterProtocol, T::__aiter__,
<T as PyAsyncAiterProtocol>::Success,
PyObjectCallbackConverter)
}
}
@ -159,11 +167,12 @@ impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncProtocol<'p>
}
}
impl<'p, T> PyAsyncAnextProtocolImpl for T where T: PyAsyncAnextProtocol<'p>
impl<T> PyAsyncAnextProtocolImpl for T where T: for<'p> PyAsyncAnextProtocol<'p>
{
#[inline]
fn am_anext() -> Option<ffi::unaryfunc> {
py_unary_func!(PyAsyncAnextProtocol, T::__anext__, PyObjectCallbackConverter)
py_unary_func!(PyAsyncAnextProtocol, T::__anext__,
<T as PyAsyncAnextProtocol>::Success, PyObjectCallbackConverter)
}
}

View file

@ -5,15 +5,16 @@
//! more information on python async support
//! https://docs.python.org/3/reference/datamodel.html#basic-customization
use std;
use std::os::raw::c_int;
use ::{Py, CompareOp};
use ffi;
use err::{PyErr, PyResult};
use python::{Python};
use python::{Python, IntoPythonPointer};
use objects::{exc, PyObject};
use typeob::PyTypeInfo;
use conversion::{ToPyObject, FromPyObject};
use conversion::{ToPyObject, FromPyObject, IntoPyObject};
use callback::{PyObjectCallbackConverter, HashConverter, UnitCallbackConverter,
BoolCallbackConverter};
use class::methods::PyMethodDef;
@ -28,29 +29,34 @@ use class::methods::PyMethodDef;
#[allow(unused_variables)]
pub trait PyObjectProtocol<'p>: PyTypeInfo + Sized + 'static {
fn __getattr__(&self, name: Self::Name)
fn __getattr__(&'p self, py: Python<'p>, name: Self::Name)
-> Self::Result where Self: PyObjectGetAttrProtocol<'p> {unimplemented!()}
fn __setattr__(&self, name: Self::Name, value: Self::Value)
fn __setattr__(&'p self, py: Python<'p>, name: Self::Name, value: Self::Value)
-> Self::Result where Self: PyObjectSetAttrProtocol<'p> {unimplemented!()}
fn __delattr__(&self, name: Self::Name)
fn __delattr__(&'p self, py: Python<'p>, name: Self::Name)
-> Self::Result where Self: PyObjectDelAttrProtocol<'p> {unimplemented!()}
fn __str__(&self) -> Self::Result where Self: PyObjectStrProtocol<'p> {unimplemented!()}
fn __str__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyObjectStrProtocol<'p> {unimplemented!()}
fn __repr__(&self) -> Self::Result where Self: PyObjectReprProtocol<'p> {unimplemented!()}
fn __repr__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyObjectReprProtocol<'p> {unimplemented!()}
fn __format__(&self, format_spec: Self::Format)
fn __format__(&'p self, py: Python<'p>, format_spec: Self::Format)
-> Self::Result where Self: PyObjectFormatProtocol<'p> {unimplemented!()}
fn __hash__(&self) -> Self::Result where Self: PyObjectHashProtocol<'p> {unimplemented!()}
fn __hash__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyObjectHashProtocol<'p> {unimplemented!()}
fn __bool__(&self) -> Self::Result where Self: PyObjectBoolProtocol<'p> {unimplemented!()}
fn __bool__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyObjectBoolProtocol<'p> {unimplemented!()}
fn __bytes__(&self) -> Self::Result where Self: PyObjectBytesProtocol<'p> {unimplemented!()}
fn __bytes__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyObjectBytesProtocol<'p> {unimplemented!()}
fn __richcmp__(&self, other: Self::Other, op: CompareOp)
fn __richcmp__(&'p self, py: Python<'p>, other: Self::Other, op: CompareOp)
-> Self::Result where Self: PyObjectRichcmpProtocol<'p> {unimplemented!()}
}
@ -158,11 +164,12 @@ impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectGetAttrProtocol<'p>
impl<T> PyObjectGetAttrProtocolImpl for T where T: for<'p> PyObjectGetAttrProtocol<'p>
{
#[inline]
fn tp_getattro() -> Option<ffi::binaryfunc> {
py_binary_func!(PyObjectGetAttrProtocol, T::__getattr__, PyObjectCallbackConverter)
py_binary_func!(PyObjectGetAttrProtocol,
T::__getattr__, T::Success, PyObjectCallbackConverter)
}
}
@ -178,17 +185,17 @@ impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'p>
impl<T> PyObjectSetAttrProtocolImpl for T where T: for<'p> PyObjectSetAttrProtocol<'p>
{
#[inline]
fn tp_setattro() -> Option<ffi::setattrofunc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PyObjectSetAttrProtocol<'p>
{
const LOCATION: &'static str = "T.__setattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() {
return Err(PyErr::new::<exc::NotImplementedError, _>(
py, format!("Subscript deletion not supported by {:?}",
@ -197,11 +204,10 @@ impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'
let name = ::PyObject::from_borrowed_ptr(py, name);
let value = ::PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(name).extract() {
Ok(name) => match ::callback::unref(value).extract() {
match name.extract() {
Ok(name) => match value.extract() {
Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__setattr__(name, value).into()
slf.__setattr__(py, name, value).into()
},
Err(e) => Err(e.into()),
},
@ -225,24 +231,23 @@ impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'p>
impl<T> PyObjectDelAttrProtocolImpl for T where T: for<'p> PyObjectDelAttrProtocol<'p>
{
#[inline]
default fn tp_delattro() -> Option<ffi::setattrofunc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyObjectDelAttrProtocol<'p>
where T: for<'p> PyObjectDelAttrProtocol<'p>
{
const LOCATION: &'static str = "T.__detattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() {
let name = ::PyObject::from_borrowed_ptr(py, name);
match ::callback::unref(name).extract() {
match name.extract() {
Ok(name) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__delattr__(name).into()
slf.__delattr__(py, name).into()
},
Err(e) => Err(e.into()),
}
@ -257,34 +262,32 @@ impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'
}
impl<'p, T> PyObjectDelAttrProtocolImpl for T
where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p>
impl<T> PyObjectDelAttrProtocolImpl for T
where T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>
{
#[inline]
fn tp_delattro() -> Option<ffi::setattrofunc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>
{
const LOCATION: &'static str = "T.__detattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
let name = ::PyObject::from_borrowed_ptr(py, name);
if value.is_null() {
match ::callback::unref(name).extract() {
match name.extract() {
Ok(name) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__delattr__(name).into()
slf.__delattr__(py, name).into()
},
Err(e) => Err(e.into()),
}
} else {
let value = ::PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(name).extract() {
Ok(name) => match ::callback::unref(value).extract() {
match name.extract() {
Ok(name) => match value.extract() {
Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__setattr__(name, value).into()
slf.__setattr__(py, name, value).into()
},
Err(e) => Err(e.into()),
},
@ -308,11 +311,12 @@ impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'p>
impl<T> PyObjectStrProtocolImpl for T where T: for<'p> PyObjectStrProtocol<'p>
{
#[inline]
fn tp_str() -> Option<ffi::unaryfunc> {
py_unary_func!(PyObjectStrProtocol, T::__str__, PyObjectCallbackConverter)
py_unary_func!(PyObjectStrProtocol, T::__str__,
<T as PyObjectStrProtocol>::Success, PyObjectCallbackConverter)
}
}
@ -326,11 +330,12 @@ impl<'p, T> PyObjectReprProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'p>
impl<T> PyObjectReprProtocolImpl for T where T: for<'p> PyObjectReprProtocol<'p>
{
#[inline]
fn tp_repr() -> Option<ffi::unaryfunc> {
py_unary_func!(PyObjectReprProtocol, T::__repr__, PyObjectCallbackConverter)
py_unary_func!(PyObjectReprProtocol,
T::__repr__, T::Success, PyObjectCallbackConverter)
}
}
@ -369,11 +374,12 @@ impl<'p, T> PyObjectHashProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'p>
impl<T> PyObjectHashProtocolImpl for T where T: for<'p> PyObjectHashProtocol<'p>
{
#[inline]
fn tp_hash() -> Option<ffi::hashfunc> {
py_unary_func!(PyObjectHashProtocol, T::__hash__, HashConverter, ffi::Py_hash_t)
py_unary_func!(PyObjectHashProtocol,
T::__hash__, usize, HashConverter, ffi::Py_hash_t)
}
}
@ -387,11 +393,11 @@ impl<'p, T> PyObjectBoolProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'p>
impl<T> PyObjectBoolProtocolImpl for T where T: for<'p> PyObjectBoolProtocol<'p>
{
#[inline]
fn nb_bool() -> Option<ffi::inquiry> {
py_unary_func!(PyObjectBoolProtocol, T::__bool__, BoolCallbackConverter, c_int)
py_unary_func!(PyObjectBoolProtocol, T::__bool__, bool, BoolCallbackConverter, c_int)
}
}
@ -405,31 +411,54 @@ impl<'p, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectProtocol<'p>
None
}
}
impl<'p, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectRichcmpProtocol<'p>
impl<T> PyObjectRichcmpProtocolImpl for T where T: for<'p> PyObjectRichcmpProtocol<'p>
{
#[inline]
fn tp_richcompare() -> Option<ffi::richcmpfunc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject,
op: c_int) -> *mut ffi::PyObject
where T: PyObjectRichcmpProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject,
op: c_int) -> *mut ffi::PyObject
where T: for<'p> PyObjectRichcmpProtocol<'p>
{
const LOCATION: &'static str = concat!(stringify!(T), ".__richcmp__()");
::callback::handle(LOCATION, PyObjectCallbackConverter, |py| {
match extract_op(py, op) {
let guard = ::callback::AbortOnDrop(LOCATION);
let ret = std::panic::catch_unwind(|| {
let py = Python::assume_gil_acquired();
let slf = Py::<T>::from_borrowed_ptr(py, slf);
let res = match extract_op(py, op) {
Ok(op) => {
let arg = PyObject::from_borrowed_ptr(py, arg);
match ::callback::unref(arg).extract() {
match arg.extract() {
Ok(arg) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__richcmp__(arg, op).into()
slf.as_ref().__richcmp__(py, arg, op).into()
}
Err(e) => Err(e.into()),
}
},
Err(e) => Err(e)
};
match res {
Ok(val) => {
val.into_object(py).into_ptr()
}
Err(e) => {
e.restore(py);
std::ptr::null_mut()
}
}
})
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
::callback::handle_panic(Python::assume_gil_acquired(), err);
std::ptr::null_mut()
}
};
std::mem::forget(guard);
ret
}
Some(wrap::<T>)
}

View file

@ -9,6 +9,7 @@ use std::os::raw::c_int;
use ffi;
use err::PyResult;
use python::Python;
use objects::PyObject;
use typeob::PyTypeInfo;
use callback::{handle, UnitCallbackConverter};
@ -18,9 +19,10 @@ use class::NO_METHODS;
/// Buffer protocol interface
pub trait PyBufferProtocol<'p> : PyTypeInfo {
fn bf_getbuffer(&self, view: *mut ffi::Py_buffer, flags: c_int) -> PyResult<()>;
fn bf_getbuffer(&'p self, py: Python<'p>,
view: *mut ffi::Py_buffer, flags: c_int) -> PyResult<()>;
fn bf_releasebuffer(&self, view: *mut ffi::Py_buffer) -> PyResult<()>;
fn bf_releasebuffer(&'p self, py: Python<'p>, view: *mut ffi::Py_buffer) -> PyResult<()>;
}
#[doc(hidden)]
@ -36,10 +38,12 @@ impl<T> PyBufferProtocolImpl for T {
impl<'p, T> PyBufferProtocol<'p> for T where T: PyTypeInfo {
default fn bf_getbuffer(&self, _view: *mut ffi::Py_buffer, _flags: c_int) -> PyResult<()> {
default fn bf_getbuffer(&'p self, _py: Python<'p>,
_view: *mut ffi::Py_buffer, _flags: c_int) -> PyResult<()> {
Ok(())
}
default fn bf_releasebuffer(&self, _view: *mut ffi::Py_buffer) -> PyResult<()> {
default fn bf_releasebuffer(&'p self, _py: Python<'p>,
_view: *mut ffi::Py_buffer) -> PyResult<()> {
Ok(())
}
}
@ -70,7 +74,7 @@ impl ffi::PyBufferProcs {
const LOCATION: &'static str = concat!(stringify!(T), ".buffer_get::<PyBufferProtocol>()");
handle(LOCATION, UnitCallbackConverter, |py| {
let slf = PyObject::from_borrowed_ptr(py, slf);
slf.bf_getbuffer(arg1, arg2)
slf.bf_getbuffer(py, arg1, arg2)
})
}
Some(wrap::<T>)

View file

@ -5,6 +5,7 @@
//!
use err::PyResult;
use python::Python;
use typeob::PyTypeInfo;
use class::methods::PyMethodDef;
@ -13,10 +14,10 @@ use class::methods::PyMethodDef;
#[allow(unused_variables)]
pub trait PyContextProtocol<'p>: PyTypeInfo {
fn __enter__(&mut self)
fn __enter__(&'p mut self, py: Python<'p>)
-> Self::Result where Self: PyContextEnterProtocol<'p> {unimplemented!()}
fn __exit__(&mut self,
fn __exit__(&'p mut self, py: Python<'p>,
exc_type: Option<Self::ExcType>,
exc_value: Option<Self::ExcValue>,
traceback: Option<Self::Traceback>)

View file

@ -9,6 +9,7 @@ use std::os::raw::c_int;
use ffi;
use err::PyResult;
use python::Python;
use objects::{PyObject, PyType};
use callback::{PyObjectCallbackConverter, UnitCallbackConverter};
use typeob::PyTypeInfo;
@ -20,16 +21,16 @@ use conversion::{ToPyObject, FromPyObject};
#[allow(unused_variables)]
pub trait PyDescrProtocol<'p>: PyTypeInfo {
fn __get__(&self, instance: &'p PyObject, owner: Option<&'p PyType>)
fn __get__(&'p self, py: Python<'p>, instance: &'p PyObject, owner: Option<&'p PyType>)
-> Self::Result where Self: PyDescrGetProtocol<'p> { unimplemented!() }
fn __set__(&self, instance: &'p PyObject, value: &'p PyObject)
fn __set__(&'p self, py: Python<'p>, instance: &'p PyObject, value: &'p PyObject)
-> Self::Result where Self: PyDescrSetProtocol<'p> { unimplemented!() }
fn __delete__(&self, instance: &'p PyObject)
fn __delete__(&'p self, py: Python<'p>, instance: &'p PyObject)
-> Self::Result where Self: PyDescrDeleteProtocol<'p> { unimplemented!() }
fn __set_name__(&self, instance: &'p PyObject)
fn __set_name__(&'p self, py: Python<'p>, instance: &'p PyObject)
-> Self::Result where Self: PyDescrSetNameProtocol<'p> { unimplemented!() }
}
@ -65,10 +66,10 @@ impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {
None
}
}
impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrGetProtocol<'p>
impl<T> PyDescrGetProtocolImpl for T where T: for<'p> PyDescrGetProtocol<'p>
{
fn tp_descr_get() -> Option<ffi::descrgetfunc> {
py_ternary_func!(PyDescrGetProtocol, T::__get__, PyObjectCallbackConverter)
py_ternary_func!(PyDescrGetProtocol, T::__get__, T::Success, PyObjectCallbackConverter)
}
}
pub trait PyDescrSetProtocolImpl {
@ -79,10 +80,10 @@ impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {
None
}
}
impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrSetProtocol<'p>
impl<T> PyDescrSetProtocolImpl for T where T: for<'p> PyDescrSetProtocol<'p>
{
fn tp_descr_set() -> Option<ffi::descrsetfunc> {
py_ternary_func!(PyDescrSetProtocol, T::__set__, UnitCallbackConverter, c_int)
py_ternary_func!(PyDescrSetProtocol, T::__set__, (), UnitCallbackConverter, c_int)
}
}

View file

@ -18,17 +18,18 @@ pub struct PyTraverseError(c_int);
/// GC support
pub trait PyGCProtocol<'p> : PyTypeInfo {
fn __traverse__(&self, visit: PyVisit) -> Result<(), PyTraverseError>;
fn __traverse__(&'p self, py: Python<'p>, visit: PyVisit) -> Result<(), PyTraverseError>;
fn __clear__(&self);
fn __clear__(&'p mut self, py: Python<'p>);
}
impl<'p, T> PyGCProtocol<'p> for T where T: PyTypeInfo {
default fn __traverse__(&self, _: PyVisit) -> Result<(), PyTraverseError> {
default fn __traverse__(&'p self, _py: Python<'p>, _: PyVisit)
-> Result<(), PyTraverseError> {
Ok(())
}
default fn __clear__(&self) {}
default fn __clear__(&'p mut self, _py: Python<'p>) {}
}
#[doc(hidden)]
@ -79,10 +80,10 @@ impl <'a> PyVisit<'a> {
}
#[doc(hidden)]
unsafe extern "C" fn tp_traverse<'p, T>(slf: *mut ffi::PyObject,
visit: ffi::visitproc,
arg: *mut c_void) -> c_int
where T: PyGCProtocol<'p>
unsafe extern "C" fn tp_traverse<T>(slf: *mut ffi::PyObject,
visit: ffi::visitproc,
arg: *mut c_void) -> c_int
where T: for<'p> PyGCProtocol<'p>
{
const LOCATION: &'static str = concat!(stringify!(T), ".__traverse__()");
@ -91,23 +92,23 @@ unsafe extern "C" fn tp_traverse<'p, T>(slf: *mut ffi::PyObject,
let visit = PyVisit { visit: visit, arg: arg, _py: py };
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
let ret = match T::__traverse__(&slf, visit) {
let ret = match T::__traverse__(&slf, py, visit) {
Ok(()) => 0,
Err(PyTraverseError(code)) => code
};
mem::forget(guard);
mem::forget(guard);
ret
}
unsafe extern "C" fn tp_clear<'p, T>(slf: *mut ffi::PyObject) -> c_int
where T: PyGCProtocol<'p>
unsafe extern "C" fn tp_clear<T>(slf: *mut ffi::PyObject) -> c_int
where T: for<'p> PyGCProtocol<'p>
{
const LOCATION: &'static str = concat!(stringify!(T), ".__clear__()");
let guard = AbortOnDrop(LOCATION);
let py = Python::assume_gil_acquired();
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
T::__clear__(&slf);
T::__clear__(slf.as_mut(), py);
mem::forget(guard);
0
}

View file

@ -8,6 +8,7 @@
use ffi;
use err::PyResult;
use python::Python;
use typeob::PyTypeInfo;
use callback::PyObjectCallbackConverter;
@ -15,9 +16,11 @@ use callback::PyObjectCallbackConverter;
/// Iterator protocol
#[allow(unused_variables)]
pub trait PyIterProtocol<'p> : PyTypeInfo {
fn __iter__(&self) -> Self::Result where Self: PyIterIterProtocol<'p> { unimplemented!() }
fn __iter__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyIterIterProtocol<'p> { unimplemented!() }
fn __next__(&self) -> Self::Result where Self: PyIterNextProtocol<'p> { unimplemented!() }
fn __next__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyIterNextProtocol<'p> { unimplemented!() }
}
@ -62,11 +65,11 @@ impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterProtocol<'p>
}
}
impl<'p, T> PyIterIterProtocolImpl for T where T: PyIterIterProtocol<'p>
impl<T> PyIterIterProtocolImpl for T where T: for<'p> PyIterIterProtocol<'p>
{
#[inline]
fn tp_iter() -> Option<ffi::getiterfunc> {
py_unary_func!(PyIterIterProtocol, T::__iter__, PyObjectCallbackConverter)
py_unary_func!(PyIterIterProtocol, T::__iter__, T::Success, PyObjectCallbackConverter)
}
}
@ -83,11 +86,10 @@ impl<'p, T> PyIterNextProtocolImpl for T
}
}
impl<'p, T> PyIterNextProtocolImpl for T
where T: PyIterNextProtocol<'p>
impl<T> PyIterNextProtocolImpl for T where T: for<'p> PyIterNextProtocol<'p>
{
#[inline]
fn tp_iternext() -> Option<ffi::iternextfunc> {
py_unary_func!(PyIterNextProtocol, T::__next__, PyObjectCallbackConverter)
py_unary_func!(PyIterNextProtocol, T::__next__, T::Success, PyObjectCallbackConverter)
}
}

View file

@ -3,35 +3,106 @@
#[macro_export]
#[doc(hidden)]
macro_rules! py_unary_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_unary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject);
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {
py_unary_func!($trait, $class::$f, $res_type, $conv, *mut $crate::ffi::PyObject);
};
($trait:ident, $class:ident :: $f:ident, $conv:expr, $res_type:ty) => {{
unsafe extern "C" fn wrap<'a, T>(slf: *mut $crate::ffi::PyObject) -> $res_type
where T: $trait<'a>
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty, $ret_type:ty) => {{
#[allow(unused_mut)]
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject) -> $ret_type
where T: for<'p> $trait<'p>
{
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
$crate::callback::handle(LOCATION, $conv, |py| {
let slf: $crate::Py<T> = $crate::Py::from_borrowed_ptr(py, slf);
slf.as_ref().$f().into()
})
let guard = $crate::callback::AbortOnDrop(LOCATION);
let ret = $crate::std::panic::catch_unwind(|| {
let py = $crate::Python::assume_gil_acquired();
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
let res = slf.$f(py).into();
match res {
Ok(val) => {
<$conv as $crate::callback::CallbackConverter<$res_type>>
::convert(val, py)
}
Err(e) => {
e.restore(py);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
}
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
$crate::callback::handle_panic($crate::Python::assume_gil_acquired(), err);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
};
$crate::mem::forget(guard);
ret
}
Some(wrap::<$class>)
}}
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_unary_func_self {
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {{
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject)
-> *mut $crate::ffi::PyObject
where T: for<'p> $trait<'p> + $crate::ToPyObject + $crate::IntoPyObject
{
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
let guard = $crate::callback::AbortOnDrop(LOCATION);
let ret = $crate::std::panic::catch_unwind(|| {
let py = $crate::Python::assume_gil_acquired();
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
let res = slf.$f(py).into();
match res {
Ok(val) => {
<$conv as $crate::callback::CallbackConverter<$res_type>>
::convert(val, py)
}
Err(e) => {
e.restore(py);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
}
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
$crate::callback::handle_panic($crate::Python::assume_gil_acquired(), err);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
};
$crate::mem::forget(guard);
ret
}
Some(wrap::<$class>)
}}
}
#[macro_export]
#[doc(hidden)]
macro_rules! py_len_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
unsafe extern "C" fn wrap<'a, T>(slf: *mut $crate::ffi::PyObject)
-> $crate::ffi::Py_ssize_t
where T: $trait<'a>
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject)
-> $crate::ffi::Py_ssize_t
where T: for<'p> $trait<'p>
{
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
$crate::callback::handle(LOCATION, $conv, |py| {
let slf: $crate::Py<T> = $crate::Py::from_borrowed_ptr(py, slf);
slf.as_ref().$f().into()
$crate::callback::cb_unary::<T, _, _, _>(LOCATION, slf, $conv, |py, slf| {
slf.$f(py).into()
})
}
Some(wrap::<$class>)
@ -40,24 +111,54 @@ macro_rules! py_len_func {
#[macro_export]
#[doc(hidden)]
macro_rules! py_binary_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject) -> *mut ffi::PyObject
where T: $trait<'a>
macro_rules! py_binary_func{
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {
py_binary_func!($trait, $class::$f, $res_type, $conv, *mut $crate::ffi::PyObject)
};
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty, $return:ty) => {{
#[allow(unused_mut)]
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject) -> $return
where T: for<'p> $trait<'p>
{
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
$crate::callback::handle(LOCATION, $conv, |py| {
let guard = $crate::callback::AbortOnDrop(LOCATION);
let ret = $crate::std::panic::catch_unwind(|| {
let py = $crate::Python::assume_gil_acquired();
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
let arg = $crate::PyObject::from_borrowed_ptr(py, arg);
match $crate::callback::unref(arg).extract() {
let result = match arg.extract() {
Ok(arg) => {
let slf: $crate::Py<T> = $crate::Py::from_borrowed_ptr(py, slf);
slf.as_ref().$f(arg).into()
slf.$f(py, arg).into()
}
Err(e) => Err(e.into()),
};
match result {
Ok(val) => {
<$conv as $crate::callback::CallbackConverter<$res_type>>
::convert(val, py)
}
Err(e) => {
e.restore(py);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
}
})
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
$crate::callback::handle_panic($crate::Python::assume_gil_acquired(), err);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
};
$crate::mem::forget(guard);
ret
}
Some(wrap::<$class>)
}}
@ -66,17 +167,43 @@ macro_rules! py_binary_func {
#[macro_export]
#[doc(hidden)]
macro_rules! py_ssizearg_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
unsafe extern "C" fn wrap<'a, T>(slf: *mut $crate::ffi::PyObject,
arg: $crate::Py_ssize_t)
-> *mut $crate::ffi::PyObject
where T: $trait<'a>
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {{
#[allow(unused_mut)]
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
arg: $crate::Py_ssize_t) -> *mut $crate::ffi::PyObject
where T: for<'p> $trait<'p> + ToPyObject + IntoPyObject
{
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
$crate::callback::handle(LOCATION, $conv, |py| {
let slf: $crate::Py<T> = $crate::Py::from_borrowed_ptr(py, slf);
slf.as_ref().$f(arg as isize).into()
})
let guard = $crate::callback::AbortOnDrop(LOCATION);
let ret = $crate::std::panic::catch_unwind(|| {
let py = $crate::Python::assume_gil_acquired();
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
let result = slf.$f(py, arg as isize).into();
match result {
Ok(val) => {
<$conv as $crate::callback::CallbackConverter<$res_type>>
::convert(val, py)
}
Err(e) => {
e.restore(py);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
}
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
$crate::callback::handle_panic($crate::Python::assume_gil_acquired(), err);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
};
$crate::mem::forget(guard);
ret
}
Some(wrap::<$class>)
}}
@ -85,31 +212,58 @@ macro_rules! py_ssizearg_func {
#[macro_export]
#[doc(hidden)]
macro_rules! py_ternary_func{
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {
py_ternary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject);
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {
py_ternary_func!($trait, $class::$f, $res_type, $conv, *mut $crate::ffi::PyObject);
};
($trait:ident, $class:ident :: $f:ident, $conv:expr, $res_type: ty) => {{
unsafe extern "C" fn wrap<'p, T>(slf: *mut $crate::ffi::PyObject,
arg1: *mut $crate::ffi::PyObject,
arg2: *mut $crate::ffi::PyObject) -> $res_type
where T: $trait<'p>
($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty, $return_type:ty) => {{
#[allow(unused_mut)]
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject,
arg1: *mut $crate::ffi::PyObject,
arg2: *mut $crate::ffi::PyObject) -> $return_type
where T: for<'p> $trait<'p>
{
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
$crate::callback::handle(LOCATION, $conv, |py| {
let slf: $crate::Py<T> = $crate::Py::from_borrowed_ptr(py, slf);
let guard = $crate::callback::AbortOnDrop(LOCATION);
let ret = $crate::std::panic::catch_unwind(|| {
let py = $crate::Python::assume_gil_acquired();
let mut slf = $crate::Py::<T>::from_borrowed_ptr(py, slf);
let arg1 = $crate::PyObject::from_borrowed_ptr(py, arg1);
let arg2 = $crate::PyObject::from_borrowed_ptr(py, arg2);
match ::callback::unref(arg1).extract() {
Ok(arg1) => match ::callback::unref(arg2).extract() {
Ok(arg2) =>
slf.$f(arg1, arg2).into(),
Err(e) => Err(e),
let result = match arg1.extract() {
Ok(arg1) => match arg2.extract() {
Ok(arg2) => slf.$f(py, arg1, arg2).into(),
Err(e) => Err(e.into())
},
Err(e) => Err(e)
Err(e) => Err(e.into()),
};
match result {
Ok(val) => {
<$conv as $crate::callback::CallbackConverter<$res_type>>
::convert(val, py)
}
Err(e) => {
e.restore(py);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
}
})
});
let ret = match ret {
Ok(r) => r,
Err(ref err) => {
$crate::callback::handle_panic(
$crate::Python::assume_gil_acquired(), err);
<$conv as $crate::callback::CallbackConverter<$res_type>>
::error_value()
}
};
$crate::mem::forget(guard);
ret
}
Some(wrap::<T>)
}}
}

View file

@ -8,6 +8,7 @@ use std::os::raw::c_int;
use ffi;
use err::{PyErr, PyResult};
use pyptr::Py;
use python::Python;
use objects::{exc, PyObject};
use callback::{PyObjectCallbackConverter, LenResultConverter, UnitCallbackConverter};
use conversion::{ToPyObject, FromPyObject};
@ -19,25 +20,25 @@ use class::methods::PyMethodDef;
#[allow(unused_variables)]
pub trait PyMappingProtocol<'p>: PyTypeInfo + Sized + 'static {
fn __len__(&self)
fn __len__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyMappingLenProtocol<'p> {unimplemented!()}
fn __getitem__(&self, key: Self::Key)
fn __getitem__(&'p self, py: Python<'p>, key: Self::Key)
-> Self::Result where Self: PyMappingGetItemProtocol<'p> {unimplemented!()}
fn __setitem__(&self, key: Self::Key, value: Self::Value)
fn __setitem__(&'p self, py: Python<'p>, key: Self::Key, value: Self::Value)
-> Self::Result where Self: PyMappingSetItemProtocol<'p> {unimplemented!()}
fn __delitem__(&self, key: Self::Key)
fn __delitem__(&'p self, py: Python<'p>, key: Self::Key)
-> Self::Result where Self: PyMappingDelItemProtocol<'p> {unimplemented!()}
fn __iter__(&self)
fn __iter__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyMappingIterProtocol<'p> {unimplemented!()}
fn __contains__(&self, value: Self::Value)
fn __contains__(&'p self, py: Python<'p>, value: Self::Value)
-> Self::Result where Self: PyMappingContainsProtocol<'p> {unimplemented!()}
fn __reversed__(&self)
fn __reversed__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyMappingReversedProtocol<'p> {unimplemented!()}
}
@ -145,7 +146,7 @@ impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingProtocol<'p>
}
}
impl<'p, T> PyMappingLenProtocolImpl for T where T: PyMappingLenProtocol<'p>
impl<T> PyMappingLenProtocolImpl for T where T: for<'p> PyMappingLenProtocol<'p>
{
#[inline]
fn mp_length() -> Option<ffi::lenfunc> {
@ -165,11 +166,12 @@ impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingProtocol<'p>
}
}
impl<'p, T> PyMappingGetItemProtocolImpl for T where T: PyMappingGetItemProtocol<'p>
impl<T> PyMappingGetItemProtocolImpl for T where T: for<'p> PyMappingGetItemProtocol<'p>
{
#[inline]
fn mp_subscript() -> Option<ffi::binaryfunc> {
py_binary_func!(PyMappingGetItemProtocol, T::__getitem__, PyObjectCallbackConverter)
py_binary_func!(PyMappingGetItemProtocol,
T::__getitem__, T::Success, PyObjectCallbackConverter)
}
}
@ -185,35 +187,35 @@ impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingProtocol<'p>
}
}
impl<'p, T> PyMappingSetItemProtocolImpl for T where T: PyMappingSetItemProtocol<'p>
impl<T> PyMappingSetItemProtocolImpl for T where T: for<'p> PyMappingSetItemProtocol<'p>
{
#[inline]
fn mp_ass_subscript() -> Option<ffi::objobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyMappingSetItemProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PyMappingSetItemProtocol<'p>
{
const LOCATION: &'static str = "T.__setitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
if value.is_null() {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
let res = if value.is_null() {
Err(PyErr::new::<exc::NotImplementedError, _>(
py, format!("Subscript deletion not supported by {:?}",
stringify!(T))))
} else {
let key = PyObject::from_borrowed_ptr(py, key);
match ::callback::unref(key).extract() {
match key.extract() {
Ok(key) => {
let slf = Py::<T>::from_borrowed_ptr(py, slf);
let value = PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(value).extract() {
Ok(value) => slf.__setitem__(key, value).into(),
match value.extract() {
Ok(value) => slf.__setitem__(py, key, value).into(),
Err(e) => Err(e),
}
},
Err(e) => Err(e),
}
}
};
res
})
}
Some(wrap::<T>)
@ -233,23 +235,22 @@ impl<'p, T> PyMappingDelItemProtocolImpl for T where T: PyMappingProtocol<'p>
}
}
impl<'p, T> PyMappingDelItemProtocolImpl for T where T: PyMappingDelItemProtocol<'p>
impl<T> PyMappingDelItemProtocolImpl for T where T: for<'p> PyMappingDelItemProtocol<'p>
{
#[inline]
default fn mp_del_subscript() -> Option<ffi::objobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyMappingDelItemProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PyMappingDelItemProtocol<'p>
{
const LOCATION: &'static str = "T.__detitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() {
let key = PyObject::from_borrowed_ptr(py, key);
match ::callback::unref(key).extract() {
match key.extract() {
Ok(key) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.__delitem__(key).into()
slf.__delitem__(py, key).into()
},
Err(e) => Err(e),
}
@ -265,15 +266,15 @@ impl<'p, T> PyMappingDelItemProtocolImpl for T where T: PyMappingDelItemProtocol
}
impl<'p, T> PyMappingDelItemProtocolImpl for T
where T: PyMappingSetItemProtocol<'p> + PyMappingDelItemProtocol<'p>
impl<T> PyMappingDelItemProtocolImpl for T
where T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p>
{
#[inline]
fn mp_del_subscript() -> Option<ffi::objobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: PyMappingSetItemProtocol<'p> + PyMappingDelItemProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PyMappingSetItemProtocol<'p> + for<'p> PyMappingDelItemProtocol<'p>
{
const LOCATION: &'static str = "T.__set/del_item__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
@ -281,16 +282,16 @@ impl<'p, T> PyMappingDelItemProtocolImpl for T
let key = PyObject::from_borrowed_ptr(py, key);
if value.is_null() {
match ::callback::unref(key).extract() {
Ok(key) => slf.__delitem__(key).into(),
match key.extract() {
Ok(key) => slf.__delitem__(py, key).into(),
Err(e) => Err(e)
}
} else {
match ::callback::unref(key).extract() {
match key.extract() {
Ok(key) => {
let value = PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(value).extract() {
Ok(value) => slf.__setitem__(key, value).into(),
match value.extract() {
Ok(value) => slf.__setitem__(py, key, value).into(),
Err(e) => Err(e),
}
},

View file

@ -6,7 +6,7 @@ pub mod async;
pub mod basic;
pub mod buffer;
pub mod context;
pub mod descr;
//pub mod descr;
pub mod mapping;
pub mod methods;
pub mod number;
@ -19,7 +19,7 @@ pub use self::async::PyAsyncProtocol;
pub use self::iter::PyIterProtocol;
pub use self::buffer::PyBufferProtocol;
pub use self::context::PyContextProtocol;
pub use self::descr::PyDescrProtocol;
//pub use self::descr::PyDescrProtocol;
pub use self::number::PyNumberProtocol;
pub use self::mapping::PyMappingProtocol;
pub use self::sequence::PySequenceProtocol;

View file

@ -5,119 +5,120 @@
use ffi;
use err::PyResult;
use python::Python;
use callback::PyObjectCallbackConverter;
use typeob::PyTypeInfo;
use class::methods::PyMethodDef;
use class::basic::PyObjectProtocolImpl;
use ::{c_void, ToPyObject, FromPyObject};
use ::{c_void, ToPyObject, IntoPyObject, FromPyObject};
/// Number interface
#[allow(unused_variables)]
pub trait PyNumberProtocol<'p>: PyTypeInfo {
fn __add__(&self, other: Self::Other)
fn __add__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberAddProtocol<'p> { unimplemented!() }
fn __sub__(&self, other: Self::Other)
fn __sub__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberSubProtocol<'p> { unimplemented!() }
fn __mul__(&self, other: Self::Other)
fn __mul__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberMulProtocol<'p> { unimplemented!() }
fn __matmul__(&self, other: Self::Other)
fn __matmul__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberMatmulProtocol<'p> { unimplemented!() }
fn __truediv__(&self, other: Self::Other)
fn __truediv__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberTruedivProtocol<'p> { unimplemented!() }
fn __floordiv__(&self, other: Self::Other)
fn __floordiv__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberFloordivProtocol<'p> { unimplemented!() }
fn __mod__(&self, other: Self::Other)
fn __mod__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberModProtocol<'p> { unimplemented!() }
fn __divmod__(&self, other: Self::Other)
fn __divmod__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberDivmodProtocol<'p> { unimplemented!() }
fn __pow__(&self, other: Self::Other, modulo: Self::Modulo)
fn __pow__(&'p self, py: Python<'p>, other: Self::Other, modulo: Self::Modulo)
-> Self::Result where Self: PyNumberPowProtocol<'p> { unimplemented!() }
fn __lshift__(&self, other: Self::Other)
fn __lshift__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberLShiftProtocol<'p> { unimplemented!() }
fn __rshift__(&self, other: Self::Other)
fn __rshift__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRShiftProtocol<'p> { unimplemented!() }
fn __and__(&self, other: Self::Other)
fn __and__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberAndProtocol<'p> { unimplemented!() }
fn __xor__(&self, other: Self::Other)
fn __xor__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberXorProtocol<'p> { unimplemented!() }
fn __or__(&self, other: Self::Other)
fn __or__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberOrProtocol<'p> { unimplemented!() }
fn __radd__(&self, other: Self::Other)
fn __radd__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRAddProtocol<'p> { unimplemented!() }
fn __rsub__(&self, other: Self::Other)
fn __rsub__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRSubProtocol<'p> { unimplemented!() }
fn __rmul__(&self, other: Self::Other)
fn __rmul__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRMulProtocol<'p> { unimplemented!() }
fn __rmatmul__(&self, other: Self::Other)
fn __rmatmul__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRMatmulProtocol<'p> { unimplemented!() }
fn __rtruediv__(&self, other: Self::Other)
fn __rtruediv__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRTruedivProtocol<'p> { unimplemented!() }
fn __rfloordiv__(&self, other: Self::Other)
fn __rfloordiv__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRFloordivProtocol<'p> { unimplemented!() }
fn __rmod__(&self, other: Self::Other)
fn __rmod__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRModProtocol<'p> { unimplemented!() }
fn __rdivmod__(&self, other: Self::Other)
fn __rdivmod__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRDivmodProtocol<'p> { unimplemented!() }
fn __rpow__(&self, other: Self::Other)
fn __rpow__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRPowProtocol<'p> { unimplemented!() }
fn __rlshift__(&self, other: Self::Other)
fn __rlshift__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRLShiftProtocol<'p> { unimplemented!() }
fn __rrshift__(&self, other: Self::Other)
fn __rrshift__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRRShiftProtocol<'p> { unimplemented!() }
fn __rand__(&self, other: Self::Other)
fn __rand__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRAndProtocol<'p> { unimplemented!() }
fn __rxor__(&self, other: Self::Other)
fn __rxor__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberRXorProtocol<'p> { unimplemented!() }
fn __ror__(&self, other: Self::Other)
fn __ror__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberROrProtocol<'p> { unimplemented!() }
fn __iadd__(&self, other: Self::Other)
fn __iadd__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIAddProtocol<'p> { unimplemented!() }
fn __isub__(&self, other: Self::Other)
fn __isub__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberISubProtocol<'p> { unimplemented!() }
fn __imul__(&self, other: Self::Other)
fn __imul__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIMulProtocol<'p> { unimplemented!() }
fn __imatmul__(&self, other: Self::Other)
fn __imatmul__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIMatmulProtocol<'p> { unimplemented!() }
fn __itruediv__(&self, other: Self::Other)
fn __itruediv__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberITruedivProtocol<'p> {unimplemented!()}
fn __ifloordiv__(&self, other: Self::Other)
fn __ifloordiv__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIFloordivProtocol<'p> {unimplemented!() }
fn __imod__(&self, other: Self::Other)
fn __imod__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIModProtocol<'p> { unimplemented!() }
fn __ipow__(&self, other: Self::Other, modulo: Self::Modulo)
fn __ipow__(&'p self, py: Python<'p>, other: Self::Other, modulo: Self::Modulo)
-> Self::Result where Self: PyNumberIPowProtocol<'p> { unimplemented!() }
fn __ilshift__(&self, other: Self::Other)
fn __ilshift__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberILShiftProtocol<'p> { unimplemented!() }
fn __irshift__(&self, other: Self::Other)
fn __irshift__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIRShiftProtocol<'p> { unimplemented!() }
fn __iand__(&self, other: Self::Other)
fn __iand__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIAndProtocol<'p> { unimplemented!() }
fn __ixor__(&self, other: Self::Other)
fn __ixor__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIXorProtocol<'p> { unimplemented!() }
fn __ior__(&self, other: Self::Other)
fn __ior__(&'p self, py: Python<'p>, other: Self::Other)
-> Self::Result where Self: PyNumberIOrProtocol<'p> { unimplemented!() }
// Unary arithmetic
fn __neg__(&self)
fn __neg__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberNegProtocol<'p> { unimplemented!() }
fn __pos__(&self)
fn __pos__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberPosProtocol<'p> { unimplemented!() }
fn __abs__(&self)
fn __abs__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberAbsProtocol<'p> { unimplemented!() }
fn __invert__(&self)
fn __invert__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberInvertProtocol<'p> { unimplemented!() }
fn __complex__(&self)
fn __complex__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberComplexProtocol<'p> { unimplemented!() }
fn __int__(&self)
fn __int__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberIntProtocol<'p> { unimplemented!() }
fn __float__(&self)
fn __float__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberFloatProtocol<'p> { unimplemented!() }
fn __round__(&self)
fn __round__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberRoundProtocol<'p> { unimplemented!() }
fn __index__(&self)
fn __index__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberIndexProtocol<'p> { unimplemented!() }
}
@ -505,9 +506,9 @@ trait PyNumberAddProtocolImpl {
impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_add() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberAddProtocol<'p> {
impl<T> PyNumberAddProtocolImpl for T where T: for<'p> PyNumberAddProtocol<'p> {
fn nb_add() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberAddProtocol, T::__add__, PyObjectCallbackConverter)
py_binary_func!(PyNumberAddProtocol, T::__add__, T::Success, PyObjectCallbackConverter)
}
}
@ -517,9 +518,9 @@ trait PyNumberSubProtocolImpl {
impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_subtract() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberSubProtocol<'p> {
impl<T> PyNumberSubProtocolImpl for T where T: for<'p> PyNumberSubProtocol<'p> {
fn nb_subtract() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberSubProtocol, T::__sub__, PyObjectCallbackConverter)
py_binary_func!(PyNumberSubProtocol, T::__sub__, T::Success, PyObjectCallbackConverter)
}
}
@ -529,9 +530,9 @@ trait PyNumberMulProtocolImpl {
impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_multiply() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberMulProtocol<'p> {
impl<T> PyNumberMulProtocolImpl for T where T: for<'p> PyNumberMulProtocol<'p> {
fn nb_multiply() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberMulProtocol, T::__mul__, PyObjectCallbackConverter)
py_binary_func!(PyNumberMulProtocol, T::__mul__, T::Success, PyObjectCallbackConverter)
}
}
@ -541,9 +542,10 @@ trait PyNumberMatmulProtocolImpl {
impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberMatmulProtocol<'p> {
impl<T> PyNumberMatmulProtocolImpl for T where T: for<'p> PyNumberMatmulProtocol<'p> {
fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberMatmulProtocol, T::__matmul__, PyObjectCallbackConverter)
py_binary_func!(PyNumberMatmulProtocol,
T::__matmul__, T::Success, PyObjectCallbackConverter)
}
}
@ -553,9 +555,10 @@ trait PyNumberTruedivProtocolImpl {
impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_true_divide() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberTruedivProtocol<'p> {
impl<T> PyNumberTruedivProtocolImpl for T where T: for<'p> PyNumberTruedivProtocol<'p> {
fn nb_true_divide() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberTruedivProtocol, T::__truediv__, PyObjectCallbackConverter)
py_binary_func!(PyNumberTruedivProtocol,
T::__truediv__, T::Success, PyObjectCallbackConverter)
}
}
@ -565,9 +568,10 @@ trait PyNumberFloordivProtocolImpl {
impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_floor_divide() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberFloordivProtocol<'p> {
impl<T> PyNumberFloordivProtocolImpl for T where T: for<'p> PyNumberFloordivProtocol<'p> {
fn nb_floor_divide() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberFloordivProtocol, T::__floordiv__, PyObjectCallbackConverter)
py_binary_func!(PyNumberFloordivProtocol,
T::__floordiv__, T::Success, PyObjectCallbackConverter)
}
}
@ -577,9 +581,9 @@ trait PyNumberModProtocolImpl {
impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_remainder() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberModProtocol<'p> {
impl<T> PyNumberModProtocolImpl for T where T: for<'p> PyNumberModProtocol<'p> {
fn nb_remainder() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberModProtocol, T::__mod__, PyObjectCallbackConverter)
py_binary_func!(PyNumberModProtocol, T::__mod__, T::Success, PyObjectCallbackConverter)
}
}
@ -589,9 +593,10 @@ trait PyNumberDivmodProtocolImpl {
impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_divmod() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberDivmodProtocol<'p> {
impl<T> PyNumberDivmodProtocolImpl for T where T: for<'p> PyNumberDivmodProtocol<'p> {
fn nb_divmod() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberDivmodProtocol, T::__divmod__, PyObjectCallbackConverter)
py_binary_func!(PyNumberDivmodProtocol,
T::__divmod__, T::Success, PyObjectCallbackConverter)
}
}
@ -601,9 +606,11 @@ trait PyNumberPowProtocolImpl {
impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_power() -> Option<ffi::ternaryfunc> {None}
}
impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberPowProtocol<'p> {
impl<T> PyNumberPowProtocolImpl for T where T: for<'p> PyNumberPowProtocol<'p> {
fn nb_power() -> Option<ffi::ternaryfunc> {
py_ternary_func!(PyNumberPowProtocol, T::__pow__, PyObjectCallbackConverter)
py_ternary_func!(PyNumberPowProtocol,
T::__pow__, <T as PyNumberPowProtocol>::Success,
PyObjectCallbackConverter)
}
}
@ -613,9 +620,10 @@ trait PyNumberLShiftProtocolImpl {
impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_lshift() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberLShiftProtocol<'p> {
impl<T> PyNumberLShiftProtocolImpl for T where T: for<'p> PyNumberLShiftProtocol<'p> {
fn nb_lshift() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberLShiftProtocol, T::__lshift__, PyObjectCallbackConverter)
py_binary_func!(PyNumberLShiftProtocol,
T::__lshift__, T::Success, PyObjectCallbackConverter)
}
}
@ -625,9 +633,10 @@ trait PyNumberRShiftProtocolImpl {
impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_rshift() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberRShiftProtocol<'p> {
impl<T> PyNumberRShiftProtocolImpl for T where T: for<'p> PyNumberRShiftProtocol<'p> {
fn nb_rshift() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberRShiftProtocol, T::__rshift__, PyObjectCallbackConverter)
py_binary_func!(PyNumberRShiftProtocol,
T::__rshift__, T::Success, PyObjectCallbackConverter)
}
}
@ -638,9 +647,10 @@ trait PyNumberAndProtocolImpl {
impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_and() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberAndProtocol<'p> {
impl<T> PyNumberAndProtocolImpl for T where T: for<'p> PyNumberAndProtocol<'p> {
fn nb_and() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberAndProtocol, T::__and__, PyObjectCallbackConverter)
py_binary_func!(PyNumberAndProtocol,
T::__and__, T::Success, PyObjectCallbackConverter)
}
}
@ -650,9 +660,10 @@ trait PyNumberXorProtocolImpl {
impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_xor() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberXorProtocol<'p> {
impl<T> PyNumberXorProtocolImpl for T where T: for<'p> PyNumberXorProtocol<'p> {
fn nb_xor() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberXorProtocol, T::__xor__, PyObjectCallbackConverter)
py_binary_func!(PyNumberXorProtocol,
T::__xor__, T::Success, PyObjectCallbackConverter)
}
}
@ -662,9 +673,10 @@ trait PyNumberOrProtocolImpl {
impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_or() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberOrProtocol<'p> {
impl<T> PyNumberOrProtocolImpl for T where T: for<'p> PyNumberOrProtocol<'p> {
fn nb_or() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberOrProtocol, T::__or__, PyObjectCallbackConverter)
py_binary_func!(PyNumberOrProtocol,
T::__or__, T::Success, PyObjectCallbackConverter)
}
}
@ -675,9 +687,10 @@ trait PyNumberIAddProtocolImpl {
impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_add() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberIAddProtocol<'p> {
impl<T> PyNumberIAddProtocolImpl for T where T: for<'p> PyNumberIAddProtocol<'p> {
fn nb_inplace_add() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIAddProtocol, T::__iadd__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIAddProtocol,
T::__iadd__, T::Success, PyObjectCallbackConverter)
}
}
@ -687,9 +700,10 @@ trait PyNumberISubProtocolImpl {
impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberISubProtocol<'p> {
impl<T> PyNumberISubProtocolImpl for T where T: for<'p> PyNumberISubProtocol<'p> {
fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberISubProtocol, T::__isub__, PyObjectCallbackConverter)
py_binary_func!(PyNumberISubProtocol,
T::__isub__, T::Success, PyObjectCallbackConverter)
}
}
@ -699,9 +713,10 @@ trait PyNumberIMulProtocolImpl {
impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberIMulProtocol<'p> {
impl<T> PyNumberIMulProtocolImpl for T where T: for<'p> PyNumberIMulProtocol<'p> {
fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIMulProtocol, T::__imul__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIMulProtocol,
T::__imul__, T::Success, PyObjectCallbackConverter)
}
}
@ -711,9 +726,10 @@ trait PyNumberIMatmulProtocolImpl {
impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberIMatmulProtocol<'p> {
impl<T> PyNumberIMatmulProtocolImpl for T where T: for<'p> PyNumberIMatmulProtocol<'p> {
fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIMatmulProtocol, T::__imatmul__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIMatmulProtocol,
T::__imatmul__, T::Success, PyObjectCallbackConverter)
}
}
@ -723,9 +739,10 @@ trait PyNumberITruedivProtocolImpl {
impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberITruedivProtocol<'p> {
impl<T> PyNumberITruedivProtocolImpl for T where T: for<'p> PyNumberITruedivProtocol<'p> {
fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberITruedivProtocol, T::__itruediv__, PyObjectCallbackConverter)
py_binary_func!(PyNumberITruedivProtocol,
T::__itruediv__, T::Success, PyObjectCallbackConverter)
}
}
@ -735,9 +752,10 @@ trait PyNumberIFloordivProtocolImpl {
impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberIFloordivProtocol<'p> {
impl<T> PyNumberIFloordivProtocolImpl for T where T: for<'p> PyNumberIFloordivProtocol<'p> {
fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIFloordivProtocol, T::__ifloordiv__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIFloordivProtocol,
T::__ifloordiv__, T::Success, PyObjectCallbackConverter)
}
}
@ -747,9 +765,10 @@ trait PyNumberIModProtocolImpl {
impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberIModProtocol<'p> {
impl<T> PyNumberIModProtocolImpl for T where T: for<'p> PyNumberIModProtocol<'p> {
fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIModProtocol, T::__imod__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIModProtocol,
T::__imod__, T::Success, PyObjectCallbackConverter)
}
}
@ -759,9 +778,10 @@ trait PyNumberIPowProtocolImpl {
impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_power() -> Option<ffi::ternaryfunc> {None}
}
impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberIPowProtocol<'p> {
impl<T> PyNumberIPowProtocolImpl for T where T: for<'p> PyNumberIPowProtocol<'p> {
fn nb_inplace_power() -> Option<ffi::ternaryfunc> {
py_ternary_func!(PyNumberIPowProtocol, T::__ipow__, PyObjectCallbackConverter)
py_ternary_func!(PyNumberIPowProtocol,
T::__ipow__, T::Success, PyObjectCallbackConverter)
}
}
@ -771,9 +791,10 @@ trait PyNumberILShiftProtocolImpl {
impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberILShiftProtocol<'p> {
impl<T> PyNumberILShiftProtocolImpl for T where T: for<'p> PyNumberILShiftProtocol<'p> {
fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberILShiftProtocol, T::__ilshift__, PyObjectCallbackConverter)
py_binary_func!(PyNumberILShiftProtocol,
T::__ilshift__, T::Success, PyObjectCallbackConverter)
}
}
@ -783,9 +804,10 @@ trait PyNumberIRShiftProtocolImpl {
impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberIRShiftProtocol<'p> {
impl<T> PyNumberIRShiftProtocolImpl for T where T: for<'p> PyNumberIRShiftProtocol<'p> {
fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIRShiftProtocol, T::__irshift__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIRShiftProtocol,
T::__irshift__, T::Success, PyObjectCallbackConverter)
}
}
@ -796,9 +818,10 @@ trait PyNumberIAndProtocolImpl {
impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_and() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberIAndProtocol<'p> {
impl<T> PyNumberIAndProtocolImpl for T where T: for<'p> PyNumberIAndProtocol<'p> {
fn nb_inplace_and() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIAndProtocol, T::__iand__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIAndProtocol,
T::__iand__, T::Success, PyObjectCallbackConverter)
}
}
@ -808,9 +831,10 @@ trait PyNumberIXorProtocolImpl {
impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_xor() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberIXorProtocol<'p> {
impl<T> PyNumberIXorProtocolImpl for T where T: for<'p> PyNumberIXorProtocol<'p> {
fn nb_inplace_xor() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIXorProtocol, T::__ixor__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIXorProtocol,
T::__ixor__, T::Success, PyObjectCallbackConverter)
}
}
@ -820,9 +844,10 @@ trait PyNumberIOrProtocolImpl {
impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_or() -> Option<ffi::binaryfunc> {None}
}
impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberIOrProtocol<'p> {
impl<T> PyNumberIOrProtocolImpl for T where T: for<'p> PyNumberIOrProtocol<'p> {
fn nb_inplace_or() -> Option<ffi::binaryfunc> {
py_binary_func!(PyNumberIOrProtocol, T::__ior__, PyObjectCallbackConverter)
py_binary_func!(PyNumberIOrProtocol,
T::__ior__, T::Success, PyObjectCallbackConverter)
}
}
@ -932,11 +957,12 @@ trait PyNumberNegProtocolImpl {
impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_negative() -> Option<ffi::unaryfunc> {None}
}
impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberNegProtocol<'p>
impl<T> PyNumberNegProtocolImpl for T
where T: for<'p> PyNumberNegProtocol<'p> + ToPyObject + IntoPyObject
{
#[inline]
fn nb_negative() -> Option<ffi::unaryfunc> {
py_unary_func!(PyNumberNegProtocol, T::__neg__, PyObjectCallbackConverter)
py_unary_func!(PyNumberNegProtocol, T::__neg__, T::Success, PyObjectCallbackConverter)
}
}
@ -946,10 +972,11 @@ trait PyNumberPosProtocolImpl {
impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_positive() -> Option<ffi::unaryfunc> {None}
}
impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberPosProtocol<'p>
impl<T> PyNumberPosProtocolImpl for T
where T: for<'p> PyNumberPosProtocol<'p> + ToPyObject + IntoPyObject
{
fn nb_positive() -> Option<ffi::unaryfunc> {
py_unary_func!(PyNumberPosProtocol, T::__pos__, PyObjectCallbackConverter)
py_unary_func!(PyNumberPosProtocol, T::__pos__, T::Success, PyObjectCallbackConverter)
}
}
@ -959,10 +986,11 @@ trait PyNumberAbsProtocolImpl {
impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_absolute() -> Option<ffi::unaryfunc> {None}
}
impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberAbsProtocol<'p>
impl<T> PyNumberAbsProtocolImpl for T
where T: for<'p> PyNumberAbsProtocol<'p> + ToPyObject + IntoPyObject
{
fn nb_absolute() -> Option<ffi::unaryfunc> {
py_unary_func!(PyNumberAbsProtocol, T::__abs__, PyObjectCallbackConverter)
py_unary_func!(PyNumberAbsProtocol, T::__abs__, T::Success, PyObjectCallbackConverter)
}
}
@ -972,10 +1000,12 @@ trait PyNumberInvertProtocolImpl {
impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_invert() -> Option<ffi::unaryfunc> {None}
}
impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberInvertProtocol<'p>
impl<T> PyNumberInvertProtocolImpl for T
where T: for<'p> PyNumberInvertProtocol<'p> + ToPyObject + IntoPyObject
{
fn nb_invert() -> Option<ffi::unaryfunc> {
py_unary_func!(PyNumberInvertProtocol, T::__invert__, PyObjectCallbackConverter)
py_unary_func!(PyNumberInvertProtocol, T::__invert__,
T::Success, PyObjectCallbackConverter)
}
}
@ -985,9 +1015,12 @@ trait PyNumberIntProtocolImpl {
impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_int() -> Option<ffi::unaryfunc> {None}
}
impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberIntProtocol<'p> {
impl<T> PyNumberIntProtocolImpl for T
where T: for<'p> PyNumberIntProtocol<'p> + ToPyObject + IntoPyObject
{
fn nb_int() -> Option<ffi::unaryfunc> {
py_unary_func!(PyNumberIntProtocol, T::__int__, PyObjectCallbackConverter)
py_unary_func!(PyNumberIntProtocol, T::__int__,
T::Success, PyObjectCallbackConverter)
}
}
@ -997,9 +1030,11 @@ trait PyNumberFloatProtocolImpl {
impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_float() -> Option<ffi::unaryfunc> {None}
}
impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberFloatProtocol<'p> {
impl<T> PyNumberFloatProtocolImpl for T
where T: for<'p> PyNumberFloatProtocol<'p> + ToPyObject + IntoPyObject {
fn nb_float() -> Option<ffi::unaryfunc> {
py_unary_func!(PyNumberFloatProtocol, T::__float__, PyObjectCallbackConverter)
py_unary_func!(PyNumberFloatProtocol, T::__float__,
T::Success, PyObjectCallbackConverter)
}
}
@ -1009,9 +1044,12 @@ trait PyNumberIndexProtocolImpl {
impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_index() -> Option<ffi::unaryfunc> {None}
}
impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberIndexProtocol<'p> {
impl<T> PyNumberIndexProtocolImpl for T
where T: for<'p> PyNumberIndexProtocol<'p>
{
fn nb_index() -> Option<ffi::unaryfunc> {
py_unary_func!(PyNumberIndexProtocol, T::__index__, PyObjectCallbackConverter)
py_unary_func!(PyNumberIndexProtocol,
T::__index__, T::Success, PyObjectCallbackConverter)
}
}

View file

@ -5,44 +5,44 @@
use std::os::raw::c_int;
use ::Py;
use ffi;
use python::Python;
use err::{PyErr, PyResult};
use objects::{exc, PyObject};
use callback::{PyObjectCallbackConverter,
LenResultConverter, UnitCallbackConverter, BoolCallbackConverter};
use typeob::PyTypeInfo;
use conversion::{ToPyObject, FromPyObject};
use conversion::{ToPyObject, IntoPyObject, FromPyObject};
/// Sequece interface
#[allow(unused_variables)]
pub trait PySequenceProtocol<'p>: PyTypeInfo + Sized + 'static {
fn __len__(&self) -> Self::Result
fn __len__(&'p self, py: Python<'p>) -> Self::Result
where Self: PySequenceLenProtocol<'p> { unimplemented!() }
fn __getitem__(&self, key: isize) -> Self::Result
fn __getitem__(&'p self, py: Python<'p>, key: isize) -> Self::Result
where Self: PySequenceGetItemProtocol<'p> { unimplemented!() }
fn __setitem__(&self, key: isize, value: Self::Value) -> Self::Result
fn __setitem__(&'p self, py: Python<'p>, key: isize, value: Self::Value) -> Self::Result
where Self: PySequenceSetItemProtocol<'p> { unimplemented!() }
fn __delitem__(&self, key: isize) -> Self::Result
fn __delitem__(&'p self, py: Python<'p>, key: isize) -> Self::Result
where Self: PySequenceDelItemProtocol<'p> { unimplemented!() }
fn __contains__(&self, item: Self::Item) -> Self::Result
fn __contains__(&'p self, py: Python<'p>, item: Self::Item) -> Self::Result
where Self: PySequenceContainsProtocol<'p> { unimplemented!() }
fn __concat__(&self, other: Self::Other) -> Self::Result
fn __concat__(&'p self, py: Python<'p>, other: Self::Other) -> Self::Result
where Self: PySequenceConcatProtocol<'p> { unimplemented!() }
fn __repeat__(&self, count: isize) -> Self::Result
fn __repeat__(&'p self, py: Python<'p>, count: isize) -> Self::Result
where Self: PySequenceRepeatProtocol<'p> { unimplemented!() }
fn __inplace_concat__(&self, other: Self::Other) -> Self::Result
fn __inplace_concat__(&'p self, py: Python<'p>, other: Self::Other) -> Self::Result
where Self: PySequenceInplaceConcatProtocol<'p> { unimplemented!() }
fn __inplace_repeat__(&self, count: isize) -> Self::Result
fn __inplace_repeat__(&'p self, py: Python<'p>, count: isize) -> Self::Result
where Self: PySequenceInplaceRepeatProtocol<'p> { unimplemented!() }
}
@ -141,7 +141,7 @@ impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceProtocol<'p>
}
}
impl<'p, T> PySequenceLenProtocolImpl for T where T: PySequenceLenProtocol<'p>
impl<T> PySequenceLenProtocolImpl for T where T: for<'p> PySequenceLenProtocol<'p>
{
#[inline]
fn sq_length() -> Option<ffi::lenfunc> {
@ -161,11 +161,13 @@ impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceProtocol<'p>
}
}
impl<'p, T> PySequenceGetItemProtocolImpl for T where T: PySequenceGetItemProtocol<'p>
impl<T> PySequenceGetItemProtocolImpl for T
where T: for<'p> PySequenceGetItemProtocol<'p> + ToPyObject + IntoPyObject
{
#[inline]
fn sq_item() -> Option<ffi::ssizeargfunc> {
py_ssizearg_func!(PySequenceGetItemProtocol, T::__getitem__, PyObjectCallbackConverter)
py_ssizearg_func!(PySequenceGetItemProtocol,
T::__getitem__, T::Success, PyObjectCallbackConverter)
}
}
@ -181,27 +183,25 @@ impl<'p, T> PySequenceSetItemProtocolImpl for T where T: PySequenceProtocol<'p>
}
}
impl<'p, T> PySequenceSetItemProtocolImpl for T where T: PySequenceSetItemProtocol<'p>
impl<T> PySequenceSetItemProtocolImpl for T where T: for<'p> PySequenceSetItemProtocol<'p>
{
#[inline]
fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: PySequenceSetItemProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PySequenceSetItemProtocol<'p>
{
const LOCATION: &'static str = "foo.__setitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() {
Err(PyErr::new::<exc::NotImplementedError, _>(
py, format!("Item deletion not supported by {:?}",
stringify!(T))))
py, format!("Item deletion not supported by {:?}", stringify!(T))))
} else {
let value = PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(value).extract() {
match value.extract() {
Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__setitem__(key as isize, value).into()
slf.__setitem__(py, key as isize, value).into()
},
Err(e) => Err(e.into()),
}
@ -223,20 +223,19 @@ impl<'p, T> PySequenceDelItemProtocolImpl for T where T: PySequenceProtocol<'p>
}
}
impl<'p, T> PySequenceDelItemProtocolImpl for T where T: PySequenceDelItemProtocol<'p>
impl<T> PySequenceDelItemProtocolImpl for T where T: for<'p> PySequenceDelItemProtocol<'p>
{
#[inline]
default fn sq_del_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: PySequenceDelItemProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PySequenceDelItemProtocol<'p>
{
const LOCATION: &'static str = "T.__detitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.__delitem__(key as isize).into()
slf.__delitem__(py, key as isize).into()
} else {
Err(PyErr::new::<exc::NotImplementedError, _>(
py, format!("Item assignment not supported by {:?}",
@ -248,28 +247,26 @@ impl<'p, T> PySequenceDelItemProtocolImpl for T where T: PySequenceDelItemProtoc
}
}
impl<'p, T> PySequenceDelItemProtocolImpl for T
where T: PySequenceSetItemProtocol<'p> + PySequenceDelItemProtocol<'p>
impl<T> PySequenceDelItemProtocolImpl for T
where T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>
{
#[inline]
fn sq_del_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: PySequenceSetItemProtocol<'p> + PySequenceDelItemProtocol<'p>
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int
where T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>
{
const LOCATION: &'static str = "T.__set/del_item__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| {
::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.__delitem__(key as isize).into()
slf.__delitem__(py, key as isize).into()
} else {
let value = ::PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(value).extract() {
match value.extract() {
Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__setitem__(key as isize, value).into()
slf.__setitem__(py, key as isize, value).into()
},
Err(e) => Err(e.into()),
}
@ -293,27 +290,12 @@ impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceProtocol<'p>
}
}
impl<'p, T> PySequenceContainsProtocolImpl for T where T: PySequenceContainsProtocol<'p>
impl<T> PySequenceContainsProtocolImpl for T where T: for<'p> PySequenceContainsProtocol<'p>
{
#[inline]
fn sq_contains() -> Option<ffi::objobjproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject) -> c_int
where T: PySequenceContainsProtocol<'p>
{
const LOCATION: &'static str = concat!(stringify!($class), ".__contains__()");
::callback::handle(LOCATION, BoolCallbackConverter, |py| {
let arg = ::PyObject::from_borrowed_ptr(py, arg);
match ::callback::unref(arg).extract() {
Ok(arg) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
slf.as_ref().__contains__(arg).into()
}
Err(e) => Err(e.into()),
}
})
}
Some(wrap::<T>)
py_binary_func!(PySequenceContainsProtocol,
T::__contains__, bool, BoolCallbackConverter, c_int)
}
}
@ -329,11 +311,12 @@ impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceProtocol<'p>
}
}
impl<'p, T> PySequenceConcatProtocolImpl for T where T: PySequenceConcatProtocol<'p>
impl<T> PySequenceConcatProtocolImpl for T where T: for<'p> PySequenceConcatProtocol<'p>
{
#[inline]
fn sq_concat() -> Option<ffi::binaryfunc> {
py_binary_func!(PySequenceConcatProtocol, T::__concat__, PyObjectCallbackConverter)
py_binary_func!(PySequenceConcatProtocol,
T::__concat__, T::Success, PyObjectCallbackConverter)
}
}
@ -350,12 +333,13 @@ impl<'p, T> PySequenceRepeatProtocolImpl for T
}
}
impl<'p, T> PySequenceRepeatProtocolImpl for T
where T: PySequenceRepeatProtocol<'p>
impl<T> PySequenceRepeatProtocolImpl for T
where T: for<'p> PySequenceRepeatProtocol<'p> + ToPyObject + IntoPyObject
{
#[inline]
fn sq_repeat() -> Option<ffi::ssizeargfunc> {
py_ssizearg_func!(PySequenceRepeatProtocol, T::__repeat__, PyObjectCallbackConverter)
py_ssizearg_func!(PySequenceRepeatProtocol,
T::__repeat__, T::Success, PyObjectCallbackConverter)
}
}
@ -371,13 +355,13 @@ impl<'p, T> PySequenceInplaceConcatProtocolImpl for T where T: PySequenceProtoco
}
}
impl<'p, T> PySequenceInplaceConcatProtocolImpl for T
where T: PySequenceInplaceConcatProtocol<'p>
impl<T> PySequenceInplaceConcatProtocolImpl for T
where T: for<'p> PySequenceInplaceConcatProtocol<'p> + ToPyObject + IntoPyObject
{
#[inline]
fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
py_binary_func!(PySequenceInplaceConcatProtocol,
T::__inplace_concat__, PyObjectCallbackConverter)
T::__inplace_concat__, T, PyObjectCallbackConverter)
}
}
@ -393,11 +377,12 @@ impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T where T: PySequenceProtoco
}
}
impl<'p, T> PySequenceInplaceRepeatProtocolImpl for T
where T: PySequenceInplaceRepeatProtocol<'p>
impl<T> PySequenceInplaceRepeatProtocolImpl for T
where T: for<'p> PySequenceInplaceRepeatProtocol<'p> + ToPyObject + IntoPyObject
{
#[inline]
fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> {
py_ssizearg_func!(PySequenceInplaceRepeatProtocol, T::__inplace_repeat__, PyObjectCallbackConverter)
py_ssizearg_func!(PySequenceInplaceRepeatProtocol,
T::__inplace_repeat__, T, PyObjectCallbackConverter)
}
}

View file

@ -76,28 +76,28 @@ pub trait ToPyTuple {
/// the inherent method `PyObject::extract()` can be used.
pub trait FromPyObject<'source> : Sized {
/// Extracts `Self` from the source `PyObject`.
fn extract<S>(py: &'source Py<'source, S>) -> PyResult<Self>
fn extract<S>(py: Py<'source, S>) -> PyResult<Self>
where S: PyTypeInfo;
}
pub trait RefFromPyObject<'p> {
/*pub trait RefFromPyObject<'p> : Sized {
fn with_extracted<F, R>(py: Python<'p>, obj: &'p Py<'p, PyObject>, f: F) -> PyResult<R>
where F: FnOnce(&Self) -> R;
where F: FnOnce(Self) -> R;
}
impl <'p, T: ?Sized> RefFromPyObject<'p> for T
where for<'a> &'a T: FromPyObject<'p>
where for<'a> &'a T: FromPyObject<'p> + Sized
{
#[inline]
fn with_extracted<F, R>(_py: Python<'p>, obj: &'p Py<'p, PyObject>, f: F) -> PyResult<R>
where F: FnOnce(&Self) -> R
where F: FnOnce(Self) -> R
{
match FromPyObject::extract(obj) {
Ok(val) => Ok(f(val)),
Err(e) => Err(e)
}
}
}
}*/
// Default IntoPyObject implementation
impl <T> IntoPyObject for T where T: ToPyObject
@ -159,7 +159,7 @@ impl ToPyObject for () {
impl <'source, T> FromPyObject<'source> for Option<T> where T: FromPyObject<'source> {
fn extract<S>(obj: &'source Py<'source, S>) -> PyResult<Self>
fn extract<S>(obj: Py<'source, S>) -> PyResult<Self>
where S: PyTypeInfo
{
if obj.as_ptr() == unsafe { ffi::Py_None() } {

View file

@ -71,7 +71,7 @@ pub use err::{PyErr, PyResult, PyDowncastError};
pub use objects::*;
pub use python::{AsPy, Python};
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_python};
pub use conversion::{FromPyObject, RefFromPyObject, ToPyObject, IntoPyObject, ToPyTuple};
pub use conversion::{FromPyObject, /*RefFromPyObject,*/ ToPyObject, IntoPyObject, ToPyTuple};
pub use class::{CompareOp};
pub mod class;
pub use class::*;

View file

@ -21,7 +21,7 @@ use std::cmp::Ordering;
use ffi;
use libc;
use pyptr::{Py, PyPtr};
use python::{Python, ToPythonPointer};
use python::{AsPy, Python, ToPythonPointer};
use objects::{PyObject, PyDict, PyString};
use conversion::{ToPyObject, ToPyTuple};
use err::{PyErr, PyResult, self};

View file

@ -71,7 +71,7 @@ macro_rules! pyobject_extract(
impl<'source> ::conversion::FromPyObject<'source>
for $t
{
fn extract<S>($obj: &'source ::Py<'source, S>) -> $crate::PyResult<Self>
fn extract<S>($obj: ::Py<'source, S>) -> $crate::PyResult<Self>
where S: ::typeob::PyTypeInfo
{
$body

View file

@ -84,10 +84,11 @@ macro_rules! int_fits_larger_int(
}
pyobject_extract!(obj to $rust_type => {
let py = obj.py();
let val = try!(obj.extract::<$larger_type>());
match cast::<$larger_type, $rust_type>(val) {
Some(v) => Ok(v),
None => Err(overflow_error(obj.py()))
None => Err(overflow_error(py))
}
});
)
@ -116,7 +117,7 @@ macro_rules! int_convert_u64_or_i64 (
}
impl<'source> FromPyObject<'source> for $rust_type {
fn extract<S>(py: &'source Py<'source, S>) -> PyResult<$rust_type>
fn extract<S>(py: Py<'source, S>) -> PyResult<$rust_type>
where S: PyTypeInfo
{
let ptr = py.as_ptr();

View file

@ -13,7 +13,7 @@ use ffi;
use python::{AsPy, Python, ToPythonPointer};
use super::{exc, PyObject};
use err::{PyResult, PyErr};
use conversion::{RefFromPyObject, ToPyObject};
use conversion::{ToPyObject}; //RefFromPyObject,
/// Represents a Python string.
pub struct PyString;
@ -243,21 +243,22 @@ impl ToPyObject for String {
}
}
/// Allows extracting strings from Python objects.
/// Accepts Python `str` and `unicode` objects.
pyobject_extract!(obj to Cow<'source, str> => {
try!(obj.cast_as::<PyString>()).to_string()
});
// /// Allows extracting strings from Python objects.
// /// Accepts Python `str` and `unicode` objects.
//pyobject_extract!(obj to Cow<'source, str> => {
// try!(obj.cast_as::<PyString>()).to_string()
//});
/// Allows extracting strings from Python objects.
/// Accepts Python `str` and `unicode` objects.
pyobject_extract!(obj to String => {
obj.extract::<Cow<str>>().map(Cow::into_owned)
let s = try!(obj.cast_as::<PyString>());
s.to_string().map(Cow::into_owned)
});
impl<'p> RefFromPyObject<'p> for str {
/*impl<'p> RefFromPyObject<'p> for str {
fn with_extracted<F, R>(py: Python<'p>, obj: &Py<'p, PyObject>, f: F) -> PyResult<R>
where F: FnOnce(&str) -> R
{
@ -265,7 +266,7 @@ impl<'p> RefFromPyObject<'p> for str {
let s = try!(p.extract::<Cow<str>>());
Ok(f(&s))
}
}
}*/
#[cfg(test)]
mod test {

View file

@ -120,14 +120,14 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
}
impl<'s, $($T: FromPyObject<'s>),+> FromPyObject<'s> for ($($T,)+) {
fn extract<S>(obj: &'s Py<'s, S>) -> PyResult<Self>
fn extract<S>(obj: Py<'s, S>) -> PyResult<Self>
where S: ::typeob::PyTypeInfo
{
let t = try!(obj.cast_as::<&PyTuple>());
let slice = t.as_slice();
if slice.len() == $length {
if t.len() == $length {
Ok((
$( try!(slice[$n].extract::<$T>()), )+
$( try!(t.get_item($n).extract::<$T>()), )+
))
} else {
Err(wrong_tuple_length(obj.py(), t, $length))
@ -137,19 +137,19 @@ macro_rules! tuple_conversion ({$length:expr,$(($refN:ident, $n:tt, $T:ident)),+
});
tuple_conversion!(1, (ref0, 0, A));
tuple_conversion!(2, (ref0, 0, A), (ref1, 1, B));
tuple_conversion!(3, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C));
tuple_conversion!(4, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D));
tuple_conversion!(5, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E));
tuple_conversion!(6, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E), (ref5, 5, F));
tuple_conversion!(7, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E), (ref5, 5, F), (ref6, 6, G));
tuple_conversion!(8, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E), (ref5, 5, F), (ref6, 6, G), (ref7, 7, H));
tuple_conversion!(9, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E), (ref5, 5, F), (ref6, 6, G), (ref7, 7, H), (ref8, 8, I));
//tuple_conversion!(2, (ref0, 0, A), (ref1, 1, B));
//tuple_conversion!(3, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C));
//tuple_conversion!(4, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D));
//tuple_conversion!(5, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
// (ref4, 4, E));
//tuple_conversion!(6, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
// (ref4, 4, E), (ref5, 5, F));
//tuple_conversion!(7, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
// (ref4, 4, E), (ref5, 5, F), (ref6, 6, G));
//tuple_conversion!(8, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
// (ref4, 4, E), (ref5, 5, F), (ref6, 6, G), (ref7, 7, H));
//tuple_conversion!(9, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
// (ref4, 4, E), (ref5, 5, F), (ref6, 6, G), (ref7, 7, H), (ref8, 8, I));
// Empty tuple:

View file

@ -8,7 +8,7 @@ use std::convert::{AsRef, AsMut};
use ffi;
use err::{PyErr, PyResult, PyDowncastError};
use conversion::{ToPyObject, IntoPyObject};
use python::{Python, ToPythonPointer, IntoPythonPointer};
use python::{AsPy, Python, ToPythonPointer, IntoPythonPointer};
use objects::PyObject;
use typeob::{PyTypeInfo, PyObjectAlloc};
@ -312,13 +312,17 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
/// Casts the PyObject to a concrete Python object type.
/// Fails with `PyDowncastError` if the object is not of the expected type.
#[inline]
pub fn cast_as<'s, D>(&'s self) -> Result<&'s D, PyDowncastError<'p>>
pub fn cast_as<D>(&'p self) -> Result<&'p D, PyDowncastError<'p>>
where D: PyTypeInfo
{
let checked = unsafe { ffi::PyObject_TypeCheck(self.inner, D::type_object()) != 0 };
if checked {
Ok( unsafe { Py::<D>::unchecked_downcast_borrow_from(self) })
Ok(
unsafe {
let offset = <D as PyTypeInfo>::offset();
let ptr = (self.inner as *mut u8).offset(offset) as *mut D;
ptr.as_ref().unwrap() })
} else {
Err(PyDowncastError(self.py(), None))
}
@ -337,9 +341,18 @@ impl<'p, T> Py<'p, T> where T: PyTypeInfo
/// Extracts some type from the Python object.
/// This is a wrapper function around `FromPyObject::extract()`.
#[inline]
pub fn extract<D>(&'p self) -> PyResult<D> where D: ::conversion::FromPyObject<'p>
pub fn extract<D>(self) -> PyResult<D> where D: ::conversion::FromPyObject<'p>
{
::conversion::FromPyObject::extract(&self)
::conversion::FromPyObject::extract(self)
}
}
impl<'p, T> AsPy<'p> for Py<'p, T> {
/// Retrieve Python instance, the GIL is already acquired and
/// stays acquired for the lifetime `'p`.
#[inline]
fn py<'a>(&'a self) -> Python<'p> {
unsafe { Python::assume_gil_acquired() }
}
}
@ -406,22 +419,21 @@ impl<'p, T> AsMut<T> for Py<'p, T> where T: PyTypeInfo {
}
}
impl<'source, T> ::FromPyObject<'source> for &'source T
where T: PyTypeInfo
{
#[inline]
default fn extract<S>(py: &'source Py<'source, S>) -> PyResult<&'source T>
where S: PyTypeInfo
{
Ok(py.cast_as()?)
}
}
//impl<'source, T> ::FromPyObject<'source> for &'source T
// where T: PyTypeInfo
//{
// #[inline]
// default fn extract<S: 'source>(py: Py<'source, S>) -> PyResult<&'source T>
// where S: PyTypeInfo
// {
// Ok(py.cast_as()?)
// }
//}
impl<'source, T> ::FromPyObject<'source> for Py<'source, T>
where T: PyTypeInfo
impl<'source, T> ::FromPyObject<'source> for Py<'source, T> where T: PyTypeInfo
{
#[inline]
default fn extract<S>(py: &'source Py<'source, S>) -> PyResult<Py<'source, T>>
default fn extract<S>(py: Py<'source, S>) -> PyResult<Py<'source, T>>
where S: PyTypeInfo
{
let checked = unsafe { ffi::PyObject_TypeCheck(py.inner, T::type_object()) != 0 };
@ -448,7 +460,6 @@ impl <'a, T> ToPyObject for Py<'a, T> {
}
}
impl <'a, T> IntoPyObject for Py<'a, T> {
#[inline]

View file

@ -188,26 +188,26 @@ pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_na
type_object.tp_basicsize = <T as PyTypeInfo>::size() as ffi::Py_ssize_t;
// GC support
<T as class::gc::PyGCProtocolImpl>::update_type_object(type_object);
//<T as class::gc::PyGCProtocolImpl>::update_type_object(type_object);
// descriptor protocol
<T as class::descr::PyDescrProtocolImpl>::tp_as_descr(type_object);
//<T as class::descr::PyDescrProtocolImpl>::tp_as_descr(type_object);
// iterator methods
// <T as class::iter::PyIterProtocolImpl>::tp_as_iter(type_object);
// basic methods
<T as class::basic::PyObjectProtocolImpl>::tp_as_object(type_object);
//<T as class::basic::PyObjectProtocolImpl>::tp_as_object(type_object);
// number methods
if let Some(meth) = <T as class::number::PyNumberProtocolImpl>::tp_as_number() {
/*if let Some(meth) = <T as class::number::PyNumberProtocolImpl>::tp_as_number() {
static mut NB_METHODS: ffi::PyNumberMethods = ffi::PyNumberMethods_INIT;
*(unsafe { &mut NB_METHODS }) = meth;
type_object.tp_as_number = unsafe { &mut NB_METHODS };
mem::forget(meth);
} else {
type_object.tp_as_number = 0 as *mut ffi::PyNumberMethods;
}
}*/
// mapping methods
if let Some(meth) = <T as class::mapping::PyMappingProtocolImpl>::tp_as_mapping() {
@ -220,7 +220,7 @@ pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_na
}
// sequence methods
if let Some(meth) = <T as class::sequence::PySequenceProtocolImpl>::tp_as_sequence() {
/*if let Some(meth) = <T as class::sequence::PySequenceProtocolImpl>::tp_as_sequence() {
static mut SQ_METHODS: ffi::PySequenceMethods = ffi::PySequenceMethods_INIT;
*(unsafe { &mut SQ_METHODS }) = meth;
type_object.tp_as_sequence = unsafe { &mut SQ_METHODS };
@ -277,7 +277,7 @@ pub fn initialize_type<'p, T>(py: Python<'p>, module_name: Option<&str>, type_na
// strange
mem::forget(props);
}
}*/
// register type object
unsafe {
@ -328,6 +328,7 @@ fn py_class_method_defs<T>() -> (Option<ffi::newfunc>,
_ => (),
}
}
/*
for def in <T as class::basic::PyObjectProtocolImpl>::methods() {
defs.push(def.as_method_def())
}
@ -345,7 +346,7 @@ fn py_class_method_defs<T>() -> (Option<ffi::newfunc>,
}
for def in <T as class::descr::PyDescrProtocolImpl>::methods() {
defs.push(def.as_method_def())
}
}*/
(new, call, defs)
}

View file

@ -24,17 +24,19 @@ fn test_basics() {
struct Test {}
#[py::proto]
impl PyMappingProtocol for Test {
fn __getitem__(&self, idx: &PyObject) -> PyResult<PyObject> {
if let Ok(slice) = PySlice::downcast_from(py, idx.clone_ref(py)) {
let indices = slice.indices(py, 1000)?;
impl<'p> PyMappingProtocol<'p> for Test {
fn __getitem__(&self, idx: Py<'p, PyObject>) -> PyResult<Py<'p, PyObject>> {
let py = self.py();
if let Ok(slice) = idx.cast_as::<PySlice>() {
let indices = slice.indices(1000)?;
if indices.start == 100 && indices.stop == 200 && indices.step == 1 {
return Ok("slice".to_py_object(py).into_object())
return Ok("slice".to_object(py).into_object())
}
}
else if let Ok(idx) = idx.extract::<isize>(py) {
else if let Ok(idx) = idx.extract::<isize>() {
if idx == 1 {
return Ok("int".to_py_object(py).into_object())
return Ok("int".to_object(py).into_object())
}
}
Err(PyErr::new::<exc::ValueError, _>(py, "error"))
@ -46,9 +48,9 @@ fn test_cls_impl() {
let gil = Python::acquire_gil();
let py = gil.python();
let ob = Test::create_instance(py).unwrap();
let ob = py.init(Test{});
let d = PyDict::new(py);
d.set_item(py, "ob", ob).unwrap();
d.set_item("ob", ob).unwrap();
py.run("assert ob[1] == 'int'", None, Some(&d)).unwrap();
py.run("assert ob[100:200:1] == 'slice'", None, Some(&d)).unwrap();