#![allow(deprecated)]
use crate::callback::{HashCallbackOutput, IntoPyCallbackOutput};
use crate::{exceptions, ffi, FromPyObject, PyAny, PyCell, PyClass, PyObject};
use std::os::raw::c_int;
#[allow(unused_variables)]
#[deprecated(since = "0.16.0", note = "prefer `#[pymethods]` to `#[pyproto]`")]
pub trait PyObjectProtocol<'p>: PyClass {
fn __getattr__(&'p self, name: Self::Name) -> Self::Result
where
Self: PyObjectGetAttrProtocol<'p>,
{
unimplemented!()
}
fn __setattr__(&'p mut self, name: Self::Name, value: Self::Value) -> Self::Result
where
Self: PyObjectSetAttrProtocol<'p>,
{
unimplemented!()
}
fn __delattr__(&'p mut self, name: Self::Name) -> Self::Result
where
Self: PyObjectDelAttrProtocol<'p>,
{
unimplemented!()
}
fn __str__(&'p self) -> Self::Result
where
Self: PyObjectStrProtocol<'p>,
{
unimplemented!()
}
fn __repr__(&'p self) -> Self::Result
where
Self: PyObjectReprProtocol<'p>,
{
unimplemented!()
}
fn __hash__(&'p self) -> Self::Result
where
Self: PyObjectHashProtocol<'p>,
{
unimplemented!()
}
fn __richcmp__(&'p self, other: Self::Other, op: CompareOp) -> Self::Result
where
Self: PyObjectRichcmpProtocol<'p>,
{
unimplemented!()
}
fn __bool__(&'p self) -> Self::Result
where
Self: PyObjectBoolProtocol<'p>,
{
unimplemented!()
}
}
pub trait PyObjectGetAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyObjectSetAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'p>;
type Value: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<()>;
}
pub trait PyObjectDelAttrProtocol<'p>: PyObjectProtocol<'p> {
type Name: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<()>;
}
pub trait PyObjectStrProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyObjectReprProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<PyObject>;
}
pub trait PyObjectHashProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<HashCallbackOutput>;
}
pub trait PyObjectBoolProtocol<'p>: PyObjectProtocol<'p> {
type Result: IntoPyCallbackOutput<bool>;
}
pub trait PyObjectRichcmpProtocol<'p>: PyObjectProtocol<'p> {
type Other: FromPyObject<'p>;
type Result: IntoPyCallbackOutput<PyObject>;
}
py_unary_func!(str, PyObjectStrProtocol, T::__str__);
py_unary_func!(repr, PyObjectReprProtocol, T::__repr__);
py_unary_func!(hash, PyObjectHashProtocol, T::__hash__, ffi::Py_hash_t);
#[doc(hidden)]
pub unsafe extern "C" fn getattr<T>(
slf: *mut ffi::PyObject,
arg: *mut ffi::PyObject,
) -> *mut ffi::PyObject
where
T: for<'p> PyObjectGetAttrProtocol<'p>,
{
crate::callback_body!(py, {
let existing = ffi::PyObject_GenericGetAttr(slf, arg);
if existing.is_null() {
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).convert(py)
})
}
#[doc(hidden)]
pub unsafe extern "C" fn richcmp<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 = extract_or_return_not_implemented!(py, arg);
let op = match op {
ffi::Py_LT => CompareOp::Lt,
ffi::Py_LE => CompareOp::Le,
ffi::Py_EQ => CompareOp::Eq,
ffi::Py_NE => CompareOp::Ne,
ffi::Py_GT => CompareOp::Gt,
ffi::Py_GE => CompareOp::Ge,
_ => {
return Err(exceptions::PyValueError::new_err(
"tp_richcompare called with invalid comparison operator",
))
}
};
slf.try_borrow()?.__richcmp__(arg, op).convert(py)
})
}
py_func_set!(setattr, PyObjectSetAttrProtocol, T::__setattr__);
py_func_del!(delattr, PyObjectDelAttrProtocol, T::__delattr__);
py_func_set_del!(
setdelattr,
PyObjectSetAttrProtocol,
PyObjectDelAttrProtocol,
Self,
__setattr__,
__delattr__
);
py_unary_func!(bool, PyObjectBoolProtocol, T::__bool__, c_int);
pub use crate::pyclass::CompareOp;