Add support for in-place numeric operators in py_class!
This commit is contained in:
parent
72e1e05835
commit
2e8d343b0f
|
@ -351,6 +351,26 @@ py_class!(class MyIterator |py| {
|
|||
If you can't handle the combination of types you've been given,
|
||||
you should return `Ok(py.NotImplemented())`.
|
||||
|
||||
* `def __iadd__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __isub__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __imul__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __imatmul__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __itruediv__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __ifloordiv__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __imod__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __ilshift__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __irshift__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __iand__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __ixor__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
* `def __ior__(&self, other: impl ExtractPyObject) -> PyResult<impl ToPyObject>`
|
||||
|
||||
Handles inplace operations if possible, falling back to the non-inplace versions.
|
||||
These methods must return a new reference! In the common case of returning the
|
||||
same (mutated) object, you will want to return `Ok(self.clone_ref(py))`.
|
||||
|
||||
If you can't handle the combination of types you've been given,
|
||||
you should return `Ok(py.NotImplemented())`.
|
||||
|
||||
## Context Manager
|
||||
|
||||
* `def __enter__(&self) -> PyResult<impl ToPyObject>`
|
||||
|
|
|
@ -584,6 +584,11 @@ def reflected_numeric_operator(special_name):
|
|||
error('Reflected numeric operator %s is not supported by py_class! Use __%s__ instead!'
|
||||
% (special_name, special_name[3:-2]))(special_name)
|
||||
|
||||
@special_method
|
||||
def inplace_numeric_operator(special_name, slot):
|
||||
operator(slot=slot,
|
||||
args=[Argument('other')])(special_name)
|
||||
|
||||
special_names = {
|
||||
'__init__': error('__init__ is not supported by py_class!; use __new__ instead.'),
|
||||
'__new__': special_class_method(
|
||||
|
@ -694,21 +699,20 @@ special_names = {
|
|||
'__ror__': reflected_numeric_operator(),
|
||||
|
||||
# Emulating numeric types - in-place
|
||||
'__iadd__': unimplemented(),
|
||||
'__isub__': unimplemented(),
|
||||
'__imul__': unimplemented(),
|
||||
'__imatmul__': unimplemented(),
|
||||
'__iadd__': inplace_numeric_operator('nb_inplace_add'),
|
||||
'__isub__': inplace_numeric_operator('nb_inplace_subtract'),
|
||||
'__imul__': inplace_numeric_operator('nb_inplace_multiply'),
|
||||
'__imatmul__': inplace_numeric_operator('nb_inplace_matrix_multiply'),
|
||||
'__idiv__': unimplemented(),
|
||||
'__itruediv__': unimplemented(),
|
||||
'__ifloordiv__': unimplemented(),
|
||||
'__imod__': unimplemented(),
|
||||
'__idivmod__': unimplemented(),
|
||||
'__itruediv__': inplace_numeric_operator('nb_inplace_true_divide'),
|
||||
'__ifloordiv__': inplace_numeric_operator('nb_inplace_floor_divide'),
|
||||
'__imod__': inplace_numeric_operator('nb_inplace_remainder'),
|
||||
'__ipow__': unimplemented(),
|
||||
'__ilshift__': unimplemented(),
|
||||
'__irshift__': unimplemented(),
|
||||
'__iand__': unimplemented(),
|
||||
'__ixor__': unimplemented(),
|
||||
'__ior__': unimplemented(),
|
||||
'__ilshift__': inplace_numeric_operator('nb_inplace_lshift'),
|
||||
'__irshift__': inplace_numeric_operator('nb_inplace_rshift'),
|
||||
'__iand__': inplace_numeric_operator('nb_inplace_and'),
|
||||
'__ixor__': inplace_numeric_operator('nb_inplace_xor'),
|
||||
'__ior__': inplace_numeric_operator('nb_inplace_or'),
|
||||
|
||||
# Unary arithmetic
|
||||
'__neg__': operator('nb_negative'),
|
||||
|
|
|
@ -673,41 +673,219 @@ macro_rules! py_class_impl {
|
|||
{ { def __hash__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "Invalid signature for operator __hash__" }
|
||||
};
|
||||
{ { def __iadd__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_add: py_class_binary_slot!($class::__iadd__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __iadd__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __iadd__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__iadd__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __iadd__" }
|
||||
};
|
||||
{ { def __iand__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_and: py_class_binary_slot!($class::__iand__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __iand__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __iand__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__iand__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __iand__" }
|
||||
};
|
||||
|
||||
{ { def __idiv__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__idiv__ is not supported by py_class! yet." }
|
||||
};
|
||||
|
||||
{ { def __idivmod__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__idivmod__ is not supported by py_class! yet." }
|
||||
};
|
||||
{ { def __ifloordiv__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_floor_divide: py_class_binary_slot!($class::__ifloordiv__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ifloordiv__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ifloordiv__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ifloordiv__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ifloordiv__" }
|
||||
};
|
||||
{ { def __ilshift__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_lshift: py_class_binary_slot!($class::__ilshift__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ilshift__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ilshift__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ilshift__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ilshift__" }
|
||||
};
|
||||
{ { def __imatmul__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_matrix_multiply: py_class_binary_slot!($class::__imatmul__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __imatmul__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __imatmul__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__imatmul__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __imatmul__" }
|
||||
};
|
||||
{ { def __imod__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_remainder: py_class_binary_slot!($class::__imod__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __imod__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __imod__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__imod__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __imod__" }
|
||||
};
|
||||
{ { def __imul__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_multiply: py_class_binary_slot!($class::__imul__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __imul__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __imul__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__imul__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __imul__" }
|
||||
};
|
||||
|
||||
{ { def __index__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
|
@ -755,21 +933,99 @@ macro_rules! py_class_impl {
|
|||
{ { def __invert__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "Invalid signature for operator __invert__" }
|
||||
};
|
||||
{ { def __ior__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_or: py_class_binary_slot!($class::__ior__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ior__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ior__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ior__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ior__" }
|
||||
};
|
||||
|
||||
{ { def __ipow__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ipow__ is not supported by py_class! yet." }
|
||||
};
|
||||
{ { def __irshift__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_rshift: py_class_binary_slot!($class::__irshift__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __irshift__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __irshift__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__irshift__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __irshift__" }
|
||||
};
|
||||
{ { def __isub__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_subtract: py_class_binary_slot!($class::__isub__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __isub__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __isub__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__isub__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __isub__" }
|
||||
};
|
||||
{ { def __iter__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
|
@ -799,13 +1055,65 @@ macro_rules! py_class_impl {
|
|||
{ { def __iter__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "Invalid signature for operator __iter__" }
|
||||
};
|
||||
{ { def __itruediv__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_true_divide: py_class_binary_slot!($class::__itruediv__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __itruediv__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __itruediv__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__itruediv__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __itruediv__" }
|
||||
};
|
||||
{ { def __ixor__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_xor: py_class_binary_slot!($class::__ixor__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ixor__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ixor__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ixor__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ixor__" }
|
||||
};
|
||||
|
||||
{ { def __le__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
|
|
|
@ -673,41 +673,219 @@ macro_rules! py_class_impl {
|
|||
{ { def __hash__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "Invalid signature for operator __hash__" }
|
||||
};
|
||||
{ { def __iadd__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_add: py_class_binary_slot!($class::__iadd__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __iadd__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __iadd__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__iadd__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __iadd__" }
|
||||
};
|
||||
{ { def __iand__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_and: py_class_binary_slot!($class::__iand__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __iand__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __iand__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__iand__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __iand__" }
|
||||
};
|
||||
|
||||
{ { def __idiv__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__idiv__ is not supported by py_class! yet." }
|
||||
};
|
||||
|
||||
{ { def __idivmod__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__idivmod__ is not supported by py_class! yet." }
|
||||
};
|
||||
{ { def __ifloordiv__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_floor_divide: py_class_binary_slot!($class::__ifloordiv__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ifloordiv__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ifloordiv__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ifloordiv__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ifloordiv__" }
|
||||
};
|
||||
{ { def __ilshift__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_lshift: py_class_binary_slot!($class::__ilshift__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ilshift__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ilshift__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ilshift__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ilshift__" }
|
||||
};
|
||||
{ { def __imatmul__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_matrix_multiply: py_class_binary_slot!($class::__imatmul__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __imatmul__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __imatmul__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__imatmul__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __imatmul__" }
|
||||
};
|
||||
{ { def __imod__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_remainder: py_class_binary_slot!($class::__imod__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __imod__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __imod__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__imod__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __imod__" }
|
||||
};
|
||||
{ { def __imul__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_multiply: py_class_binary_slot!($class::__imul__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __imul__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __imul__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__imul__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __imul__" }
|
||||
};
|
||||
|
||||
{ { def __index__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
|
@ -755,21 +933,99 @@ macro_rules! py_class_impl {
|
|||
{ { def __invert__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "Invalid signature for operator __invert__" }
|
||||
};
|
||||
{ { def __ior__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_or: py_class_binary_slot!($class::__ior__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ior__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ior__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ior__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ior__" }
|
||||
};
|
||||
|
||||
{ { def __ipow__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ipow__ is not supported by py_class! yet." }
|
||||
};
|
||||
{ { def __irshift__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_rshift: py_class_binary_slot!($class::__irshift__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __irshift__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __irshift__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__irshift__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __irshift__" }
|
||||
};
|
||||
{ { def __isub__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_subtract: py_class_binary_slot!($class::__isub__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __isub__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __isub__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__isub__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __isub__" }
|
||||
};
|
||||
{ { def __iter__(&$slf:ident) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
|
@ -799,13 +1055,65 @@ macro_rules! py_class_impl {
|
|||
{ { def __iter__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "Invalid signature for operator __iter__" }
|
||||
};
|
||||
{ { def __itruediv__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_true_divide: py_class_binary_slot!($class::__itruediv__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __itruediv__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __itruediv__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__itruediv__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __itruediv__" }
|
||||
};
|
||||
{ { def __ixor__(&$slf:ident, $other:ident : $other_type:ty) -> $res_type:ty { $($body:tt)* } $($tail:tt)* }
|
||||
$class:ident $py:ident $info:tt
|
||||
/* slots: */ {
|
||||
$type_slots:tt
|
||||
/* as_number */ [ $( $nb_slot_name:ident : $nb_slot_value:expr, )* ]
|
||||
$as_sequence:tt $as_mapping:tt $setdelitem:tt
|
||||
}
|
||||
{ $( $imp:item )* }
|
||||
$members:tt
|
||||
} => { py_class_impl! {
|
||||
{ $($tail)* }
|
||||
$class $py $info
|
||||
/* slots: */ {
|
||||
$type_slots
|
||||
/* as_number */ [
|
||||
$( $nb_slot_name : $nb_slot_value, )*
|
||||
nb_inplace_xor: py_class_binary_slot!($class::__ixor__, $other_type, *mut $crate::_detail::ffi::PyObject, $crate::_detail::PyObjectCallbackConverter),
|
||||
]
|
||||
$as_sequence $as_mapping $setdelitem
|
||||
}
|
||||
/* impl: */ {
|
||||
$($imp)*
|
||||
py_class_impl_item! { $class, $py, __ixor__(&$slf,) $res_type; { $($body)* } [{ $other : $other_type = {} }] }
|
||||
}
|
||||
$members
|
||||
}};
|
||||
|
||||
{ { def __ixor__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
py_error! { "__ixor__ is not supported by py_class! yet." }
|
||||
py_error! { "Invalid signature for operator __ixor__" }
|
||||
};
|
||||
|
||||
{ { def __le__ $($tail:tt)* } $( $stuff:tt )* } => {
|
||||
|
|
|
@ -749,6 +749,84 @@ fn rich_comparisons_python_3_type_error() {
|
|||
py_expect_exception!(py, c2, "1 >= c2", TypeError);
|
||||
}
|
||||
|
||||
py_class!(class InPlaceOperations |py| {
|
||||
data value: Cell<u32>;
|
||||
|
||||
def __repr__(&self) -> PyResult<String> {
|
||||
Ok(format!("IPO({:?})", self.value(py).get()))
|
||||
}
|
||||
|
||||
def __iadd__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() + other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
|
||||
def __isub__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() - other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
|
||||
def __imul__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() * other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
|
||||
def __ilshift__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() << other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
|
||||
def __irshift__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() >> other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
|
||||
def __iand__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() & other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
|
||||
def __ixor__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() ^ other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
|
||||
def __ior__(&self, other: u32) -> PyResult<Self> {
|
||||
self.value(py).set(self.value(py).get() | other);
|
||||
Ok(self.clone_ref(py))
|
||||
}
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn inplace_operations() {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(0)).unwrap();
|
||||
py_run!(py, c, "d = c; c += 1; assert repr(c) == repr(d) == 'IPO(1)'");
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(10)).unwrap();
|
||||
py_run!(py, c, "d = c; c -= 1; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(3)).unwrap();
|
||||
py_run!(py, c, "d = c; c *= 3; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(3)).unwrap();
|
||||
py_run!(py, c, "d = c; c <<= 2; assert repr(c) == repr(d) == 'IPO(12)'");
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(12)).unwrap();
|
||||
py_run!(py, c, "d = c; c >>= 2; assert repr(c) == repr(d) == 'IPO(3)'");
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(12)).unwrap();
|
||||
py_run!(py, c, "d = c; c &= 10; assert repr(c) == repr(d) == 'IPO(8)'");
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(12)).unwrap();
|
||||
py_run!(py, c, "d = c; c |= 3; assert repr(c) == repr(d) == 'IPO(15)'");
|
||||
|
||||
let c = InPlaceOperations::create_instance(py, Cell::new(12)).unwrap();
|
||||
py_run!(py, c, "d = c; c ^= 5; assert repr(c) == repr(d) == 'IPO(9)'");
|
||||
}
|
||||
|
||||
py_class!(class ContextManager |py| {
|
||||
data exit_called : Cell<bool>;
|
||||
|
||||
|
|
Loading…
Reference in New Issue