Avoid function definition in setters for readability
This commit is contained in:
parent
d678093509
commit
05effe26f1
|
@ -183,54 +183,13 @@ impl PyObjectMethods {
|
|||
where
|
||||
T: for<'p> PyObjectGetAttrProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn wrap<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
arg: *mut ffi::PyObject,
|
||||
) -> *mut ffi::PyObject
|
||||
where
|
||||
T: for<'p> PyObjectGetAttrProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
// Behave like python's __getattr__ (as opposed to __getattribute__) and check
|
||||
// for existing fields and methods first
|
||||
let existing = ffi::PyObject_GenericGetAttr(slf, arg);
|
||||
if existing.is_null() {
|
||||
// PyObject_HasAttr also tries to get an object and clears the error if it fails
|
||||
ffi::PyErr_Clear();
|
||||
} else {
|
||||
return Ok(existing);
|
||||
}
|
||||
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
let arg = py.from_borrowed_ptr::<PyAny>(arg);
|
||||
call_ref!(slf, __getattr__, arg)
|
||||
})
|
||||
}
|
||||
self.tp_getattro = Some(wrap::<T>);
|
||||
self.tp_getattro = tp_getattro::<T>();
|
||||
}
|
||||
pub fn set_richcompare<T>(&mut self)
|
||||
where
|
||||
T: for<'p> PyObjectRichcmpProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn wrap<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
arg: *mut ffi::PyObject,
|
||||
op: c_int,
|
||||
) -> *mut ffi::PyObject
|
||||
where
|
||||
T: for<'p> PyObjectRichcmpProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||
let arg = py.from_borrowed_ptr::<PyAny>(arg);
|
||||
|
||||
let op = extract_op(op)?;
|
||||
let arg = arg.extract()?;
|
||||
|
||||
slf.try_borrow()?.__richcmp__(arg, op).into()
|
||||
})
|
||||
}
|
||||
self.tp_richcompare = Some(wrap::<T>);
|
||||
self.tp_richcompare = tp_richcompare::<T>();
|
||||
}
|
||||
pub fn set_setattr<T>(&mut self)
|
||||
where
|
||||
|
@ -258,16 +217,70 @@ impl PyObjectMethods {
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_op(op: c_int) -> PyResult<CompareOp> {
|
||||
match op {
|
||||
ffi::Py_LT => Ok(CompareOp::Lt),
|
||||
ffi::Py_LE => Ok(CompareOp::Le),
|
||||
ffi::Py_EQ => Ok(CompareOp::Eq),
|
||||
ffi::Py_NE => Ok(CompareOp::Ne),
|
||||
ffi::Py_GT => Ok(CompareOp::Gt),
|
||||
ffi::Py_GE => Ok(CompareOp::Ge),
|
||||
_ => Err(PyErr::new::<exceptions::ValueError, _>(
|
||||
"tp_richcompare called with invalid comparison operator",
|
||||
)),
|
||||
fn tp_getattro<T>() -> Option<ffi::binaryfunc>
|
||||
where
|
||||
T: for<'p> PyObjectGetAttrProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn wrap<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
arg: *mut ffi::PyObject,
|
||||
) -> *mut ffi::PyObject
|
||||
where
|
||||
T: for<'p> PyObjectGetAttrProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
// Behave like python's __getattr__ (as opposed to __getattribute__) and check
|
||||
// for existing fields and methods first
|
||||
let existing = ffi::PyObject_GenericGetAttr(slf, arg);
|
||||
if existing.is_null() {
|
||||
// PyObject_HasAttr also tries to get an object and clears the error if it fails
|
||||
ffi::PyErr_Clear();
|
||||
} else {
|
||||
return Ok(existing);
|
||||
}
|
||||
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
let arg = py.from_borrowed_ptr::<PyAny>(arg);
|
||||
call_ref!(slf, __getattr__, arg)
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
}
|
||||
|
||||
fn tp_richcompare<T>() -> Option<ffi::richcmpfunc>
|
||||
where
|
||||
T: for<'p> PyObjectRichcmpProtocol<'p>,
|
||||
{
|
||||
fn extract_op(op: c_int) -> PyResult<CompareOp> {
|
||||
match op {
|
||||
ffi::Py_LT => Ok(CompareOp::Lt),
|
||||
ffi::Py_LE => Ok(CompareOp::Le),
|
||||
ffi::Py_EQ => Ok(CompareOp::Eq),
|
||||
ffi::Py_NE => Ok(CompareOp::Ne),
|
||||
ffi::Py_GT => Ok(CompareOp::Gt),
|
||||
ffi::Py_GE => Ok(CompareOp::Ge),
|
||||
_ => Err(PyErr::new::<exceptions::ValueError, _>(
|
||||
"tp_richcompare called with invalid comparison operator",
|
||||
)),
|
||||
}
|
||||
}
|
||||
unsafe extern "C" fn wrap<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
arg: *mut ffi::PyObject,
|
||||
op: c_int,
|
||||
) -> *mut ffi::PyObject
|
||||
where
|
||||
T: for<'p> PyObjectRichcmpProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||
let arg = py.from_borrowed_ptr::<PyAny>(arg);
|
||||
|
||||
let op = extract_op(op)?;
|
||||
let arg = arg.extract()?;
|
||||
|
||||
slf.try_borrow()?.__richcmp__(arg, op).into()
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
}
|
||||
|
|
|
@ -45,34 +45,48 @@ impl PyBufferProcs {
|
|||
where
|
||||
T: for<'p> PyBufferGetBufferProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn wrap<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
arg1: *mut ffi::Py_buffer,
|
||||
arg2: c_int,
|
||||
) -> c_int
|
||||
where
|
||||
T: for<'p> PyBufferGetBufferProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).into()
|
||||
})
|
||||
}
|
||||
self.bf_getbuffer = Some(wrap::<T>);
|
||||
self.bf_getbuffer = bf_getbuffer::<T>();
|
||||
}
|
||||
pub fn set_releasebuffer<T>(&mut self)
|
||||
where
|
||||
T: for<'p> PyBufferReleaseBufferProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg1: *mut ffi::Py_buffer)
|
||||
where
|
||||
T: for<'p> PyBufferReleaseBufferProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||
T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).into()
|
||||
})
|
||||
}
|
||||
self.bf_releasebuffer = Some(wrap::<T>);
|
||||
self.bf_releasebuffer = bf_releasebuffer::<T>();
|
||||
}
|
||||
}
|
||||
|
||||
fn bf_getbuffer<T>() -> Option<ffi::getbufferproc>
|
||||
where
|
||||
T: for<'p> PyBufferGetBufferProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn wrap<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
arg1: *mut ffi::Py_buffer,
|
||||
arg2: c_int,
|
||||
) -> c_int
|
||||
where
|
||||
T: for<'p> PyBufferGetBufferProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
T::bf_getbuffer(slf.try_borrow_mut()?, arg1, arg2).into()
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
}
|
||||
|
||||
fn bf_releasebuffer<T>() -> Option<ffi::releasebufferproc>
|
||||
where
|
||||
T: for<'p> PyBufferReleaseBufferProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn wrap<T>(slf: *mut ffi::PyObject, arg1: *mut ffi::Py_buffer)
|
||||
where
|
||||
T: for<'p> PyBufferReleaseBufferProtocol<'p>,
|
||||
{
|
||||
crate::callback_body!(py, {
|
||||
let slf = py.from_borrowed_ptr::<crate::PyCell<T>>(slf);
|
||||
T::bf_releasebuffer(slf.try_borrow_mut()?, arg1).into()
|
||||
})
|
||||
}
|
||||
Some(wrap::<T>)
|
||||
}
|
||||
|
|
|
@ -35,52 +35,14 @@ impl PyGCMethods {
|
|||
where
|
||||
T: for<'p> PyGCTraverseProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn tp_traverse<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
visit: ffi::visitproc,
|
||||
arg: *mut c_void,
|
||||
) -> c_int
|
||||
where
|
||||
T: for<'p> PyGCTraverseProtocol<'p>,
|
||||
{
|
||||
let pool = crate::GILPool::new();
|
||||
let py = pool.python();
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
|
||||
let visit = PyVisit {
|
||||
visit,
|
||||
arg,
|
||||
_py: py,
|
||||
};
|
||||
let borrow = slf.try_borrow();
|
||||
if let Ok(borrow) = borrow {
|
||||
match borrow.__traverse__(visit) {
|
||||
Ok(()) => 0,
|
||||
Err(PyTraverseError(code)) => code,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
self.tp_traverse = Some(tp_traverse::<T>);
|
||||
self.tp_traverse = tp_traverse::<T>();
|
||||
}
|
||||
|
||||
pub fn set_clear<T>(&mut self)
|
||||
where
|
||||
T: for<'p> PyGCClearProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn tp_clear<T>(slf: *mut ffi::PyObject) -> c_int
|
||||
where
|
||||
T: for<'p> PyGCClearProtocol<'p>,
|
||||
{
|
||||
let pool = crate::GILPool::new();
|
||||
let py = pool.python();
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
|
||||
slf.borrow_mut().__clear__();
|
||||
0
|
||||
}
|
||||
self.tp_clear = Some(tp_clear::<T>);
|
||||
self.tp_clear = tp_clear::<T>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,3 +71,56 @@ impl<'p> PyVisit<'p> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tp_traverse<T>() -> Option<ffi::traverseproc>
|
||||
where
|
||||
T: for<'p> PyGCTraverseProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn tp_traverse<T>(
|
||||
slf: *mut ffi::PyObject,
|
||||
visit: ffi::visitproc,
|
||||
arg: *mut c_void,
|
||||
) -> c_int
|
||||
where
|
||||
T: for<'p> PyGCTraverseProtocol<'p>,
|
||||
{
|
||||
let pool = crate::GILPool::new();
|
||||
let py = pool.python();
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
|
||||
let visit = PyVisit {
|
||||
visit,
|
||||
arg,
|
||||
_py: py,
|
||||
};
|
||||
let borrow = slf.try_borrow();
|
||||
if let Ok(borrow) = borrow {
|
||||
match borrow.__traverse__(visit) {
|
||||
Ok(()) => 0,
|
||||
Err(PyTraverseError(code)) => code,
|
||||
}
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
Some(tp_traverse::<T>)
|
||||
}
|
||||
|
||||
fn tp_clear<T>() -> Option<ffi::inquiry>
|
||||
where
|
||||
T: for<'p> PyGCClearProtocol<'p>,
|
||||
{
|
||||
unsafe extern "C" fn tp_clear<T>(slf: *mut ffi::PyObject) -> c_int
|
||||
where
|
||||
T: for<'p> PyGCClearProtocol<'p>,
|
||||
{
|
||||
let pool = crate::GILPool::new();
|
||||
let py = pool.python();
|
||||
let slf = py.from_borrowed_ptr::<PyCell<T>>(slf);
|
||||
|
||||
slf.borrow_mut().__clear__();
|
||||
0
|
||||
}
|
||||
Some(tp_clear::<T>)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue