diff --git a/python3-sys/src/memoryobject.rs b/python3-sys/src/memoryobject.rs index 27d60d05..56c5af35 100644 --- a/python3-sys/src/memoryobject.rs +++ b/python3-sys/src/memoryobject.rs @@ -21,6 +21,7 @@ extern "C" { size: Py_ssize_t, flags: c_int, ) -> *mut PyObject; + pub fn PyMemoryView_FromBuffer(view: *mut Py_buffer) -> *mut PyObject; pub fn PyMemoryView_GetContiguous( base: *mut PyObject, buffertype: c_int, diff --git a/python3-sys/src/object.rs b/python3-sys/src/object.rs index 09df770b..3fd67bf6 100644 --- a/python3-sys/src/object.rs +++ b/python3-sys/src/object.rs @@ -109,13 +109,13 @@ mod bufferinfo { } } - pub type getbufferproc = extern "C" fn( + pub type getbufferproc = unsafe extern "C" fn( arg1: *mut crate::object::PyObject, arg2: *mut Py_buffer, arg3: c_int, ) -> c_int; pub type releasebufferproc = - extern "C" fn(arg1: *mut crate::object::PyObject, arg2: *mut Py_buffer) -> (); + unsafe extern "C" fn(arg1: *mut crate::object::PyObject, arg2: *mut Py_buffer) -> (); /// Maximum number of dimensions pub const PyBUF_MAX_NDIM: c_int = 64; @@ -430,6 +430,10 @@ mod typeobject { unsafe { core::mem::zeroed() } } } + pub const PyBufferProcs_INIT: PyBufferProcs = PyBufferProcs { + bf_getbuffer: None, + bf_releasebuffer: None, + }; #[repr(C)] #[derive(Copy)] diff --git a/src/buffer.rs b/src/buffer.rs index 4c0662c2..a268234b 100644 --- a/src/buffer.rs +++ b/src/buffer.rs @@ -18,7 +18,7 @@ use libc; use std::ffi::CStr; -use std::{cell, mem, slice}; +use std::{cell, mem, ptr, slice}; use crate::err::{self, PyResult}; use crate::exc; @@ -661,6 +661,36 @@ impl_element!(isize, SignedInteger); impl_element!(f32, Float); impl_element!(f64, Float); +/// Trait for the backing storage of a PyBuffer provided from a Rust binding. +/// +/// It is unsafe because its implementation needs to uphold certain invariants. +/// See the method docs for more details. +pub unsafe trait BufferHandle: 'static + Send { + /// Returns the data of `Self` as a continous array of bytes. + /// + /// # Safety + /// + /// This needs to return an address that remains valid + /// and stable if `self` gets moved or transformed to or from a void pointer. + fn as_bytes(&self) -> &[u8]; + + /// Convert `self` into an owned void pointer. + /// + /// # Safety + /// + /// The returned pointer has to be a valid pointer that + /// can be converted back to `Self`. + fn into_owned_void_pointer(self) -> *mut libc::c_void; + + /// Convert an owned void pointer back to `Self`. This takes owenrship of the pointer. + /// + /// # Safety + /// + /// The passed `ptr` has been created by this trait, and is only + /// used at most once to convert back to `Self`. + unsafe fn from_owned_void_pointer(ptr: *mut libc::c_void) -> Self; +} + #[cfg(test)] mod test { use super::PyBuffer; diff --git a/src/py_class/py_class.rs b/src/py_class/py_class.rs index 80d6d64e..d3ce34bc 100644 --- a/src/py_class/py_class.rs +++ b/src/py_class/py_class.rs @@ -465,6 +465,10 @@ macro_rules! py_class { /* as_number */ [ /* slot: expr, */ ] /* as_sequence */ [ /* slot: expr, */ ] /* as_mapping */ [ /* slot: expr, */ ] + /* as_buffer */ [ + bf_getbuffer: {}, + bf_releasebuffer: {}, + ] /* setitem_delitem */ [ sdi_setitem: {}, sdi_delitem: {}, @@ -495,6 +499,10 @@ macro_rules! py_class { /* as_number */ [ /* slot: expr, */ ] /* as_sequence */ [ /* slot: expr, */ ] /* as_mapping */ [ /* slot: expr, */ ] + /* as_buffer */ [ + bf_getbuffer: {}, + bf_releasebuffer: {}, + ] /* setitem_delitem */ [ sdi_setitem: {}, sdi_delitem: {}, diff --git a/src/py_class/py_class_impl.py b/src/py_class/py_class_impl.py index c70fc4d7..131a916a 100644 --- a/src/py_class/py_class_impl.py +++ b/src/py_class/py_class_impl.py @@ -247,7 +247,8 @@ def write(text): ('nb', 'as_number', None), ('sq', 'as_sequence', None), ('mp', 'as_mapping', None), - ('sdi', 'setdelitem', ['sdi_setitem', 'sdi_delitem']) + ('bf', 'as_buffer', ['bf_getbuffer', 'bf_releasebuffer']), + ('sdi', 'setdelitem', ['sdi_setitem', 'sdi_delitem']), ) def generate_case(pattern, old_info=None, new_info=None, new_impl=None, new_slots=None, new_members=None, new_props=None): @@ -723,6 +724,30 @@ def inplace_numeric_operator(special_name, slot): operator(slot=slot, args=[Argument('other')])(special_name) +@special_method +def buffer_protocol(special_name, enabled, mode): + if enabled: + if mode == "direct": + pattern = 'def %s <$gil_lt:lifetime>(&$slf_lt:lifetime $slf:ident) -> $res_type:ty $body:block' % special_name + new_impl=''' + impl $class { + fn %s<$gil_lt>(&$slf_lt $slf, $py: $crate::Python<$gil_lt>) -> $res_type $body + } + ''' % special_name + + if mode == "handle": + pattern = 'def %s (&$slf:ident) -> $res_type:ty $body:block' % special_name + new_impl=''' + impl $class { + fn %s(&$slf, $py: $crate::Python<'_>) -> $res_type $body + } + ''' % special_name + + new_slots = [] + for slot in ['bf_getbuffer', 'bf_releasebuffer']: + new_slots.append((slot, '$crate::py_class_buffer_slot!(%s, %s, $class::%s)' % (mode, slot, special_name))) + generate_case(pattern, new_slots=new_slots, new_impl=new_impl) + special_names = { '__init__': error('__init__ is not supported by py_class!; use __new__ instead.'), '__new__': special_class_method( @@ -870,6 +895,10 @@ def inplace_numeric_operator(special_name, slot): '__aiter__': unimplemented(), '__aenter__': unimplemented(), '__aexit__': unimplemented(), + + # Buffer protocol + '__buffer__': buffer_protocol(not PY2, "handle"), + '__direct_buffer__': buffer_protocol(not PY2, "direct"), } def main(): @@ -907,4 +936,3 @@ def main(): if __name__ == '__main__': main() - diff --git a/src/py_class/py_class_impl2.rs b/src/py_class/py_class_impl2.rs index b87e57dc..a166116a 100644 --- a/src/py_class/py_class_impl2.rs +++ b/src/py_class/py_class_impl2.rs @@ -341,7 +341,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -353,7 +353,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_clear: $crate::py_class_tp_clear!($class), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -370,7 +370,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -383,7 +383,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_absolute: $crate::py_class_unary_slot!($class::__abs__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -400,7 +400,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -413,7 +413,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_add: $crate::py_class_binary_numeric_slot!($class::__add__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -442,7 +442,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -455,7 +455,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_and: $crate::py_class_binary_numeric_slot!($class::__and__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -476,7 +476,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -489,7 +489,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_nonzero: $crate::py_class_unary_slot!($class::__bool__, $crate::_detail::libc::c_int, $crate::py_class::slots::BoolConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -505,7 +505,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -517,7 +517,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_call: $crate::py_class_call_slot!{$class::__call__ []}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -529,7 +529,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -541,7 +541,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_call: $crate::py_argparse_parse_plist_impl!{py_class_call_slot {$class::__call__} [] ($($p)+,)}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -569,7 +569,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - $as_mapping:tt $setdelitem:tt + $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -582,7 +582,7 @@ macro_rules! py_class_impl { $( $sq_slot_name : $sq_slot_value, )* sq_contains: $crate::py_class_contains_slot!($class::__contains__, [Option<&$item_name>]), ] - $as_mapping $setdelitem + $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -595,7 +595,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - $as_mapping:tt $setdelitem:tt + $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -608,7 +608,7 @@ macro_rules! py_class_impl { $( $sq_slot_name : $sq_slot_value, )* sq_contains: $crate::py_class_contains_slot!($class::__contains__, [&$item_name]), ] - $as_mapping $setdelitem + $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -621,7 +621,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - $as_mapping:tt $setdelitem:tt + $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -634,7 +634,7 @@ macro_rules! py_class_impl { $( $sq_slot_name : $sq_slot_value, )* sq_contains: $crate::py_class_contains_slot!($class::__contains__, [$item_name]), ] - $as_mapping $setdelitem + $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -661,7 +661,7 @@ macro_rules! py_class_impl { { { def __delitem__(&$slf:ident, $key:ident : Option<&$key_name:ty>) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value:tt, sdi_delitem: {}, @@ -673,7 +673,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value, sdi_delitem: { $crate::py_class_binary_slot!($class::__delitem__, [Option<&$key_name>], $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, @@ -688,7 +688,7 @@ macro_rules! py_class_impl { { { def __delitem__(&$slf:ident, $key:ident : &$key_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value:tt, sdi_delitem: {}, @@ -700,7 +700,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value, sdi_delitem: { $crate::py_class_binary_slot!($class::__delitem__, [&$key_name], $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, @@ -715,7 +715,7 @@ macro_rules! py_class_impl { { { def __delitem__(&$slf:ident, $key:ident : $key_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value:tt, sdi_delitem: {}, @@ -727,7 +727,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value, sdi_delitem: { $crate::py_class_binary_slot!($class::__delitem__, [$key_name], $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, @@ -789,7 +789,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -806,7 +806,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_subscript: $crate::py_class_binary_slot!($class::__getitem__, [Option<&$key_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -820,7 +820,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -837,7 +837,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_subscript: $crate::py_class_binary_slot!($class::__getitem__, [&$key_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -851,7 +851,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -868,7 +868,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_subscript: $crate::py_class_binary_slot!($class::__getitem__, [$key_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -888,7 +888,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -900,7 +900,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_hash: $crate::py_class_unary_slot!($class::__hash__, $crate::Py_hash_t, $crate::py_class::slots::HashConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -917,7 +917,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -930,7 +930,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_add: $crate::py_class_binary_slot!($class::__iadd__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -943,7 +943,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -956,7 +956,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_add: $crate::py_class_binary_slot!($class::__iadd__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -969,7 +969,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -982,7 +982,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_add: $crate::py_class_binary_slot!($class::__iadd__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -999,7 +999,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1012,7 +1012,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_and: $crate::py_class_binary_slot!($class::__iand__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1025,7 +1025,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1038,7 +1038,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_and: $crate::py_class_binary_slot!($class::__iand__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1051,7 +1051,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1064,7 +1064,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_and: $crate::py_class_binary_slot!($class::__iand__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1085,7 +1085,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1098,7 +1098,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_floor_divide: $crate::py_class_binary_slot!($class::__ifloordiv__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1111,7 +1111,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1124,7 +1124,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_floor_divide: $crate::py_class_binary_slot!($class::__ifloordiv__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1137,7 +1137,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1150,7 +1150,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_floor_divide: $crate::py_class_binary_slot!($class::__ifloordiv__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1167,7 +1167,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1180,7 +1180,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_lshift: $crate::py_class_binary_slot!($class::__ilshift__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1193,7 +1193,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1206,7 +1206,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_lshift: $crate::py_class_binary_slot!($class::__ilshift__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1219,7 +1219,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1232,7 +1232,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_lshift: $crate::py_class_binary_slot!($class::__ilshift__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1249,7 +1249,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1262,7 +1262,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_matrix_multiply: $crate::py_class_binary_slot!($class::__imatmul__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1275,7 +1275,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1288,7 +1288,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_matrix_multiply: $crate::py_class_binary_slot!($class::__imatmul__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1301,7 +1301,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1314,7 +1314,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_matrix_multiply: $crate::py_class_binary_slot!($class::__imatmul__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1331,7 +1331,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1344,7 +1344,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_remainder: $crate::py_class_binary_slot!($class::__imod__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1357,7 +1357,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1370,7 +1370,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_remainder: $crate::py_class_binary_slot!($class::__imod__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1383,7 +1383,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1396,7 +1396,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_remainder: $crate::py_class_binary_slot!($class::__imod__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1413,7 +1413,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1426,7 +1426,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_multiply: $crate::py_class_binary_slot!($class::__imul__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1439,7 +1439,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1452,7 +1452,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_multiply: $crate::py_class_binary_slot!($class::__imul__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1465,7 +1465,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1478,7 +1478,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_multiply: $crate::py_class_binary_slot!($class::__imul__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1511,7 +1511,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1524,7 +1524,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_invert: $crate::py_class_unary_slot!($class::__invert__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1541,7 +1541,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1554,7 +1554,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_or: $crate::py_class_binary_slot!($class::__ior__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1567,7 +1567,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1580,7 +1580,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_or: $crate::py_class_binary_slot!($class::__ior__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1593,7 +1593,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1606,7 +1606,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_or: $crate::py_class_binary_slot!($class::__ior__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1627,7 +1627,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1640,7 +1640,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_rshift: $crate::py_class_binary_slot!($class::__irshift__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1653,7 +1653,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1666,7 +1666,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_rshift: $crate::py_class_binary_slot!($class::__irshift__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1679,7 +1679,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1692,7 +1692,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_rshift: $crate::py_class_binary_slot!($class::__irshift__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1709,7 +1709,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1722,7 +1722,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_subtract: $crate::py_class_binary_slot!($class::__isub__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1735,7 +1735,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1748,7 +1748,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_subtract: $crate::py_class_binary_slot!($class::__isub__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1761,7 +1761,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1774,7 +1774,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_subtract: $crate::py_class_binary_slot!($class::__isub__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1790,7 +1790,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1802,7 +1802,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_iter: $crate::py_class_unary_slot!($class::__iter__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1819,7 +1819,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1832,7 +1832,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_true_divide: $crate::py_class_binary_slot!($class::__itruediv__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1845,7 +1845,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1858,7 +1858,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_true_divide: $crate::py_class_binary_slot!($class::__itruediv__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1871,7 +1871,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1884,7 +1884,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_true_divide: $crate::py_class_binary_slot!($class::__itruediv__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1901,7 +1901,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1914,7 +1914,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_xor: $crate::py_class_binary_slot!($class::__ixor__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1927,7 +1927,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1940,7 +1940,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_xor: $crate::py_class_binary_slot!($class::__ixor__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1953,7 +1953,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1966,7 +1966,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_xor: $crate::py_class_binary_slot!($class::__ixor__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1988,7 +1988,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2005,7 +2005,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_length: Some($crate::_detail::ffi::PySequence_Size), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2026,7 +2026,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2039,7 +2039,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_lshift: $crate::py_class_binary_numeric_slot!($class::__lshift__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2068,7 +2068,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2081,7 +2081,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_multiply: $crate::py_class_binary_numeric_slot!($class::__mul__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2102,7 +2102,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2115,7 +2115,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_negative: $crate::py_class_unary_slot!($class::__neg__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2131,7 +2131,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2143,7 +2143,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_new: $crate::py_class_wrap_newfunc!{$class::__new__ []}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2155,7 +2155,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2167,7 +2167,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_new: $crate::py_argparse_parse_plist_impl!{py_class_wrap_newfunc {$class::__new__} [] ($($p)+,)}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2182,7 +2182,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2194,7 +2194,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_iternext: $crate::py_class_unary_slot!($class::__next__, *mut $crate::_detail::ffi::PyObject, $crate::py_class::slots::IterNextResultConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2215,7 +2215,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2228,7 +2228,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_or: $crate::py_class_binary_numeric_slot!($class::__or__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2245,7 +2245,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2258,7 +2258,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_positive: $crate::py_class_unary_slot!($class::__pos__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2294,7 +2294,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2306,7 +2306,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_repr: $crate::py_class_unary_slot!($class::__repr__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PythonObjectCallbackConverter::<$crate::PyString>(std::marker::PhantomData)), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2326,7 +2326,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2338,7 +2338,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_richcompare: $crate::py_class_richcompare_slot!($class::__richcmp__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2350,7 +2350,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2362,7 +2362,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_richcompare: $crate::py_class_richcompare_slot!($class::__richcmp__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2374,7 +2374,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2386,7 +2386,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_richcompare: $crate::py_class_richcompare_slot!($class::__richcmp__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2435,7 +2435,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2448,7 +2448,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_rshift: $crate::py_class_binary_numeric_slot!($class::__rshift__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2483,7 +2483,7 @@ macro_rules! py_class_impl { { { def __setitem__(&$slf:ident, $key:ident : Option<&$key_name:ty>, $value:ident : $value_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: {}, sdi_delitem: $sdi_delitem_slot_value:tt, @@ -2495,7 +2495,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: { $crate::py_class_ternary_slot!($class::__setitem__, [Option<&$key_name>], $value_name, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, sdi_delitem: $sdi_delitem_slot_value, @@ -2510,7 +2510,7 @@ macro_rules! py_class_impl { { { def __setitem__(&$slf:ident, $key:ident : &$key_name:ty, $value:ident : $value_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: {}, sdi_delitem: $sdi_delitem_slot_value:tt, @@ -2522,7 +2522,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: { $crate::py_class_ternary_slot!($class::__setitem__, [&$key_name], $value_name, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, sdi_delitem: $sdi_delitem_slot_value, @@ -2537,7 +2537,7 @@ macro_rules! py_class_impl { { { def __setitem__(&$slf:ident, $key:ident : $key_name:ty, $value:ident : $value_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: {}, sdi_delitem: $sdi_delitem_slot_value:tt, @@ -2549,7 +2549,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: { $crate::py_class_ternary_slot!($class::__setitem__, [$key_name], $value_name, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, sdi_delitem: $sdi_delitem_slot_value, @@ -2569,7 +2569,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2581,7 +2581,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_str: $crate::py_class_unary_slot!($class::__str__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PythonObjectCallbackConverter::<$crate::PyString>(std::marker::PhantomData)), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2598,7 +2598,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2611,7 +2611,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_subtract: $crate::py_class_binary_numeric_slot!($class::__sub__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2636,7 +2636,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2649,7 +2649,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_xor: $crate::py_class_binary_numeric_slot!($class::__xor__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* diff --git a/src/py_class/py_class_impl3.rs b/src/py_class/py_class_impl3.rs index d3923ebf..9fcbcfe5 100644 --- a/src/py_class/py_class_impl3.rs +++ b/src/py_class/py_class_impl3.rs @@ -341,7 +341,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -353,7 +353,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_clear: $crate::py_class_tp_clear!($class), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -370,7 +370,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -383,7 +383,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_absolute: $crate::py_class_unary_slot!($class::__abs__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -400,7 +400,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -413,7 +413,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_add: $crate::py_class_binary_numeric_slot!($class::__add__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -442,7 +442,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -455,7 +455,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_and: $crate::py_class_binary_numeric_slot!($class::__and__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -476,7 +476,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -489,7 +489,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_bool: $crate::py_class_unary_slot!($class::__bool__, $crate::_detail::libc::c_int, $crate::py_class::slots::BoolConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -501,11 +501,42 @@ macro_rules! py_class_impl { { { def __bool__ $($tail:tt)* } $( $stuff:tt )* } => { $crate::py_error! { "Invalid signature for operator __bool__" } }; + { { def __buffer__ (&$slf:ident) -> $res_type:ty $body:block $($tail:tt)* } + $class:ident $py:ident $info:tt + /* slots: */ { + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + /* as_buffer */ [ + bf_getbuffer: {}, + bf_releasebuffer: {}, + ] + $setdelitem:tt + } + { $( $imp:item )* } + $members:tt $props:tt + } => { $crate::py_class_impl! { + { $($tail)* } + $class $py $info + /* slots: */ { + $type_slots $as_number $as_sequence $as_mapping + /* as_buffer */ [ + bf_getbuffer: { $crate::py_class_buffer_slot!(handle, bf_getbuffer, $class::__buffer__) }, + bf_releasebuffer: { $crate::py_class_buffer_slot!(handle, bf_releasebuffer, $class::__buffer__) }, + ] + $setdelitem + } + /* impl: */ { + $($imp)* + impl $class { + fn __buffer__(&$slf, $py: $crate::Python<'_>) -> $res_type $body + } + } + $members $props + }}; { { def __call__ (&$slf:ident) -> $res_type:ty { $( $body:tt )* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -517,7 +548,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_call: $crate::py_class_call_slot!{$class::__call__ []}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -529,7 +560,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -541,7 +572,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_call: $crate::py_argparse_parse_plist_impl!{py_class_call_slot {$class::__call__} [] ($($p)+,)}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -569,7 +600,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - $as_mapping:tt $setdelitem:tt + $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -582,7 +613,7 @@ macro_rules! py_class_impl { $( $sq_slot_name : $sq_slot_value, )* sq_contains: $crate::py_class_contains_slot!($class::__contains__, [Option<&$item_name>]), ] - $as_mapping $setdelitem + $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -595,7 +626,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - $as_mapping:tt $setdelitem:tt + $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -608,7 +639,7 @@ macro_rules! py_class_impl { $( $sq_slot_name : $sq_slot_value, )* sq_contains: $crate::py_class_contains_slot!($class::__contains__, [&$item_name]), ] - $as_mapping $setdelitem + $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -621,7 +652,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] - $as_mapping:tt $setdelitem:tt + $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -634,7 +665,7 @@ macro_rules! py_class_impl { $( $sq_slot_name : $sq_slot_value, )* sq_contains: $crate::py_class_contains_slot!($class::__contains__, [$item_name]), ] - $as_mapping $setdelitem + $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -661,7 +692,7 @@ macro_rules! py_class_impl { { { def __delitem__(&$slf:ident, $key:ident : Option<&$key_name:ty>) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value:tt, sdi_delitem: {}, @@ -673,7 +704,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value, sdi_delitem: { $crate::py_class_binary_slot!($class::__delitem__, [Option<&$key_name>], $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, @@ -688,7 +719,7 @@ macro_rules! py_class_impl { { { def __delitem__(&$slf:ident, $key:ident : &$key_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value:tt, sdi_delitem: {}, @@ -700,7 +731,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value, sdi_delitem: { $crate::py_class_binary_slot!($class::__delitem__, [&$key_name], $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, @@ -715,7 +746,7 @@ macro_rules! py_class_impl { { { def __delitem__(&$slf:ident, $key:ident : $key_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value:tt, sdi_delitem: {}, @@ -727,7 +758,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: $sdi_setitem_slot_value, sdi_delitem: { $crate::py_class_binary_slot!($class::__delitem__, [$key_name], $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, @@ -747,6 +778,37 @@ macro_rules! py_class_impl { { { def __dir__ $($tail:tt)* } $( $stuff:tt )* } => { $crate::py_error! { "__dir__ is not supported by py_class! yet." } }; + { { def __direct_buffer__ <$gil_lt:lifetime>(&$slf_lt:lifetime $slf:ident) -> $res_type:ty $body:block $($tail:tt)* } + $class:ident $py:ident $info:tt + /* slots: */ { + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + /* as_buffer */ [ + bf_getbuffer: {}, + bf_releasebuffer: {}, + ] + $setdelitem:tt + } + { $( $imp:item )* } + $members:tt $props:tt + } => { $crate::py_class_impl! { + { $($tail)* } + $class $py $info + /* slots: */ { + $type_slots $as_number $as_sequence $as_mapping + /* as_buffer */ [ + bf_getbuffer: { $crate::py_class_buffer_slot!(direct, bf_getbuffer, $class::__direct_buffer__) }, + bf_releasebuffer: { $crate::py_class_buffer_slot!(direct, bf_releasebuffer, $class::__direct_buffer__) }, + ] + $setdelitem + } + /* impl: */ { + $($imp)* + impl $class { + fn __direct_buffer__<$gil_lt>(&$slf_lt $slf, $py: $crate::Python<$gil_lt>) -> $res_type $body + } + } + $members $props + }}; { { def __div__ $($tail:tt)* } $( $stuff:tt )* } => { $crate::py_error! { "__div__ is not supported by py_class! yet." } @@ -789,7 +851,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -806,7 +868,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_subscript: $crate::py_class_binary_slot!($class::__getitem__, [Option<&$key_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -820,7 +882,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -837,7 +899,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_subscript: $crate::py_class_binary_slot!($class::__getitem__, [&$key_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -851,7 +913,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -868,7 +930,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_subscript: $crate::py_class_binary_slot!($class::__getitem__, [$key_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -888,7 +950,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -900,7 +962,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_hash: $crate::py_class_unary_slot!($class::__hash__, $crate::Py_hash_t, $crate::py_class::slots::HashConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -917,7 +979,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -930,7 +992,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_add: $crate::py_class_binary_slot!($class::__iadd__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -943,7 +1005,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -956,7 +1018,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_add: $crate::py_class_binary_slot!($class::__iadd__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -969,7 +1031,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -982,7 +1044,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_add: $crate::py_class_binary_slot!($class::__iadd__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -999,7 +1061,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1012,7 +1074,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_and: $crate::py_class_binary_slot!($class::__iand__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1025,7 +1087,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1038,7 +1100,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_and: $crate::py_class_binary_slot!($class::__iand__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1051,7 +1113,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1064,7 +1126,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_and: $crate::py_class_binary_slot!($class::__iand__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1085,7 +1147,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1098,7 +1160,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_floor_divide: $crate::py_class_binary_slot!($class::__ifloordiv__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1111,7 +1173,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1124,7 +1186,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_floor_divide: $crate::py_class_binary_slot!($class::__ifloordiv__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1137,7 +1199,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1150,7 +1212,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_floor_divide: $crate::py_class_binary_slot!($class::__ifloordiv__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1167,7 +1229,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1180,7 +1242,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_lshift: $crate::py_class_binary_slot!($class::__ilshift__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1193,7 +1255,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1206,7 +1268,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_lshift: $crate::py_class_binary_slot!($class::__ilshift__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1219,7 +1281,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1232,7 +1294,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_lshift: $crate::py_class_binary_slot!($class::__ilshift__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1249,7 +1311,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1262,7 +1324,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_matrix_multiply: $crate::py_class_binary_slot!($class::__imatmul__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1275,7 +1337,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1288,7 +1350,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_matrix_multiply: $crate::py_class_binary_slot!($class::__imatmul__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1301,7 +1363,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1314,7 +1376,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_matrix_multiply: $crate::py_class_binary_slot!($class::__imatmul__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1331,7 +1393,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1344,7 +1406,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_remainder: $crate::py_class_binary_slot!($class::__imod__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1357,7 +1419,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1370,7 +1432,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_remainder: $crate::py_class_binary_slot!($class::__imod__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1383,7 +1445,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1396,7 +1458,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_remainder: $crate::py_class_binary_slot!($class::__imod__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1413,7 +1475,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1426,7 +1488,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_multiply: $crate::py_class_binary_slot!($class::__imul__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1439,7 +1501,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1452,7 +1514,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_multiply: $crate::py_class_binary_slot!($class::__imul__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1465,7 +1527,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1478,7 +1540,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_multiply: $crate::py_class_binary_slot!($class::__imul__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1511,7 +1573,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1524,7 +1586,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_invert: $crate::py_class_unary_slot!($class::__invert__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1541,7 +1603,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1554,7 +1616,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_or: $crate::py_class_binary_slot!($class::__ior__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1567,7 +1629,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1580,7 +1642,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_or: $crate::py_class_binary_slot!($class::__ior__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1593,7 +1655,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1606,7 +1668,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_or: $crate::py_class_binary_slot!($class::__ior__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1627,7 +1689,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1640,7 +1702,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_rshift: $crate::py_class_binary_slot!($class::__irshift__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1653,7 +1715,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1666,7 +1728,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_rshift: $crate::py_class_binary_slot!($class::__irshift__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1679,7 +1741,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1692,7 +1754,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_rshift: $crate::py_class_binary_slot!($class::__irshift__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1709,7 +1771,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1722,7 +1784,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_subtract: $crate::py_class_binary_slot!($class::__isub__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1735,7 +1797,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1748,7 +1810,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_subtract: $crate::py_class_binary_slot!($class::__isub__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1761,7 +1823,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1774,7 +1836,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_subtract: $crate::py_class_binary_slot!($class::__isub__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1790,7 +1852,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1802,7 +1864,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_iter: $crate::py_class_unary_slot!($class::__iter__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1819,7 +1881,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1832,7 +1894,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_true_divide: $crate::py_class_binary_slot!($class::__itruediv__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1845,7 +1907,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1858,7 +1920,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_true_divide: $crate::py_class_binary_slot!($class::__itruediv__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1871,7 +1933,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1884,7 +1946,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_true_divide: $crate::py_class_binary_slot!($class::__itruediv__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1901,7 +1963,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1914,7 +1976,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_xor: $crate::py_class_binary_slot!($class::__ixor__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1927,7 +1989,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1940,7 +2002,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_xor: $crate::py_class_binary_slot!($class::__ixor__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1953,7 +2015,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -1966,7 +2028,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_inplace_xor: $crate::py_class_binary_slot!($class::__ixor__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -1988,7 +2050,7 @@ macro_rules! py_class_impl { $type_slots:tt $as_number:tt /* as_sequence */ [ $( $sq_slot_name:ident : $sq_slot_value:expr, )* ] /* as_mapping */ [ $( $mp_slot_name:ident : $mp_slot_value:expr, )* ] - $setdelitem:tt + $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2005,7 +2067,7 @@ macro_rules! py_class_impl { $( $mp_slot_name : $mp_slot_value, )* mp_length: Some($crate::_detail::ffi::PySequence_Size), ] - $setdelitem + $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2026,7 +2088,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2039,7 +2101,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_lshift: $crate::py_class_binary_numeric_slot!($class::__lshift__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2068,7 +2130,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2081,7 +2143,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_multiply: $crate::py_class_binary_numeric_slot!($class::__mul__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2102,7 +2164,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2115,7 +2177,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_negative: $crate::py_class_unary_slot!($class::__neg__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2131,7 +2193,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2143,7 +2205,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_new: $crate::py_class_wrap_newfunc!{$class::__new__ []}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2155,7 +2217,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2167,7 +2229,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_new: $crate::py_argparse_parse_plist_impl!{py_class_wrap_newfunc {$class::__new__} [] ($($p)+,)}, ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2182,7 +2244,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2194,7 +2256,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_iternext: $crate::py_class_unary_slot!($class::__next__, *mut $crate::_detail::ffi::PyObject, $crate::py_class::slots::IterNextResultConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2215,7 +2277,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2228,7 +2290,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_or: $crate::py_class_binary_numeric_slot!($class::__or__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2245,7 +2307,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2258,7 +2320,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_positive: $crate::py_class_unary_slot!($class::__pos__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2294,7 +2356,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2306,7 +2368,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_repr: $crate::py_class_unary_slot!($class::__repr__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PythonObjectCallbackConverter::<$crate::PyString>(std::marker::PhantomData)), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2326,7 +2388,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2338,7 +2400,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_richcompare: $crate::py_class_richcompare_slot!($class::__richcmp__, [Option<&$other_name>], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2350,7 +2412,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2362,7 +2424,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_richcompare: $crate::py_class_richcompare_slot!($class::__richcmp__, [&$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2374,7 +2436,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2386,7 +2448,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_richcompare: $crate::py_class_richcompare_slot!($class::__richcmp__, [$other_name], *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2435,7 +2497,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2448,7 +2510,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_rshift: $crate::py_class_binary_numeric_slot!($class::__rshift__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2483,7 +2545,7 @@ macro_rules! py_class_impl { { { def __setitem__(&$slf:ident, $key:ident : Option<&$key_name:ty>, $value:ident : $value_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: {}, sdi_delitem: $sdi_delitem_slot_value:tt, @@ -2495,7 +2557,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: { $crate::py_class_ternary_slot!($class::__setitem__, [Option<&$key_name>], $value_name, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, sdi_delitem: $sdi_delitem_slot_value, @@ -2510,7 +2572,7 @@ macro_rules! py_class_impl { { { def __setitem__(&$slf:ident, $key:ident : &$key_name:ty, $value:ident : $value_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: {}, sdi_delitem: $sdi_delitem_slot_value:tt, @@ -2522,7 +2584,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: { $crate::py_class_ternary_slot!($class::__setitem__, [&$key_name], $value_name, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, sdi_delitem: $sdi_delitem_slot_value, @@ -2537,7 +2599,7 @@ macro_rules! py_class_impl { { { def __setitem__(&$slf:ident, $key:ident : $key_name:ty, $value:ident : $value_name:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* } $class:ident $py:ident $info:tt /* slots: */ { - $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt + $type_slots:tt $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt /* setdelitem */ [ sdi_setitem: {}, sdi_delitem: $sdi_delitem_slot_value:tt, @@ -2549,7 +2611,7 @@ macro_rules! py_class_impl { { $($tail)* } $class $py $info /* slots: */ { - $type_slots $as_number $as_sequence $as_mapping + $type_slots $as_number $as_sequence $as_mapping $as_buffer /* setdelitem */ [ sdi_setitem: { $crate::py_class_ternary_slot!($class::__setitem__, [$key_name], $value_name, $crate::_detail::libc::c_int, $crate::py_class::slots::UnitCallbackConverter) }, sdi_delitem: $sdi_delitem_slot_value, @@ -2569,7 +2631,7 @@ macro_rules! py_class_impl { $class:ident $py:ident $info:tt /* slots: */ { /* type_slots */ [ $( $tp_slot_name:ident : $tp_slot_value:expr, )* ] - $as_number:tt $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_number:tt $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2581,7 +2643,7 @@ macro_rules! py_class_impl { $( $tp_slot_name : $tp_slot_value, )* tp_str: $crate::py_class_unary_slot!($class::__str__, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PythonObjectCallbackConverter::<$crate::PyString>(std::marker::PhantomData)), ] - $as_number $as_sequence $as_mapping $setdelitem + $as_number $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2598,7 +2660,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2611,7 +2673,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_subtract: $crate::py_class_binary_numeric_slot!($class::__sub__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* @@ -2636,7 +2698,7 @@ macro_rules! py_class_impl { /* slots: */ { $type_slots:tt /* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ] - $as_sequence:tt $as_mapping:tt $setdelitem:tt + $as_sequence:tt $as_mapping:tt $as_buffer:tt $setdelitem:tt } { $( $imp:item )* } $members:tt $props:tt @@ -2649,7 +2711,7 @@ macro_rules! py_class_impl { $( $nb_slot_name : $nb_slot_value, )* nb_xor: $crate::py_class_binary_numeric_slot!($class::__xor__), ] - $as_sequence $as_mapping $setdelitem + $as_sequence $as_mapping $as_buffer $setdelitem } /* impl: */ { $($imp)* diff --git a/src/py_class/slots.rs b/src/py_class/slots.rs index ac6e24bd..cb25091f 100644 --- a/src/py_class/slots.rs +++ b/src/py_class/slots.rs @@ -18,8 +18,10 @@ use libc::{c_char, c_int}; use std::ffi::CString; +use std::marker::PhantomData; use std::{isize, mem, ptr}; +use crate::buffer::BufferHandle; use crate::conversion::ToPyObject; use crate::err::{PyErr, PyResult}; use crate::exc; @@ -28,6 +30,7 @@ use crate::function::CallbackConverter; use crate::objects::PyObject; use crate::py_class::CompareOp; use crate::python::{Python, PythonObject}; +use crate::PySharedRef; use crate::Py_hash_t; #[macro_export] @@ -40,6 +43,7 @@ macro_rules! py_class_type_object_static_init { $as_number:tt $as_sequence:tt $as_mapping:tt + $as_buffer:tt $setdelitem:tt }) => ( $crate::_detail::ffi::PyTypeObject { @@ -86,6 +90,7 @@ macro_rules! py_class_type_object_dynamic_init { $as_number:tt $as_sequence:tt $as_mapping:tt + $as_buffer:tt $setdelitem:tt } $props:tt @@ -101,6 +106,7 @@ macro_rules! py_class_type_object_dynamic_init { *(unsafe { &mut $type_object.tp_as_sequence }) = $crate::py_class_as_sequence!($as_sequence); *(unsafe { &mut $type_object.tp_as_number }) = $crate::py_class_as_number!($as_number); + *(unsafe { &mut $type_object.tp_as_buffer }) = $crate::py_class_as_buffer!($as_buffer); $crate::py_class_as_mapping!($type_object, $as_mapping, $setdelitem); *(unsafe { &mut $type_object.tp_getset }) = $crate::py_class_tp_getset!($class, $props); }; @@ -184,6 +190,29 @@ macro_rules! py_class_as_number { }} } +#[macro_export] +#[doc(hidden)] +macro_rules! py_class_as_buffer { + ([ + bf_getbuffer: {}, + bf_releasebuffer: {}, + ]) => { + 0 as *mut $crate::_detail::ffi::PyBufferProcs + }; + ([ + bf_getbuffer: $bf_getbuffer:expr, + bf_releasebuffer: $bf_releasebuffer:expr, + ]) => {{ + static mut BUFFER_PROCS: $crate::_detail::ffi::PyBufferProcs = + $crate::_detail::ffi::PyBufferProcs { + bf_getbuffer: $bf_getbuffer, + bf_releasebuffer: $bf_releasebuffer, + ..$crate::_detail::ffi::PyBufferProcs_INIT + }; + unsafe { &mut BUFFER_PROCS } + }}; +} + #[macro_export] #[doc(hidden)] macro_rules! py_class_as_mapping { @@ -538,6 +567,232 @@ macro_rules! py_class_binary_numeric_slot { }}; } +#[doc(hidden)] +pub struct BufferHandleRaw { + pub buf: *mut libc::c_void, + pub len: crate::Py_ssize_t, + pub owner: *mut libc::c_void, +} + +impl BufferHandleRaw { + #[doc(hidden)] + #[inline] + pub unsafe fn new_owned(handle: T) -> Self { + let slice = handle.as_bytes(); + let buf = slice.as_ptr() as *mut libc::c_void; + let len = slice.len() as crate::Py_ssize_t; + let owner = handle.into_owned_void_pointer(); + Self { buf, len, owner } + } + + #[doc(hidden)] + #[inline] + pub unsafe fn new_borrowed(slice: &[u8]) -> Self { + let buf = slice.as_ptr() as *mut libc::c_void; + let len = slice.len() as crate::Py_ssize_t; + let owner = ptr::null_mut(); + Self { buf, len, owner } + } +} + +pub struct BufferHandleConverter; + +impl CallbackConverter for BufferHandleConverter { + type R = Option; + + #[inline] + fn convert(val: BufferHandleRaw, _: Python) -> Option { + Some(val) + } + + #[inline] + fn error_value() -> Option { + None + } +} +/// This is a bit of a hack to get the actual type of the Rust Buffer from +/// the py_class's method return type. +#[doc(hidden)] +pub struct BufferType(PhantomData); +impl BufferType { + #[doc(hidden)] + #[inline] + pub fn of(_: fn(&C, Python) -> PyResult) -> Self { + Self(PhantomData) + } + + #[doc(hidden)] + #[inline] + pub fn assert_same_type(self, _: &T) {} + + #[doc(hidden)] + #[inline] + pub unsafe fn drop_buffer(self, ptr: *mut libc::c_void) { + T::from_owned_void_pointer(ptr); + } +} + +#[doc(hidden)] +#[inline] +pub fn assert_buffer_type_direct(_: for<'a> fn(&'a C, Python<'a>) -> PyResult<&'a [u8]>) {} + +#[macro_export] +#[doc(hidden)] +macro_rules! py_class_buffer_slot { + (handle, bf_getbuffer, $class:ident :: $f:ident) => {{ + unsafe extern "C" fn getbufferproc( + exporter: *mut $crate::_detail::ffi::PyObject, + view: *mut $crate::_detail::ffi::Py_buffer, + flags: $crate::_detail::libc::c_int, + ) -> $crate::_detail::libc::c_int { + /* + According to https://docs.python.org/3/c-api/typeobj.html#c.PyBufferProcs, + the implementation of this function needs to behave like this: + + 1. Check if the request can be met. If not, raise PyExc_BufferError, + set view->obj to NULL and return -1. + 2. Fill in the requested fields. + 3. Increment an internal counter for the number of exports. + 4. Set view->obj to exporter and increment view->obj. + 5. Return 0. + + We handle 1) by trying to get a buffer via the Rust API, and 2) and 4) + via `PyBuffer_FillInfo`. Instead of doing 3) by tracking the number of + exported buffers in `exporter`, we take ownership of a handle for the + buffer and store it in `view.internal`. + */ + + const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); + let res = $crate::_detail::handle_callback( + LOCATION, + $crate::py_class::slots::BufferHandleConverter, + |py| { + let slf = $crate::PyObject::from_borrowed_ptr(py, exporter) + .unchecked_cast_into::<$class>(); + + let buf_handle = slf.$f(py)?; + + // assert that we are working with the same type as in + // `releasebufferproc` + $crate::py_class::slots::BufferType::of($class::$f) + .assert_same_type(&buf_handle); + + let buf_handle_raw = + $crate::py_class::slots::BufferHandleRaw::new_owned(buf_handle); + Ok(buf_handle_raw) + }, + ); + match res { + None => -1, + Some($crate::py_class::slots::BufferHandleRaw { buf, len, owner }) => { + let readonly = 0x1; + let ret = $crate::_detail::ffi::PyBuffer_FillInfo( + view, exporter, buf, len, readonly, flags, + ); + if ret == 0 { + (*view).internal = owner; + } + ret + } + } + } + Some(getbufferproc) + }}; + (handle, bf_releasebuffer, $class:ident :: $f:ident) => {{ + unsafe extern "C" fn releasebufferproc( + exporter: *mut $crate::_detail::ffi::PyObject, + view: *mut $crate::_detail::ffi::Py_buffer, + ) { + /* + According to https://docs.python.org/3/c-api/typeobj.html#c.PyBufferProcs, + the implementation of this function needs to (optionally) behave like this: + + 1. Decrement an internal counter for the number of exports. + 2. If the counter is 0, free all memory associated with view. + + However, we are not reference counting the buffer inside the export object, + but rather handle this by carrying around a owned handle in `view.internal`, + which we drop here again. + */ + + const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); + $crate::_detail::handle_callback( + LOCATION, + $crate::py_class::slots::UnitCallbackConverter, + |py| { + let owner = (*view).internal; + + // zeroing out the buffer fields should not be needed here, + // but we do so defensivly to catch bugs. + (*view).internal = 0 as *mut _; + (*view).buf = 0 as *mut _; + (*view).len = 0; + + $crate::py_class::slots::BufferType::of($class::$f).drop_buffer(owner); + + Ok(()) + }, + ); + } + Some(releasebufferproc) + }}; + (direct, bf_getbuffer, $class:ident :: $f:ident) => {{ + unsafe extern "C" fn getbufferproc( + exporter: *mut $crate::_detail::ffi::PyObject, + view: *mut $crate::_detail::ffi::Py_buffer, + flags: $crate::_detail::libc::c_int, + ) -> $crate::_detail::libc::c_int { + /* + According to https://docs.python.org/3/c-api/typeobj.html#c.PyBufferProcs, + the implementation of this function needs to behave like this: + + 1. Check if the request can be met. If not, raise PyExc_BufferError, + set view->obj to NULL and return -1. + 2. Fill in the requested fields. + 3. Increment an internal counter for the number of exports. + 4. Set view->obj to exporter and increment view->obj. + 5. Return 0. + + We handle 1) by trying to get a buffer via the Rust API, and 2) and 4) + via `PyBuffer_FillInfo`. Instead of doing 3) by tracking the number of + exported buffers in `exporter`, we just do nothing. + */ + + const LOCATION: &'static str = concat!(stringify!($class), ".", stringify!($f), "()"); + let res = $crate::_detail::handle_callback( + LOCATION, + $crate::py_class::slots::BufferHandleConverter, + |py| { + let slf = $crate::PyObject::from_borrowed_ptr(py, exporter) + .unchecked_cast_into::<$class>(); + + // assert that we are borrowing bytes from the refcounted $class object + $crate::py_class::slots::assert_buffer_type_direct($class::$f); + + let buf_slice = slf.$f(py)?; + + let buf_handle_raw = + $crate::py_class::slots::BufferHandleRaw::new_borrowed(buf_slice); + Ok(buf_handle_raw) + }, + ); + match res { + None => -1, + Some($crate::py_class::slots::BufferHandleRaw { buf, len, owner }) => { + let readonly = 0x1; + $crate::_detail::ffi::PyBuffer_FillInfo( + view, exporter, buf, len, readonly, flags, + ) + } + } + } + Some(getbufferproc) + }}; + (direct, bf_releasebuffer, $class:ident :: $f:ident) => {{ + None + }}; +} + pub struct UnitCallbackConverter; impl CallbackConverter<()> for UnitCallbackConverter { diff --git a/tests/test_class.rs b/tests/test_class.rs index b448c5a6..a3233395 100644 --- a/tests/test_class.rs +++ b/tests/test_class.rs @@ -1276,3 +1276,209 @@ fn properties() { py_run!(py, c, "del c.prop_by_opt_ref"); py_run!(py, c, "repr(c) == 'P(42, \"testing\" \"DELETED\")'"); } + +#[cfg(feature = "python3-sys")] +mod py3_only { + use self::RefCountLog::*; + use super::*; + use std::sync::Mutex; + + #[derive(PartialEq, Debug)] + enum RefCountLog { + Plus, + Minus, + } + + struct SharedBuffer { + buf: Vec, + log: Mutex>, + } + + impl SharedBuffer { + fn new(buf: Vec) -> Arc { + Arc::new(SharedBuffer { + buf, + log: Mutex::new(vec![]), + }) + } + } + + struct TestBuffer { + ptr: Arc, + count_drop: bool, + } + + impl TestBuffer { + fn new(ptr: &Arc) -> Self { + ptr.log.lock().unwrap().push(RefCountLog::Plus); + Self::from_arc(ptr.clone()) + } + fn into_arc(mut self) -> Arc { + self.count_drop = false; + self.ptr.clone() + } + fn from_arc(ptr: Arc) -> Self { + Self { + ptr: ptr.clone(), + count_drop: true, + } + } + } + impl Drop for TestBuffer { + fn drop(&mut self) { + if self.count_drop { + self.ptr.log.lock().unwrap().push(RefCountLog::Minus); + } + } + } + + unsafe impl buffer::BufferHandle for TestBuffer { + fn as_bytes(&self) -> &[u8] { + &self.ptr.buf + } + fn into_owned_void_pointer(self) -> *mut libc::c_void { + let raw = Arc::into_raw(self.into_arc()); + assert_eq!( + std::mem::size_of::<*mut libc::c_void>(), + std::mem::size_of_val(&raw) + ); + raw as *const libc::c_void as *mut libc::c_void + } + unsafe fn from_owned_void_pointer(ptr: *mut libc::c_void) -> Self { + TestBuffer::from_arc(Arc::from_raw(ptr as *const libc::c_void as *const _)) + } + } + + py_class!(class BufferProtocol |py| { + data ptr: Arc; + + def __buffer__(&self) -> PyResult { + Ok(TestBuffer::new(self.ptr(py))) + } + }); + + #[test] + fn test_buffer() { + let gil = Python::acquire_gil(); + let py = gil.python(); + + let buf = SharedBuffer::new(vec![1, 2, 42]); + let log_access = buf.clone(); + + let c = BufferProtocol::create_instance(py, buf).unwrap(); + + macro_rules! check_log { + ($($e:expr),+; $($r:expr),+) => { + py_run!(py, c, &[$($e),+].join("\n")[..]); + { + let should_log = &[$($r),+]; + let mut log = log_access.log.lock().unwrap(); + assert_eq!(&**log, should_log); + log.clear(); + } + } + } + + check_log!("memoryview(c)"; Plus, Minus); + check_log!("assert memoryview(c).readonly"; Plus, Minus); + check_log!("assert len(memoryview(c)) == 3"; Plus, Minus); + check_log!("assert memoryview(c)[0] == 1"; Plus, Minus); + check_log!("assert memoryview(c)[2] == 42"; Plus, Minus); + check_log!("assert list(memoryview(c)) == [1, 2, 42]"; Plus, Minus); + check_log!( + "a = memoryview(c)", + "b = memoryview(c)", + "assert a == b"; + Plus, Plus, Minus, Minus); + check_log!( + "a = memoryview(c)", + "b = memoryview(a)", + "assert a == b"; + Plus, Minus); + check_log!( + "def foo(x):", + " a = memoryview(x)", + " assert a[1] == 2", + "foo(c)", + "foo(c)"; + Plus, Minus, Plus, Minus); + check_log!( + "def foo(x):", + " a = memoryview(x)", + " assert a[1] == 2", + "foo(c)", + "e = memoryview(c)", + "f = memoryview(c)", + "assert e[2] == f[2] == 42"; + Plus, Minus, Plus, Plus, Minus, Minus); + + check_log!( + "with memoryview(c):", + " pass", + "with memoryview(c):", + " pass"; + Plus, Minus, Plus, Minus); + + py_expect_exception!(py, c, "memoryview(c)[3]", IndexError); + py_expect_exception!(py, c, "memoryview(c)[2] = 413", TypeError); + } + + py_class!(class DirectBufferProtocol |py| { + data ptr: Arc>; + + def __direct_buffer__<'a>(&'a self) -> PyResult<&'a [u8]> { + Ok(self.ptr(py)) + } + }); + + #[test] + fn test_direct_buffer() { + let gil = Python::acquire_gil(); + let py = gil.python(); + + let buf = Arc::new(vec![1, 2, 42]); + + let c = DirectBufferProtocol::create_instance(py, buf).unwrap(); + + macro_rules! check_log { + ($($e:expr),+) => { + py_run!(py, c, &[$($e),+].join("\n")[..]); + } + } + + check_log!("memoryview(c)"); + check_log!("assert memoryview(c).readonly"); + check_log!("assert len(memoryview(c)) == 3"); + check_log!("assert memoryview(c)[0] == 1"); + check_log!("assert memoryview(c)[2] == 42"); + check_log!("assert list(memoryview(c)) == [1, 2, 42]"); + check_log!("a = memoryview(c)", "b = memoryview(c)", "assert a == b"); + check_log!("a = memoryview(c)", "b = memoryview(a)", "assert a == b"); + check_log!( + "def foo(x):", + " a = memoryview(x)", + " assert a[1] == 2", + "foo(c)", + "foo(c)" + ); + check_log!( + "def foo(x):", + " a = memoryview(x)", + " assert a[1] == 2", + "foo(c)", + "e = memoryview(c)", + "f = memoryview(c)", + "assert e[2] == f[2] == 42" + ); + + check_log!( + "with memoryview(c):", + " pass", + "with memoryview(c):", + " pass" + ); + + py_expect_exception!(py, c, "memoryview(c)[3]", IndexError); + py_expect_exception!(py, c, "memoryview(c)[2] = 413", TypeError); + } +}