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 { impl<'p> _pyo3::python::AsPy<'p> for &'p #cls {
// #[inline] #[inline]
// fn py<'a>(&'a self) -> _pyo3::Python<'p> { fn py<'a>(&'a self) -> _pyo3::Python<'p> {
// unsafe { _pyo3::python::Python::assume_gil_acquired() } unsafe { _pyo3::python::Python::assume_gil_acquired() }
// } }
//} }
impl<'p> _pyo3::python::AsPy<'p> for &'p mut #cls { impl<'p> _pyo3::python::AsPy<'p> for &'p mut #cls {
#[inline] #[inline]

View file

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

View file

@ -6,7 +6,7 @@ use libc;
use pyptr::Py; use pyptr::Py;
use python::{Python, IntoPythonPointer}; use python::{Python, IntoPythonPointer};
use objects::exc; use objects::{exc, PyObject};
use conversion::IntoPyObject; use conversion::IntoPyObject;
use ffi::{self, Py_hash_t}; use ffi::{self, Py_hash_t};
use err::{PyErr, PyResult}; 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 pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
where F: FnOnce(Python<'p>) -> PyResult<T>, where F: FnOnce(Python<'p>) -> PyResult<T>,
F: panic::UnwindSafe, F: panic::UnwindSafe,
@ -200,15 +192,20 @@ pub unsafe fn handle<'p, F, T, C>(location: &str, _c: C, f: F) -> C::R
ret ret
} }
pub unsafe fn handle_cb<F, T, C>(location: &str, _c: C, f: F) -> C::R #[allow(unused_mut)]
where F: FnOnce(Python) -> PyResult<T>, 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, F: panic::UnwindSafe,
Slf: ::typeob::PyTypeInfo,
C: CallbackConverter<T> C: CallbackConverter<T>
{ {
let guard = AbortOnDrop(location); let guard = AbortOnDrop(location);
let ret = panic::catch_unwind(|| { let ret = panic::catch_unwind(|| {
let py = Python::assume_gil_acquired(); 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) => { Ok(val) => {
C::convert(val, py) 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 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 { unsafe {
ffi::PyErr_SetString(ffi::PyExc_SystemError, "Rust panic\0".as_ptr() as *const i8); ffi::PyErr_SetString(ffi::PyExc_SystemError, "Rust panic\0".as_ptr() as *const i8);
} }

View file

@ -8,6 +8,7 @@
use ffi; use ffi;
use err::PyResult; use err::PyResult;
use python::Python;
use callback::PyObjectCallbackConverter; use callback::PyObjectCallbackConverter;
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use class::methods::PyMethodDef; use class::methods::PyMethodDef;
@ -17,15 +18,19 @@ use class::methods::PyMethodDef;
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PyAsyncProtocol<'p>: PyTypeInfo + Sized + 'static { 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_type: Option<Self::ExcType>,
exc_value: Option<Self::ExcValue>, exc_value: Option<Self::ExcValue>,
traceback: Option<Self::Traceback>) 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] #[inline]
fn am_await() -> Option<ffi::unaryfunc> { 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] #[inline]
fn am_aiter() -> Option<ffi::unaryfunc> { 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] #[inline]
fn am_anext() -> Option<ffi::unaryfunc> { 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 //! more information on python async support
//! https://docs.python.org/3/reference/datamodel.html#basic-customization //! https://docs.python.org/3/reference/datamodel.html#basic-customization
use std;
use std::os::raw::c_int; use std::os::raw::c_int;
use ::{Py, CompareOp}; use ::{Py, CompareOp};
use ffi; use ffi;
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use python::{Python}; use python::{Python, IntoPythonPointer};
use objects::{exc, PyObject}; use objects::{exc, PyObject};
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use conversion::{ToPyObject, FromPyObject}; use conversion::{ToPyObject, FromPyObject, IntoPyObject};
use callback::{PyObjectCallbackConverter, HashConverter, UnitCallbackConverter, use callback::{PyObjectCallbackConverter, HashConverter, UnitCallbackConverter,
BoolCallbackConverter}; BoolCallbackConverter};
use class::methods::PyMethodDef; use class::methods::PyMethodDef;
@ -28,29 +29,34 @@ use class::methods::PyMethodDef;
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PyObjectProtocol<'p>: PyTypeInfo + Sized + 'static { 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!()} -> 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!()} -> 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!()} -> 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!()} -> 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!()} -> Self::Result where Self: PyObjectRichcmpProtocol<'p> {unimplemented!()}
} }
@ -158,11 +164,12 @@ impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectProtocol<'p>
None None
} }
} }
impl<'p, T> PyObjectGetAttrProtocolImpl for T where T: PyObjectGetAttrProtocol<'p> impl<T> PyObjectGetAttrProtocolImpl for T where T: for<'p> PyObjectGetAttrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_getattro() -> Option<ffi::binaryfunc> { 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 None
} }
} }
impl<'p, T> PyObjectSetAttrProtocolImpl for T where T: PyObjectSetAttrProtocol<'p> impl<T> PyObjectSetAttrProtocolImpl for T where T: for<'p> PyObjectSetAttrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_setattro() -> Option<ffi::setattrofunc> { fn tp_setattro() -> 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, name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'p> where T: for<'p> PyObjectSetAttrProtocol<'p>
{ {
const LOCATION: &'static str = "T.__setattr__()"; const LOCATION: &'static str = "T.__setattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| { ::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() { if value.is_null() {
return Err(PyErr::new::<exc::NotImplementedError, _>( return Err(PyErr::new::<exc::NotImplementedError, _>(
py, format!("Subscript deletion not supported by {:?}", 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 name = ::PyObject::from_borrowed_ptr(py, name);
let value = ::PyObject::from_borrowed_ptr(py, value); let value = ::PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(name).extract() { match name.extract() {
Ok(name) => match ::callback::unref(value).extract() { Ok(name) => match value.extract() {
Ok(value) => { Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__setattr__(py, name, value).into()
slf.as_ref().__setattr__(name, value).into()
}, },
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
}, },
@ -225,24 +231,23 @@ impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectProtocol<'p>
None None
} }
} }
impl<'p, T> PyObjectDelAttrProtocolImpl for T where T: PyObjectDelAttrProtocol<'p> impl<T> PyObjectDelAttrProtocolImpl for T where T: for<'p> PyObjectDelAttrProtocol<'p>
{ {
#[inline] #[inline]
default fn tp_delattro() -> Option<ffi::setattrofunc> { 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, name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PyObjectDelAttrProtocol<'p> where T: for<'p> PyObjectDelAttrProtocol<'p>
{ {
const LOCATION: &'static str = "T.__detattr__()"; const LOCATION: &'static str = "T.__detattr__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| { ::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() { if value.is_null() {
let name = ::PyObject::from_borrowed_ptr(py, name); let name = ::PyObject::from_borrowed_ptr(py, name);
match ::callback::unref(name).extract() { match name.extract() {
Ok(name) => { Ok(name) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__delattr__(py, name).into()
slf.as_ref().__delattr__(name).into()
}, },
Err(e) => Err(e.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 impl<T> PyObjectDelAttrProtocolImpl for T
where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p> where T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_delattro() -> Option<ffi::setattrofunc> { 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, name: *mut ffi::PyObject,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PyObjectSetAttrProtocol<'p> + PyObjectDelAttrProtocol<'p> where T: for<'p> PyObjectSetAttrProtocol<'p> + for<'p> PyObjectDelAttrProtocol<'p>
{ {
const LOCATION: &'static str = "T.__detattr__()"; 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); let name = ::PyObject::from_borrowed_ptr(py, name);
if value.is_null() { if value.is_null() {
match ::callback::unref(name).extract() { match name.extract() {
Ok(name) => { Ok(name) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__delattr__(py, name).into()
slf.as_ref().__delattr__(name).into()
}, },
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
} else { } else {
let value = ::PyObject::from_borrowed_ptr(py, value); let value = ::PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(name).extract() { match name.extract() {
Ok(name) => match ::callback::unref(value).extract() { Ok(name) => match value.extract() {
Ok(value) => { Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__setattr__(py, name, value).into()
slf.as_ref().__setattr__(name, value).into()
}, },
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
}, },
@ -308,11 +311,12 @@ impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectProtocol<'p>
None None
} }
} }
impl<'p, T> PyObjectStrProtocolImpl for T where T: PyObjectStrProtocol<'p> impl<T> PyObjectStrProtocolImpl for T where T: for<'p> PyObjectStrProtocol<'p>
{ {
#[inline] #[inline]
fn tp_str() -> Option<ffi::unaryfunc> { 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 None
} }
} }
impl<'p, T> PyObjectReprProtocolImpl for T where T: PyObjectReprProtocol<'p> impl<T> PyObjectReprProtocolImpl for T where T: for<'p> PyObjectReprProtocol<'p>
{ {
#[inline] #[inline]
fn tp_repr() -> Option<ffi::unaryfunc> { 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 None
} }
} }
impl<'p, T> PyObjectHashProtocolImpl for T where T: PyObjectHashProtocol<'p> impl<T> PyObjectHashProtocolImpl for T where T: for<'p> PyObjectHashProtocol<'p>
{ {
#[inline] #[inline]
fn tp_hash() -> Option<ffi::hashfunc> { 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 None
} }
} }
impl<'p, T> PyObjectBoolProtocolImpl for T where T: PyObjectBoolProtocol<'p> impl<T> PyObjectBoolProtocolImpl for T where T: for<'p> PyObjectBoolProtocol<'p>
{ {
#[inline] #[inline]
fn nb_bool() -> Option<ffi::inquiry> { 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 None
} }
} }
impl<'p, T> PyObjectRichcmpProtocolImpl for T where T: PyObjectRichcmpProtocol<'p> impl<T> PyObjectRichcmpProtocolImpl for T where T: for<'p> PyObjectRichcmpProtocol<'p>
{ {
#[inline] #[inline]
fn tp_richcompare() -> Option<ffi::richcmpfunc> { fn tp_richcompare() -> Option<ffi::richcmpfunc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject, unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject, arg: *mut ffi::PyObject,
op: c_int) -> *mut ffi::PyObject op: c_int) -> *mut ffi::PyObject
where T: PyObjectRichcmpProtocol<'p> where T: for<'p> PyObjectRichcmpProtocol<'p>
{ {
const LOCATION: &'static str = concat!(stringify!(T), ".__richcmp__()"); 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) => { Ok(op) => {
let arg = PyObject::from_borrowed_ptr(py, arg); let arg = PyObject::from_borrowed_ptr(py, arg);
match ::callback::unref(arg).extract() { match arg.extract() {
Ok(arg) => { Ok(arg) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.as_ref().__richcmp__(py, arg, op).into()
slf.as_ref().__richcmp__(arg, op).into()
} }
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
} }
}, },
Err(e) => Err(e) 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>) Some(wrap::<T>)
} }

View file

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

View file

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

View file

@ -9,6 +9,7 @@ use std::os::raw::c_int;
use ffi; use ffi;
use err::PyResult; use err::PyResult;
use python::Python;
use objects::{PyObject, PyType}; use objects::{PyObject, PyType};
use callback::{PyObjectCallbackConverter, UnitCallbackConverter}; use callback::{PyObjectCallbackConverter, UnitCallbackConverter};
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
@ -20,16 +21,16 @@ use conversion::{ToPyObject, FromPyObject};
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PyDescrProtocol<'p>: PyTypeInfo { 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!() } -> 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!() } -> 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!() } -> 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!() } -> Self::Result where Self: PyDescrSetNameProtocol<'p> { unimplemented!() }
} }
@ -65,10 +66,10 @@ impl<'p, T> PyDescrGetProtocolImpl for T where T: PyDescrProtocol<'p> {
None 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> { 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 { pub trait PyDescrSetProtocolImpl {
@ -79,10 +80,10 @@ impl<'p, T> PyDescrSetProtocolImpl for T where T: PyDescrProtocol<'p> {
None 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> { 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 /// GC support
pub trait PyGCProtocol<'p> : PyTypeInfo { 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 { 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(()) Ok(())
} }
default fn __clear__(&self) {} default fn __clear__(&'p mut self, _py: Python<'p>) {}
} }
#[doc(hidden)] #[doc(hidden)]
@ -79,10 +80,10 @@ impl <'a> PyVisit<'a> {
} }
#[doc(hidden)] #[doc(hidden)]
unsafe extern "C" fn tp_traverse<'p, T>(slf: *mut ffi::PyObject, unsafe extern "C" fn tp_traverse<T>(slf: *mut ffi::PyObject,
visit: ffi::visitproc, visit: ffi::visitproc,
arg: *mut c_void) -> c_int arg: *mut c_void) -> c_int
where T: PyGCProtocol<'p> where T: for<'p> PyGCProtocol<'p>
{ {
const LOCATION: &'static str = concat!(stringify!(T), ".__traverse__()"); const LOCATION: &'static str = concat!(stringify!(T), ".__traverse__()");
@ -91,7 +92,7 @@ unsafe extern "C" fn tp_traverse<'p, T>(slf: *mut ffi::PyObject,
let visit = PyVisit { visit: visit, arg: arg, _py: py }; let visit = PyVisit { visit: visit, arg: arg, _py: py };
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); 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, Ok(()) => 0,
Err(PyTraverseError(code)) => code Err(PyTraverseError(code)) => code
}; };
@ -99,15 +100,15 @@ unsafe extern "C" fn tp_traverse<'p, T>(slf: *mut ffi::PyObject,
ret ret
} }
unsafe extern "C" fn tp_clear<'p, T>(slf: *mut ffi::PyObject) -> c_int unsafe extern "C" fn tp_clear<T>(slf: *mut ffi::PyObject) -> c_int
where T: PyGCProtocol<'p> where T: for<'p> PyGCProtocol<'p>
{ {
const LOCATION: &'static str = concat!(stringify!(T), ".__clear__()"); const LOCATION: &'static str = concat!(stringify!(T), ".__clear__()");
let guard = AbortOnDrop(LOCATION); let guard = AbortOnDrop(LOCATION);
let py = Python::assume_gil_acquired(); let py = Python::assume_gil_acquired();
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); let slf: Py<T> = Py::from_borrowed_ptr(py, slf);
T::__clear__(&slf); T::__clear__(slf.as_mut(), py);
mem::forget(guard); mem::forget(guard);
0 0
} }

