add number protocol
This commit is contained in:
parent
78d7d99bd8
commit
6d40d651a1
|
@ -42,6 +42,18 @@ static MAPPING_METHODS: Methods = Methods {
|
||||||
no_adjust: false,
|
no_adjust: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static NUM_METHODS: Methods = Methods {
|
||||||
|
methods: &[
|
||||||
|
"__radd__", "__rsub__", "__rmul__", "__rmatmul__", "__rtruediv__",
|
||||||
|
"__rfloordiv__", "__rmod__", "__rdivmod__", "__rpow__", "__rlshift__",
|
||||||
|
"__rrshift__", "__rand__", "__rxor__", "__ror__", "__complex__",
|
||||||
|
"__round__"
|
||||||
|
],
|
||||||
|
non_pyobj_result: &[],
|
||||||
|
no_adjust: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum ImplType {
|
enum ImplType {
|
||||||
Async,
|
Async,
|
||||||
Buffer,
|
Buffer,
|
||||||
|
@ -49,6 +61,7 @@ enum ImplType {
|
||||||
GC,
|
GC,
|
||||||
Mapping,
|
Mapping,
|
||||||
Sequence,
|
Sequence,
|
||||||
|
Number,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
|
pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
|
||||||
|
@ -79,6 +92,10 @@ pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
|
||||||
ImplType::Sequence => {
|
ImplType::Sequence => {
|
||||||
impl_protocol("pyo3::class::mapping::PySequenceProtocolImpl",
|
impl_protocol("pyo3::class::mapping::PySequenceProtocolImpl",
|
||||||
path.clone(), ty, impl_items, &DEFAULT_METHODS)
|
path.clone(), ty, impl_items, &DEFAULT_METHODS)
|
||||||
|
},
|
||||||
|
ImplType::Number => {
|
||||||
|
impl_protocol("pyo3::class::number::PyNumberProtocolImpl",
|
||||||
|
path.clone(), ty, impl_items, &NUM_METHODS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,6 +115,7 @@ fn process_path(path: &syn::Path) -> ImplType {
|
||||||
"PyGCProtocol" => ImplType::GC,
|
"PyGCProtocol" => ImplType::GC,
|
||||||
"PyMappingProtocol" => ImplType::Mapping,
|
"PyMappingProtocol" => ImplType::Mapping,
|
||||||
"PySequenceProtocol" => ImplType::Sequence,
|
"PySequenceProtocol" => ImplType::Sequence,
|
||||||
|
"PyNumberProtocol" => ImplType::Number,
|
||||||
_ => panic!("#[py_proto] can not be used with this block"),
|
_ => panic!("#[py_proto] can not be used with this block"),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -52,45 +52,7 @@ impl<T> PyContextProtocolImpl for T {
|
||||||
default fn methods() -> &'static [&'static str] {
|
default fn methods() -> &'static [&'static str] {
|
||||||
NO_METHODS
|
NO_METHODS
|
||||||
}
|
}
|
||||||
|
|
||||||
default fn py_methods() -> &'static [::class::PyMethodDef] {
|
default fn py_methods() -> &'static [::class::PyMethodDef] {
|
||||||
NO_PY_METHODS
|
NO_PY_METHODS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
/// Construct PyAsyncMethods struct for PyTypeObject.tp_as_async
|
|
||||||
pub fn new<T>() -> Option<ffi::PyAsyncMethods>
|
|
||||||
where T: PyAsyncProtocol + PyAsyncProtocolImpl + PythonObject
|
|
||||||
{
|
|
||||||
let methods = T::methods();
|
|
||||||
if methods.is_empty() {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut meth: ffi::PyAsyncMethods = ffi::PyAsyncMethods_INIT;
|
|
||||||
|
|
||||||
for name in methods {
|
|
||||||
match name {
|
|
||||||
&"am_await" => {
|
|
||||||
meth.am_await = py_unary_slot!(
|
|
||||||
PyAsyncProtocol, T::am_await,
|
|
||||||
*mut ffi::PyObject, PyObjectCallbackConverter);
|
|
||||||
},
|
|
||||||
&"am_aiter" => {
|
|
||||||
meth.am_aiter = py_unary_slot!(
|
|
||||||
PyAsyncProtocol, T::am_aiter,
|
|
||||||
*mut ffi::PyObject, PyObjectCallbackConverter);
|
|
||||||
},
|
|
||||||
&"am_anext" => {
|
|
||||||
meth.am_anext = py_unary_slot!(
|
|
||||||
PyAsyncProtocol, T::am_anext,
|
|
||||||
*mut ffi::PyObject, PyObjectCallbackConverter);
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(meth)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -63,6 +63,32 @@ macro_rules! py_binary_func {
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
#[doc(hidden)]
|
||||||
|
macro_rules! py_ternary_func {
|
||||||
|
($trait:ident, $class:ident :: $f:ident, $conv:expr) => {{
|
||||||
|
unsafe extern "C" fn wrap<T>(slf: *mut $crate::ffi::PyObject,
|
||||||
|
arg1: *mut $crate::ffi::PyObject,
|
||||||
|
arg2: *mut $crate::ffi::PyObject)
|
||||||
|
-> *mut $crate::ffi::PyObject
|
||||||
|
where T: $trait + PythonObject
|
||||||
|
{
|
||||||
|
const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()");
|
||||||
|
$crate::_detail::handle_callback(LOCATION, $conv, |py| {
|
||||||
|
let slf = $crate::PyObject::from_borrowed_ptr(py, slf).unchecked_cast_into::<T>();
|
||||||
|
let arg1 = $crate::PyObject::from_borrowed_ptr(py, arg1);
|
||||||
|
let arg2 = $crate::PyObject::from_borrowed_ptr(py, arg2);
|
||||||
|
let ret = slf.$f(py, &arg1, &arg2);
|
||||||
|
$crate::PyDrop::release_ref(arg1, py);
|
||||||
|
$crate::PyDrop::release_ref(arg2, py);
|
||||||
|
$crate::PyDrop::release_ref(slf, py);
|
||||||
|
ret
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Some(wrap::<T>)
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
macro_rules! py_ssizearg_func {
|
macro_rules! py_ssizearg_func {
|
||||||
|
|
|
@ -26,6 +26,28 @@ pub struct PyMethodDef {
|
||||||
unsafe impl Sync for PyMethodDef {}
|
unsafe impl Sync for PyMethodDef {}
|
||||||
unsafe impl Sync for ffi::PyMethodDef {}
|
unsafe impl Sync for ffi::PyMethodDef {}
|
||||||
|
|
||||||
|
impl PyMethodDef {
|
||||||
|
|
||||||
|
fn as_method_def(&self) -> ffi::PyMethodDef {
|
||||||
|
let meth = match self.ml_meth {
|
||||||
|
PyMethodType::PyCFunction(meth) => meth,
|
||||||
|
PyMethodType::PyCFunctionWithKeywords(meth) =>
|
||||||
|
unsafe {
|
||||||
|
::std::mem::transmute::<
|
||||||
|
ffi::PyCFunctionWithKeywords, ffi::PyCFunction>(meth)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ffi::PyMethodDef {
|
||||||
|
ml_name: CString::new(self.ml_name).expect(
|
||||||
|
"Method name must not contain NULL byte").into_raw(),
|
||||||
|
ml_meth: Some(meth),
|
||||||
|
ml_flags: self.ml_flags,
|
||||||
|
ml_doc: 0 as *const ::c_char,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub trait PyClassInit {
|
pub trait PyClassInit {
|
||||||
|
|
||||||
|
@ -72,37 +94,46 @@ impl<T> PyClassInit for T where T: PythonObject + py_class::BaseObject {
|
||||||
// type size
|
// type size
|
||||||
type_object.tp_basicsize = <T as py_class::BaseObject>::size() as ffi::Py_ssize_t;
|
type_object.tp_basicsize = <T as py_class::BaseObject>::size() as ffi::Py_ssize_t;
|
||||||
|
|
||||||
|
// number methods
|
||||||
|
if let Some(meth) = ffi::PyNumberMethods::new::<T>() {
|
||||||
|
static mut NB_METHODS: ffi::PyNumberMethods = ffi::PyNumberMethods_INIT;
|
||||||
|
*(unsafe { &mut NB_METHODS }) = meth;
|
||||||
|
type_object.tp_as_number = unsafe { &mut NB_METHODS };
|
||||||
|
} else {
|
||||||
|
type_object.tp_as_number = 0 as *mut ffi::PyNumberMethods;
|
||||||
|
}
|
||||||
|
|
||||||
// mapping methods
|
// mapping methods
|
||||||
if let Some(buf) = ffi::PyMappingMethods::new::<T>() {
|
if let Some(meth) = ffi::PyMappingMethods::new::<T>() {
|
||||||
static mut MP_METHODS: ffi::PyMappingMethods = ffi::PyMappingMethods_INIT;
|
static mut MP_METHODS: ffi::PyMappingMethods = ffi::PyMappingMethods_INIT;
|
||||||
*(unsafe { &mut MP_METHODS }) = buf;
|
*(unsafe { &mut MP_METHODS }) = meth;
|
||||||
type_object.tp_as_mapping = unsafe { &mut MP_METHODS };
|
type_object.tp_as_mapping = unsafe { &mut MP_METHODS };
|
||||||
} else {
|
} else {
|
||||||
type_object.tp_as_mapping = 0 as *mut ffi::PyMappingMethods;
|
type_object.tp_as_mapping = 0 as *mut ffi::PyMappingMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sequence methods
|
// sequence methods
|
||||||
if let Some(buf) = ffi::PySequenceMethods::new::<T>() {
|
if let Some(meth) = ffi::PySequenceMethods::new::<T>() {
|
||||||
static mut SQ_METHODS: ffi::PySequenceMethods = ffi::PySequenceMethods_INIT;
|
static mut SQ_METHODS: ffi::PySequenceMethods = ffi::PySequenceMethods_INIT;
|
||||||
*(unsafe { &mut SQ_METHODS }) = buf;
|
*(unsafe { &mut SQ_METHODS }) = meth;
|
||||||
type_object.tp_as_sequence = unsafe { &mut SQ_METHODS };
|
type_object.tp_as_sequence = unsafe { &mut SQ_METHODS };
|
||||||
} else {
|
} else {
|
||||||
type_object.tp_as_sequence = 0 as *mut ffi::PySequenceMethods;
|
type_object.tp_as_sequence = 0 as *mut ffi::PySequenceMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
// async methods
|
// async methods
|
||||||
if let Some(buf) = ffi::PyAsyncMethods::new::<T>() {
|
if let Some(meth) = ffi::PyAsyncMethods::new::<T>() {
|
||||||
static mut ASYNC_METHODS: ffi::PyAsyncMethods = ffi::PyAsyncMethods_INIT;
|
static mut ASYNC_METHODS: ffi::PyAsyncMethods = ffi::PyAsyncMethods_INIT;
|
||||||
*(unsafe { &mut ASYNC_METHODS }) = buf;
|
*(unsafe { &mut ASYNC_METHODS }) = meth;
|
||||||
type_object.tp_as_async = unsafe { &mut ASYNC_METHODS };
|
type_object.tp_as_async = unsafe { &mut ASYNC_METHODS };
|
||||||
} else {
|
} else {
|
||||||
type_object.tp_as_async = 0 as *mut ffi::PyAsyncMethods;
|
type_object.tp_as_async = 0 as *mut ffi::PyAsyncMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
// buffer protocol
|
// buffer protocol
|
||||||
if let Some(buf) = ffi::PyBufferProcs::new::<T>() {
|
if let Some(meth) = ffi::PyBufferProcs::new::<T>() {
|
||||||
static mut BUFFER_PROCS: ffi::PyBufferProcs = ffi::PyBufferProcs_INIT;
|
static mut BUFFER_PROCS: ffi::PyBufferProcs = ffi::PyBufferProcs_INIT;
|
||||||
*(unsafe { &mut BUFFER_PROCS }) = buf;
|
*(unsafe { &mut BUFFER_PROCS }) = meth;
|
||||||
type_object.tp_as_buffer = unsafe { &mut BUFFER_PROCS };
|
type_object.tp_as_buffer = unsafe { &mut BUFFER_PROCS };
|
||||||
} else {
|
} else {
|
||||||
type_object.tp_as_buffer = 0 as *mut ffi::PyBufferProcs;
|
type_object.tp_as_buffer = 0 as *mut ffi::PyBufferProcs;
|
||||||
|
@ -143,23 +174,11 @@ pub fn py_class_method_defs<T>() -> Vec<ffi::PyMethodDef> {
|
||||||
let mut defs = Vec::new();
|
let mut defs = Vec::new();
|
||||||
|
|
||||||
for def in <T as class::context::PyContextProtocolImpl>::py_methods() {
|
for def in <T as class::context::PyContextProtocolImpl>::py_methods() {
|
||||||
let meth = match def.ml_meth {
|
defs.push(def.as_method_def())
|
||||||
PyMethodType::PyCFunction(meth) => meth,
|
|
||||||
PyMethodType::PyCFunctionWithKeywords(meth) =>
|
|
||||||
unsafe {
|
|
||||||
::std::mem::transmute::<
|
|
||||||
ffi::PyCFunctionWithKeywords, ffi::PyCFunction>(meth)
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
let fdef = ffi::PyMethodDef {
|
for def in <T as class::number::PyNumberProtocolImpl>::py_methods() {
|
||||||
ml_name: CString::new(def.ml_name).expect(
|
defs.push(def.as_method_def())
|
||||||
"Method name must not contain NULL byte").into_raw(),
|
|
||||||
ml_meth: Some(meth),
|
|
||||||
ml_flags: def.ml_flags,
|
|
||||||
ml_doc: 0 as *const ::c_char,
|
|
||||||
};
|
|
||||||
defs.push(fdef)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
defs
|
defs
|
||||||
|
|
|
@ -7,6 +7,7 @@ pub mod buffer;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod mapping;
|
pub mod mapping;
|
||||||
pub mod methods;
|
pub mod methods;
|
||||||
|
pub mod number;
|
||||||
pub mod gc;
|
pub mod gc;
|
||||||
pub mod sequence;
|
pub mod sequence;
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ pub use self::async::*;
|
||||||
pub use self::buffer::*;
|
pub use self::buffer::*;
|
||||||
pub use self::context::*;
|
pub use self::context::*;
|
||||||
pub use self::gc::{PyVisit, PyGCProtocol, PyTraverseError};
|
pub use self::gc::{PyVisit, PyGCProtocol, PyTraverseError};
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
410
src/class/number.rs
Normal file
410
src/class/number.rs
Normal file
|
@ -0,0 +1,410 @@
|
||||||
|
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||||
|
|
||||||
|
//! Python Number Interface
|
||||||
|
//! Trait and support implementation for implementing number protocol
|
||||||
|
|
||||||
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
|
use ffi;
|
||||||
|
use err::{PyErr, PyResult};
|
||||||
|
use python::{self, Python, PythonObject, PyDrop};
|
||||||
|
use conversion::ToPyObject;
|
||||||
|
use objects::{exc, PyObject, PyType, PyModule};
|
||||||
|
use py_class::slots::{LenResultConverter, UnitCallbackConverter, BoolConverter};
|
||||||
|
use function::{handle_callback, PyObjectCallbackConverter};
|
||||||
|
use class::{NO_METHODS, NO_PY_METHODS};
|
||||||
|
|
||||||
|
|
||||||
|
/// Number interface
|
||||||
|
pub trait PyNumberProtocol {
|
||||||
|
|
||||||
|
fn __add__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __sub__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __mul__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __matmul__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __truediv__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __floordiv__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __mod__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __divmod__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __pow__(&self, py: Python, other: &PyObject, modulo: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __lshift__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rshift__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __and__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __xor__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __or__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
|
||||||
|
fn __radd__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rsub__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rmul__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rmatmul__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rtruediv__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rfloordiv__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rmod__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rdivmod__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rpow__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rlshift__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rrshift__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rand__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __rxor__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __ror__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
|
||||||
|
fn __iadd__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __isub__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __imul__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __imatmul__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __itruediv__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __ifloordiv__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __imod__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __ipow__(&self, py: Python, other: &PyObject, modulo: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __ilshift__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __irshift__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __iand__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __ixor__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
fn __ior__(&self, py: Python, other: &PyObject) -> PyResult<PyObject>;
|
||||||
|
|
||||||
|
// Unary arithmetic
|
||||||
|
fn __neg__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __pos__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __abs__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __invert__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __complex__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __int__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __float__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __round__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
fn __index__(&self, py: Python) -> PyResult<PyObject>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyNumberProtocol for T where T: PythonObject {
|
||||||
|
default fn __add__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __sub__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __mul__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __matmul__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __truediv__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __floordiv__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __mod__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __divmod__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __pow__(&self, py: Python, _: &PyObject, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __lshift__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rshift__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __and__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __xor__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __or__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
|
||||||
|
default fn __radd__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rsub__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rmul__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rmatmul__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rtruediv__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rfloordiv__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rmod__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rdivmod__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rpow__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rlshift__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rrshift__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rand__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __rxor__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __ror__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
|
||||||
|
default fn __iadd__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __isub__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __imul__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __imatmul__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __itruediv__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __ifloordiv__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __imod__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __ipow__(&self, py: Python, _: &PyObject, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __ilshift__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __irshift__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __iand__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __ixor__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __ior__(&self, py: Python, _: &PyObject) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __neg__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __pos__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __abs__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __invert__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __complex__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __int__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __float__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __round__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
default fn __index__(&self, py: Python) -> PyResult<PyObject> {
|
||||||
|
Ok(py.NotImplemented())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub trait PyNumberProtocolImpl {
|
||||||
|
fn methods() -> &'static [&'static str];
|
||||||
|
fn py_methods() -> &'static [::class::PyMethodDef];
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> PyNumberProtocolImpl for T {
|
||||||
|
default fn methods() -> &'static [&'static str] {
|
||||||
|
NO_METHODS
|
||||||
|
}
|
||||||
|
default fn py_methods() -> &'static [::class::PyMethodDef] {
|
||||||
|
NO_PY_METHODS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ffi::PyNumberMethods {
|
||||||
|
|
||||||
|
/// Construct PyNumberMethods struct for PyTypeObject.tp_as_number
|
||||||
|
pub fn new<T>() -> Option<ffi::PyNumberMethods>
|
||||||
|
where T: PyNumberProtocol + PyNumberProtocolImpl + PythonObject
|
||||||
|
{
|
||||||
|
let methods = T::methods();
|
||||||
|
if methods.is_empty() {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut meth: ffi::PyNumberMethods = ffi::PyNumberMethods_INIT;
|
||||||
|
|
||||||
|
for name in methods {
|
||||||
|
match name {
|
||||||
|
&"__add__" => {
|
||||||
|
meth.nb_add = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__add__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__sub__" => {
|
||||||
|
meth.nb_subtract = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__sub__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__mul__" => {
|
||||||
|
meth.nb_multiply = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__mul__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__matmul__" => {
|
||||||
|
meth.nb_matrix_multiply = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__matmul__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__truediv__" => {
|
||||||
|
meth.nb_true_divide = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__truediv__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__floordiv__" => {
|
||||||
|
meth.nb_floor_divide = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__floordiv__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__mod__" => {
|
||||||
|
meth.nb_remainder = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__mod__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__divmod__" => {
|
||||||
|
meth.nb_divmod = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__divmod__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__pow__" => {
|
||||||
|
meth.nb_power = py_ternary_func!(
|
||||||
|
PyNumberProtocol, T::__pow__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__lshift__" => {
|
||||||
|
meth.nb_lshift = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__lshift__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__rshift__" => {
|
||||||
|
meth.nb_rshift = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__rshift__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__and__" => {
|
||||||
|
meth.nb_and = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__and__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__xor__" => {
|
||||||
|
meth.nb_xor = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__xor__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__or__" => {
|
||||||
|
meth.nb_or = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__or__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__iadd__" => {
|
||||||
|
meth.nb_inplace_add = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__iadd__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__isub__" => {
|
||||||
|
meth.nb_inplace_subtract = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__isub__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__imul__" => {
|
||||||
|
meth.nb_inplace_multiply = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__imul__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__imatmul__" => {
|
||||||
|
meth.nb_inplace_matrix_multiply = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__imatmul__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__itruediv__" => {
|
||||||
|
meth.nb_inplace_true_divide = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__itruediv__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__ifloordiv__" => {
|
||||||
|
meth.nb_inplace_floor_divide = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__ifloordiv__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__imod__" => {
|
||||||
|
meth.nb_inplace_remainder = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__imod__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__ipow__" => {
|
||||||
|
meth.nb_inplace_power = py_ternary_func!(
|
||||||
|
PyNumberProtocol, T::__ipow__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__ilshift__" => {
|
||||||
|
meth.nb_inplace_lshift = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__ilshift__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__irshift__" => {
|
||||||
|
meth.nb_inplace_rshift = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__irshift__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__iand__" => {
|
||||||
|
meth.nb_inplace_and = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__iand__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__ixor__" => {
|
||||||
|
meth.nb_inplace_xor = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__ixor__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__ior__" => {
|
||||||
|
meth.nb_inplace_or = py_binary_func!(
|
||||||
|
PyNumberProtocol, T::__ior__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
&"__neg__" => {
|
||||||
|
meth.nb_negative = py_unary_func!(
|
||||||
|
PyNumberProtocol, T::__neg__, PyObjectCallbackConverter);
|
||||||
|
|
||||||
|
},
|
||||||
|
&"__pos__" => {
|
||||||
|
meth.nb_positive = py_unary_func!(
|
||||||
|
PyNumberProtocol, T::__pos__, PyObjectCallbackConverter);
|
||||||
|
|
||||||
|
},
|
||||||
|
&"__abs__" => {
|
||||||
|
meth.nb_absolute = py_unary_func!(
|
||||||
|
PyNumberProtocol, T::__abs__, PyObjectCallbackConverter);
|
||||||
|
|
||||||
|
},
|
||||||
|
&"__invert__" => {
|
||||||
|
meth.nb_invert = py_unary_func!(
|
||||||
|
PyNumberProtocol, T::__invert__, PyObjectCallbackConverter);
|
||||||
|
|
||||||
|
},
|
||||||
|
&"__int__" => {
|
||||||
|
meth.nb_int = py_unary_func!(
|
||||||
|
PyNumberProtocol, T::__int__, PyObjectCallbackConverter);
|
||||||
|
|
||||||
|
},
|
||||||
|
&"__float__" => {
|
||||||
|
meth.nb_float = py_unary_func!(
|
||||||
|
PyNumberProtocol, T::__float__, PyObjectCallbackConverter);
|
||||||
|
|
||||||
|
},
|
||||||
|
&"__index__" => {
|
||||||
|
meth.nb_index = py_unary_func!(
|
||||||
|
PyNumberProtocol, T::__index__, PyObjectCallbackConverter);
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(meth)
|
||||||
|
}
|
||||||
|
}
|
|
@ -125,7 +125,6 @@ macro_rules! py_class_impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init($py: $crate::Python, module_name: Option<&str>) -> $crate::PyResult<$crate::PyType> {
|
fn init($py: $crate::Python, module_name: Option<&str>) -> $crate::PyResult<$crate::PyType> {
|
||||||
py_class_type_object_dynamic_init!($class, $py, TYPE_OBJECT, module_name, $slots);
|
|
||||||
py_class_init_members!($class, $py, TYPE_OBJECT, $members);
|
py_class_init_members!($class, $py, TYPE_OBJECT, $members);
|
||||||
py_class_init_properties!($class, $py, TYPE_OBJECT, $properties);
|
py_class_init_properties!($class, $py, TYPE_OBJECT, $properties);
|
||||||
unsafe { <$class as $crate::class::methods::PyClassInit>
|
unsafe { <$class as $crate::class::methods::PyClassInit>
|
||||||
|
|
|
@ -53,26 +53,6 @@ macro_rules! py_class_type_object_static_init {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
#[doc(hidden)]
|
|
||||||
macro_rules! py_class_type_object_dynamic_init {
|
|
||||||
// initialize those fields of PyTypeObject that we couldn't initialize statically
|
|
||||||
($class: ident, $py:ident, $type_object:ident, $module_name: ident,
|
|
||||||
/* slots: */ {
|
|
||||||
$type_slots:tt
|
|
||||||
$as_async:tt
|
|
||||||
$as_number:tt
|
|
||||||
$as_sequence:tt
|
|
||||||
$as_mapping:tt
|
|
||||||
$as_buffer:tt
|
|
||||||
$setdelitem:tt
|
|
||||||
}
|
|
||||||
) => {
|
|
||||||
// call slot macros outside of unsafe block
|
|
||||||
*(unsafe { &mut $type_object.tp_as_number }) = py_class_as_number!($as_number);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
macro_rules! py_class_wrap_newfunc {
|
macro_rules! py_class_wrap_newfunc {
|
||||||
|
|
Loading…
Reference in a new issue