add number protocol

This commit is contained in:
Nikolay Kim 2017-05-16 03:31:48 -07:00
parent 78d7d99bd8
commit 6d40d651a1
8 changed files with 500 additions and 84 deletions

View file

@ -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 {

View file

@ -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)
}
*/

View file

@ -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 {

View file

@ -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

View file

@ -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
View 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)
}
}

View file

@ -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>

View file

@ -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 {