View file

@ -8,6 +8,7 @@
use ffi; use ffi;
use err::PyResult; use err::PyResult;
use python::Python;
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use callback::PyObjectCallbackConverter; use callback::PyObjectCallbackConverter;
@ -15,9 +16,11 @@ use callback::PyObjectCallbackConverter;
/// Iterator protocol /// Iterator protocol
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PyIterProtocol<'p> : PyTypeInfo { 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] #[inline]
fn tp_iter() -> Option<ffi::getiterfunc> { 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 impl<T> PyIterNextProtocolImpl for T where T: for<'p> PyIterNextProtocol<'p>
where T: PyIterNextProtocol<'p>
{ {
#[inline] #[inline]
fn tp_iternext() -> Option<ffi::iternextfunc> { 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,18 +3,45 @@
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_unary_func { macro_rules! py_unary_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => { ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {
py_unary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject); py_unary_func!($trait, $class::$f, $res_type, $conv, *mut $crate::ffi::PyObject);
}; };
($trait:ident, $class:ident :: $f:ident, $conv:expr, $res_type:ty) => {{ ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty, $ret_type:ty) => {{
unsafe extern "C" fn wrap<'a, T>(slf: *mut $crate::ffi::PyObject) -> $res_type #[allow(unused_mut)]
where T: $trait<'a> 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), "()"); 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);
slf.as_ref().$f().into() 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>) Some(wrap::<$class>)
}} }}
@ -22,16 +49,60 @@ macro_rules! py_unary_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_len_func { macro_rules! py_unary_func_self {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{ ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {{
unsafe extern "C" fn wrap<'a, T>(slf: *mut $crate::ffi::PyObject) unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject)
-> $crate::ffi::Py_ssize_t -> *mut $crate::ffi::PyObject
where T: $trait<'a> where T: for<'p> $trait<'p> + $crate::ToPyObject + $crate::IntoPyObject
{ {
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); 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);
slf.as_ref().$f().into() 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<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::cb_unary::<T, _, _, _>(LOCATION, slf, $conv, |py, slf| {
slf.$f(py).into()
}) })
} }
Some(wrap::<$class>) Some(wrap::<$class>)
@ -41,23 +112,53 @@ macro_rules! py_len_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_binary_func{ macro_rules! py_binary_func{
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{ ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {
unsafe extern "C" fn wrap<'a, T>(slf: *mut ffi::PyObject, py_binary_func!($trait, $class::$f, $res_type, $conv, *mut $crate::ffi::PyObject)
arg: *mut ffi::PyObject) -> *mut ffi::PyObject };
where T: $trait<'a> ($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), "()"); 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); let arg = $crate::PyObject::from_borrowed_ptr(py, arg);
match $crate::callback::unref(arg).extract() { let result = match arg.extract() {
Ok(arg) => { Ok(arg) => {
let slf: $crate::Py<T> = $crate::Py::from_borrowed_ptr(py, slf); slf.$f(py, arg).into()
slf.as_ref().$f(arg).into()
} }
Err(e) => Err(e.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>) Some(wrap::<$class>)
}} }}
@ -66,17 +167,43 @@ macro_rules! py_binary_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_ssizearg_func { macro_rules! py_ssizearg_func {
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{ ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {{
unsafe extern "C" fn wrap<'a, T>(slf: *mut $crate::ffi::PyObject, #[allow(unused_mut)]
arg: $crate::Py_ssize_t) unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
-> *mut $crate::ffi::PyObject arg: $crate::Py_ssize_t) -> *mut $crate::ffi::PyObject
where T: $trait<'a> where T: for<'p> $trait<'p> + ToPyObject + IntoPyObject
{ {
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); 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);
slf.as_ref().$f(arg as isize).into() 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>) Some(wrap::<$class>)
}} }}
@ -85,31 +212,58 @@ macro_rules! py_ssizearg_func {
#[macro_export] #[macro_export]
#[doc(hidden)] #[doc(hidden)]
macro_rules! py_ternary_func{ macro_rules! py_ternary_func{
($trait:ident, $class:ident :: $f:ident, $conv:expr) => { ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty) => {
py_ternary_func!($trait, $class::$f, $conv, *mut $crate::ffi::PyObject); py_ternary_func!($trait, $class::$f, $res_type, $conv, *mut $crate::ffi::PyObject);
}; };
($trait:ident, $class:ident :: $f:ident, $conv:expr, $res_type: ty) => {{ ($trait:ident, $class:ident :: $f:ident, $res_type:ty, $conv:ty, $return_type:ty) => {{
unsafe extern "C" fn wrap<'p, T>(slf: *mut $crate::ffi::PyObject, #[allow(unused_mut)]
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject,
arg1: *mut $crate::ffi::PyObject, arg1: *mut $crate::ffi::PyObject,
arg2: *mut $crate::ffi::PyObject) -> $res_type arg2: *mut $crate::ffi::PyObject) -> $return_type
where T: $trait<'p> where T: for<'p> $trait<'p>
{ {
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
$crate::callback::handle(LOCATION, $conv, |py| { let guard = $crate::callback::AbortOnDrop(LOCATION);
let slf: $crate::Py<T> = $crate::Py::from_borrowed_ptr(py, slf); 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 arg1 = $crate::PyObject::from_borrowed_ptr(py, arg1);
let arg2 = $crate::PyObject::from_borrowed_ptr(py, arg2); let arg2 = $crate::PyObject::from_borrowed_ptr(py, arg2);
match ::callback::unref(arg1).extract() { let result = match arg1.extract() {
Ok(arg1) => match ::callback::unref(arg2).extract() { Ok(arg1) => match arg2.extract() {
Ok(arg2) => Ok(arg2) => slf.$f(py, arg1, arg2).into(),
slf.$f(arg1, arg2).into(), Err(e) => Err(e.into())
Err(e) => Err(e),
}, },
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>) Some(wrap::<T>)
}} }}
} }

View file

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

View file

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

View file

@ -5,119 +5,120 @@
use ffi; use ffi;
use err::PyResult; use err::PyResult;
use python::Python;
use callback::PyObjectCallbackConverter; use callback::PyObjectCallbackConverter;
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use class::methods::PyMethodDef; use class::methods::PyMethodDef;
use class::basic::PyObjectProtocolImpl; use class::basic::PyObjectProtocolImpl;
use ::{c_void, ToPyObject, FromPyObject}; use ::{c_void, ToPyObject, IntoPyObject, FromPyObject};
/// Number interface /// Number interface
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PyNumberProtocol<'p>: PyTypeInfo { 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!()} -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> 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!() } -> Self::Result where Self: PyNumberIOrProtocol<'p> { unimplemented!() }
// Unary arithmetic // Unary arithmetic
fn __neg__(&self) fn __neg__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberNegProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberNegProtocol<'p> { unimplemented!() }
fn __pos__(&self) fn __pos__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberPosProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberPosProtocol<'p> { unimplemented!() }
fn __abs__(&self) fn __abs__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberAbsProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberAbsProtocol<'p> { unimplemented!() }
fn __invert__(&self) fn __invert__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberInvertProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberInvertProtocol<'p> { unimplemented!() }
fn __complex__(&self) fn __complex__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberComplexProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberComplexProtocol<'p> { unimplemented!() }
fn __int__(&self) fn __int__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberIntProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberIntProtocol<'p> { unimplemented!() }
fn __float__(&self) fn __float__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberFloatProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberFloatProtocol<'p> { unimplemented!() }
fn __round__(&self) fn __round__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberRoundProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberRoundProtocol<'p> { unimplemented!() }
fn __index__(&self) fn __index__(&'p self, py: Python<'p>)
-> Self::Result where Self: PyNumberIndexProtocol<'p> { unimplemented!() } -> Self::Result where Self: PyNumberIndexProtocol<'p> { unimplemented!() }
} }
@ -505,9 +506,9 @@ trait PyNumberAddProtocolImpl {
impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> { impl<'p, T> PyNumberAddProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_add() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberSubProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_subtract() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberMulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_multiply() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_matrix_multiply() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberTruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_true_divide() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_floor_divide() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberModProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_remainder() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberDivmodProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_divmod() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberPowProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_power() -> Option<ffi::ternaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberLShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_lshift() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_rshift() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberAndProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_and() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberXorProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_xor() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberOrProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_or() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIAddProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_add() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberISubProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_subtract() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIMulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_multiply() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIMatmulProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_matrix_multiply() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberITruedivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_true_divide() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIFloordivProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_floor_divide() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIModProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_remainder() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIPowProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_power() -> Option<ffi::ternaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberILShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_lshift() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIRShiftProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_rshift() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIAndProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_and() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIXorProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_xor() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIOrProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_inplace_or() -> Option<ffi::binaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberNegProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_negative() -> Option<ffi::unaryfunc> {None} 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] #[inline]
fn nb_negative() -> Option<ffi::unaryfunc> { 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> { impl<'p, T> PyNumberPosProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_positive() -> Option<ffi::unaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberAbsProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_absolute() -> Option<ffi::unaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberInvertProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_invert() -> Option<ffi::unaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIntProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_int() -> Option<ffi::unaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberFloatProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_float() -> Option<ffi::unaryfunc> {None} 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> { 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> { impl<'p, T> PyNumberIndexProtocolImpl for T where T: PyNumberProtocol<'p> {
default fn nb_index() -> Option<ffi::unaryfunc> {None} 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> { 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 std::os::raw::c_int;
use ::Py;
use ffi; use ffi;
use python::Python;
use err::{PyErr, PyResult}; use err::{PyErr, PyResult};
use objects::{exc, PyObject}; use objects::{exc, PyObject};
use callback::{PyObjectCallbackConverter, use callback::{PyObjectCallbackConverter,
LenResultConverter, UnitCallbackConverter, BoolCallbackConverter}; LenResultConverter, UnitCallbackConverter, BoolCallbackConverter};
use typeob::PyTypeInfo; use typeob::PyTypeInfo;
use conversion::{ToPyObject, FromPyObject}; use conversion::{ToPyObject, IntoPyObject, FromPyObject};
/// Sequece interface /// Sequece interface
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait PySequenceProtocol<'p>: PyTypeInfo + Sized + 'static { 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!() } 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!() } 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!() } 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!() } 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!() } 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!() } 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!() } 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!() } 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!() } 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] #[inline]
fn sq_length() -> Option<ffi::lenfunc> { 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] #[inline]
fn sq_item() -> Option<ffi::ssizeargfunc> { 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] #[inline]
fn sq_ass_item() -> Option<ffi::ssizeobjargproc> { fn sq_ass_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject, unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t, key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PySequenceSetItemProtocol<'p> where T: for<'p> PySequenceSetItemProtocol<'p>
{ {
const LOCATION: &'static str = "foo.__setitem__()"; const LOCATION: &'static str = "foo.__setitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| { ::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() { if value.is_null() {
Err(PyErr::new::<exc::NotImplementedError, _>( Err(PyErr::new::<exc::NotImplementedError, _>(
py, format!("Item deletion not supported by {:?}", py, format!("Item deletion not supported by {:?}", stringify!(T))))
stringify!(T))))
} else { } else {
let value = PyObject::from_borrowed_ptr(py, value); let value = PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(value).extract() { match value.extract() {
Ok(value) => { Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__setitem__(py, key as isize, value).into()
slf.as_ref().__setitem__(key as isize, value).into()
}, },
Err(e) => Err(e.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] #[inline]
default fn sq_del_item() -> Option<ffi::ssizeobjargproc> { default fn sq_del_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject, unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t, key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PySequenceDelItemProtocol<'p> where T: for<'p> PySequenceDelItemProtocol<'p>
{ {
const LOCATION: &'static str = "T.__detitem__()"; const LOCATION: &'static str = "T.__detitem__()";
::callback::handle(LOCATION, UnitCallbackConverter, |py| { ::callback::cb_unary::<T, _, _, _>(LOCATION, slf, UnitCallbackConverter, |py, slf| {
if value.is_null() { if value.is_null() {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__delitem__(py, key as isize).into()
slf.__delitem__(key as isize).into()
} else { } else {
Err(PyErr::new::<exc::NotImplementedError, _>( Err(PyErr::new::<exc::NotImplementedError, _>(
py, format!("Item assignment not supported by {:?}", 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 impl<T> PySequenceDelItemProtocolImpl for T
where T: PySequenceSetItemProtocol<'p> + PySequenceDelItemProtocol<'p> where T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>
{ {
#[inline] #[inline]
fn sq_del_item() -> Option<ffi::ssizeobjargproc> { fn sq_del_item() -> Option<ffi::ssizeobjargproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject, unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject,
key: ffi::Py_ssize_t, key: ffi::Py_ssize_t,
value: *mut ffi::PyObject) -> c_int value: *mut ffi::PyObject) -> c_int
where T: PySequenceSetItemProtocol<'p> + PySequenceDelItemProtocol<'p> where T: for<'p> PySequenceSetItemProtocol<'p> + for<'p> PySequenceDelItemProtocol<'p>
{ {
const LOCATION: &'static str = "T.__set/del_item__()"; 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() { if value.is_null() {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__delitem__(py, key as isize).into()
slf.__delitem__(key as isize).into()
} else { } else {
let value = ::PyObject::from_borrowed_ptr(py, value); let value = ::PyObject::from_borrowed_ptr(py, value);
match ::callback::unref(value).extract() { match value.extract() {
Ok(value) => { Ok(value) => {
let slf: Py<T> = Py::from_borrowed_ptr(py, slf); slf.__setitem__(py, key as isize, value).into()
slf.as_ref().__setitem__(key as isize, value).into()
}, },
Err(e) => Err(e.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] #[inline]
fn sq_contains() -> Option<ffi::objobjproc> { fn sq_contains() -> Option<ffi::objobjproc> {
unsafe extern "C" fn wrap<'p, T>(slf: *mut ffi::PyObject, py_binary_func!(PySequenceContainsProtocol,
arg: *mut ffi::PyObject) -> c_int T::__contains__, bool, BoolCallbackConverter, 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>)
} }
} }
@ -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] #[inline]
fn sq_concat() -> Option<ffi::binaryfunc> { 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 impl<T> PySequenceRepeatProtocolImpl for T
where T: PySequenceRepeatProtocol<'p> where T: for<'p> PySequenceRepeatProtocol<'p> + ToPyObject + IntoPyObject
{ {
#[inline] #[inline]
fn sq_repeat() -> Option<ffi::ssizeargfunc> { 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 impl<T> PySequenceInplaceConcatProtocolImpl for T
where T: PySequenceInplaceConcatProtocol<'p> where T: for<'p> PySequenceInplaceConcatProtocol<'p> + ToPyObject + IntoPyObject
{ {
#[inline] #[inline]
fn sq_inplace_concat() -> Option<ffi::binaryfunc> { fn sq_inplace_concat() -> Option<ffi::binaryfunc> {
py_binary_func!(PySequenceInplaceConcatProtocol, 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 impl<T> PySequenceInplaceRepeatProtocolImpl for T
where T: PySequenceInplaceRepeatProtocol<'p> where T: for<'p> PySequenceInplaceRepeatProtocol<'p> + ToPyObject + IntoPyObject
{ {
#[inline] #[inline]
fn sq_inplace_repeat() -> Option<ffi::ssizeargfunc> { 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. /// the inherent method `PyObject::extract()` can be used.
pub trait FromPyObject<'source> : Sized { pub trait FromPyObject<'source> : Sized {
/// Extracts `Self` from the source `PyObject`. /// 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; 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> 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 impl <'p, T: ?Sized> RefFromPyObject<'p> for T
where for<'a> &'a T: FromPyObject<'p> where for<'a> &'a T: FromPyObject<'p> + Sized
{ {
#[inline] #[inline]
fn with_extracted<F, R>(_py: Python<'p>, obj: &'p Py<'p, PyObject>, f: F) -> PyResult<R> 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) { match FromPyObject::extract(obj) {
Ok(val) => Ok(f(val)), Ok(val) => Ok(f(val)),
Err(e) => Err(e) Err(e) => Err(e)
} }
} }
} }*/
// Default IntoPyObject implementation // Default IntoPyObject implementation
impl <T> IntoPyObject for T where T: ToPyObject 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> { 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 where S: PyTypeInfo
{ {
if obj.as_ptr() == unsafe { ffi::Py_None() } { 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 objects::*;
pub use python::{AsPy, Python}; pub use python::{AsPy, Python};
pub use pythonrun::{GILGuard, GILProtected, prepare_freethreaded_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 use class::{CompareOp};
pub mod class; pub mod class;
pub use class::*; pub use class::*;

View file

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

View file

@ -71,7 +71,7 @@ macro_rules! pyobject_extract(
impl<'source> ::conversion::FromPyObject<'source> impl<'source> ::conversion::FromPyObject<'source>
for $t 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 where S: ::typeob::PyTypeInfo
{ {
$body $body

View file

@ -84,10 +84,11 @@ macro_rules! int_fits_larger_int(
} }
pyobject_extract!(obj to $rust_type => { pyobject_extract!(obj to $rust_type => {
let py = obj.py();
let val = try!(obj.extract::<$larger_type>()); let val = try!(obj.extract::<$larger_type>());
match cast::<$larger_type, $rust_type>(val) { match cast::<$larger_type, $rust_type>(val) {
Some(v) => Ok(v), 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 { 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 where S: PyTypeInfo
{ {
let ptr = py.as_ptr(); let ptr = py.as_ptr();

View file

@ -13,7 +13,7 @@ use ffi;
use python::{AsPy, Python, ToPythonPointer}; use python::{AsPy, Python, ToPythonPointer};
use super::{exc, PyObject}; use super::{exc, PyObject};
use err::{PyResult, PyErr}; use err::{PyResult, PyErr};
use conversion::{RefFromPyObject, ToPyObject}; use conversion::{ToPyObject}; //RefFromPyObject,
/// Represents a Python string. /// Represents a Python string.
pub struct PyString; pub struct PyString;
@ -243,21 +243,22 @@ impl ToPyObject for String {
} }
} }
/// Allows extracting strings from Python objects. // /// Allows extracting strings from Python objects.
/// Accepts Python `str` and `unicode` objects. // /// Accepts Python `str` and `unicode` objects.
pyobject_extract!(obj to Cow<'source, str> => { //pyobject_extract!(obj to Cow<'source, str> => {
try!(obj.cast_as::<PyString>()).to_string() // try!(obj.cast_as::<PyString>()).to_string()
}); //});
/// Allows extracting strings from Python objects. /// Allows extracting strings from Python objects.
/// Accepts Python `str` and `unicode` objects. /// Accepts Python `str` and `unicode` objects.
pyobject_extract!(obj to String => { 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> fn with_extracted<F, R>(py: Python<'p>, obj: &Py<'p, PyObject>, f: F) -> PyResult<R>
where F: FnOnce(&str) -> R where F: FnOnce(&str) -> R
{ {
@ -265,7 +266,7 @@ impl<'p> RefFromPyObject<'p> for str {
let s = try!(p.extract::<Cow<str>>()); let s = try!(p.extract::<Cow<str>>());
Ok(f(&s)) Ok(f(&s))
} }
} }*/
#[cfg(test)] #[cfg(test)]
mod 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,)+) { 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 where S: ::typeob::PyTypeInfo
{ {
let t = try!(obj.cast_as::<&PyTuple>()); let t = try!(obj.cast_as::<&PyTuple>());
let slice = t.as_slice(); let slice = t.as_slice();
if slice.len() == $length { if t.len() == $length {
Ok(( Ok((
$( try!(slice[$n].extract::<$T>()), )+ $( try!(t.get_item($n).extract::<$T>()), )+
)) ))
} else { } else {
Err(wrong_tuple_length(obj.py(), t, $length)) 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!(1, (ref0, 0, A));
tuple_conversion!(2, (ref0, 0, A), (ref1, 1, B)); //tuple_conversion!(2, (ref0, 0, A), (ref1, 1, B));
tuple_conversion!(3, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C)); //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!(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), //tuple_conversion!(5, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E)); // (ref4, 4, E));
tuple_conversion!(6, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D), //tuple_conversion!(6, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E), (ref5, 5, F)); // (ref4, 4, E), (ref5, 5, F));
tuple_conversion!(7, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D), //tuple_conversion!(7, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D),
(ref4, 4, E), (ref5, 5, F), (ref6, 6, G)); // (ref4, 4, E), (ref5, 5, F), (ref6, 6, G));
tuple_conversion!(8, (ref0, 0, A), (ref1, 1, B), (ref2, 2, C), (ref3, 3, D), //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)); // (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), //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)); // (ref4, 4, E), (ref5, 5, F), (ref6, 6, G), (ref7, 7, H), (ref8, 8, I));
// Empty tuple: // Empty tuple:

View file

@ -8,7 +8,7 @@ use std::convert::{AsRef, AsMut};
use ffi; use ffi;
use err::{PyErr, PyResult, PyDowncastError}; use err::{PyErr, PyResult, PyDowncastError};
use conversion::{ToPyObject, IntoPyObject}; use conversion::{ToPyObject, IntoPyObject};
use python::{Python, ToPythonPointer, IntoPythonPointer}; use python::{AsPy, Python, ToPythonPointer, IntoPythonPointer};
use objects::PyObject; use objects::PyObject;
use typeob::{PyTypeInfo, PyObjectAlloc}; 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. /// Casts the PyObject to a concrete Python object type.
/// Fails with `PyDowncastError` if the object is not of the expected type. /// Fails with `PyDowncastError` if the object is not of the expected type.
#[inline] #[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 where D: PyTypeInfo
{ {
let checked = unsafe { ffi::PyObject_TypeCheck(self.inner, D::type_object()) != 0 }; let checked = unsafe { ffi::PyObject_TypeCheck(self.inner, D::type_object()) != 0 };
if checked { 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 { } else {
Err(PyDowncastError(self.py(), None)) 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. /// Extracts some type from the Python object.
/// This is a wrapper function around `FromPyObject::extract()`. /// This is a wrapper function around `FromPyObject::extract()`.
#[inline] #[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 //impl<'source, T> ::FromPyObject<'source> for &'source T
where T: PyTypeInfo // where T: PyTypeInfo
{ //{
#[inline] // #[inline]
default fn extract<S>(py: &'source Py<'source, S>) -> PyResult<&'source T> // default fn extract<S: 'source>(py: Py<'source, S>) -> PyResult<&'source T>
where S: PyTypeInfo // where S: PyTypeInfo
{ // {
Ok(py.cast_as()?) // Ok(py.cast_as()?)
} // }
} //}
impl<'source, T> ::FromPyObject<'source> for Py<'source, T> impl<'source, T> ::FromPyObject<'source> for Py<'source, T> where T: PyTypeInfo
where T: PyTypeInfo
{ {
#[inline] #[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 where S: PyTypeInfo
{ {
let checked = unsafe { ffi::PyObject_TypeCheck(py.inner, T::type_object()) != 0 }; 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> { impl <'a, T> IntoPyObject for Py<'a, T> {
#[inline] #[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; type_object.tp_basicsize = <T as PyTypeInfo>::size() as ffi::Py_ssize_t;
// GC support // GC support
<T as class::gc::PyGCProtocolImpl>::update_type_object(type_object); //<T as class::gc::PyGCProtocolImpl>::update_type_object(type_object);
// descriptor protocol // descriptor protocol
<T as class::descr::PyDescrProtocolImpl>::tp_as_descr(type_object); //<T as class::descr::PyDescrProtocolImpl>::tp_as_descr(type_object);
// iterator methods // iterator methods
// <T as class::iter::PyIterProtocolImpl>::tp_as_iter(type_object); // <T as class::iter::PyIterProtocolImpl>::tp_as_iter(type_object);
// basic methods // basic methods
<T as class::basic::PyObjectProtocolImpl>::tp_as_object(type_object); //<T as class::basic::PyObjectProtocolImpl>::tp_as_object(type_object);
// number methods // 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; static mut NB_METHODS: ffi::PyNumberMethods = ffi::PyNumberMethods_INIT;
*(unsafe { &mut NB_METHODS }) = meth; *(unsafe { &mut NB_METHODS }) = meth;
type_object.tp_as_number = unsafe { &mut NB_METHODS }; type_object.tp_as_number = unsafe { &mut NB_METHODS };
mem::forget(meth); mem::forget(meth);
} else { } else {
type_object.tp_as_number = 0 as *mut ffi::PyNumberMethods; type_object.tp_as_number = 0 as *mut ffi::PyNumberMethods;
} }*/
// mapping methods // mapping methods
if let Some(meth) = <T as class::mapping::PyMappingProtocolImpl>::tp_as_mapping() { 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 // 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; static mut SQ_METHODS: ffi::PySequenceMethods = ffi::PySequenceMethods_INIT;
*(unsafe { &mut SQ_METHODS }) = meth; *(unsafe { &mut SQ_METHODS }) = meth;
type_object.tp_as_sequence = unsafe { &mut SQ_METHODS }; 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 // strange
mem::forget(props); mem::forget(props);
} }*/
// register type object // register type object
unsafe { unsafe {
@ -328,6 +328,7 @@ fn py_class_method_defs<T>() -> (Option<ffi::newfunc>,
_ => (), _ => (),
} }
} }
/*
for def in <T as class::basic::PyObjectProtocolImpl>::methods() { for def in <T as class::basic::PyObjectProtocolImpl>::methods() {
defs.push(def.as_method_def()) 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() { for def in <T as class::descr::PyDescrProtocolImpl>::methods() {
defs.push(def.as_method_def()) defs.push(def.as_method_def())
} }*/
(new, call, defs) (new, call, defs)
} }

View file

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