pymethods: add support for inplace concat & repeat
This commit is contained in:
parent
253507b5dd
commit
424644181b
|
@ -243,6 +243,18 @@ and `Return` a final value - see its docs for further details and an example.
|
|||
Used by the `*` operator, after trying the numeric multiplication via
|
||||
the `__mul__` and `__rmul__` methods.
|
||||
|
||||
* `fn __inplace_concat__(&self, other: impl FromPyObject) -> PyResult<impl ToPyObject>`
|
||||
|
||||
Concatenates two sequences.
|
||||
Used by the `+=` operator, after trying the numeric addition via
|
||||
the `__iadd__` method.
|
||||
|
||||
* `fn __inplace_repeat__(&self, count: isize) -> PyResult<impl ToPyObject>`
|
||||
|
||||
Concatenates two sequences.
|
||||
Used by the `*=` operator, after trying the numeric multiplication via
|
||||
the `__imul__` method.
|
||||
|
||||
|
||||
### Descriptors
|
||||
|
||||
|
|
|
@ -53,6 +53,12 @@ impl PyMethodKind {
|
|||
"__contains__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__CONTAINS__)),
|
||||
"__concat__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__CONCAT__)),
|
||||
"__repeat__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__REPEAT__)),
|
||||
"__inplace_concat__" => {
|
||||
PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INPLACE_CONCAT__))
|
||||
}
|
||||
"__inplace_repeat__" => {
|
||||
PyMethodKind::Proto(PyMethodProtoKind::Slot(&__INPLACE_REPEAT__))
|
||||
}
|
||||
"__getitem__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__GETITEM__)),
|
||||
"__pos__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__POS__)),
|
||||
"__neg__" => PyMethodKind::Proto(PyMethodProtoKind::Slot(&__NEG__)),
|
||||
|
@ -606,6 +612,10 @@ const __CONTAINS__: SlotDef = SlotDef::new("Py_sq_contains", "objobjproc")
|
|||
.ret_ty(Ty::Int);
|
||||
const __CONCAT__: SlotDef = SlotDef::new("Py_sq_concat", "binaryfunc").arguments(&[Ty::Object]);
|
||||
const __REPEAT__: SlotDef = SlotDef::new("Py_sq_repeat", "ssizeargfunc").arguments(&[Ty::PySsizeT]);
|
||||
const __INPLACE_CONCAT__: SlotDef =
|
||||
SlotDef::new("Py_sq_concat", "binaryfunc").arguments(&[Ty::Object]);
|
||||
const __INPLACE_REPEAT__: SlotDef =
|
||||
SlotDef::new("Py_sq_repeat", "ssizeargfunc").arguments(&[Ty::PySsizeT]);
|
||||
const __GETITEM__: SlotDef = SlotDef::new("Py_mp_subscript", "binaryfunc").arguments(&[Ty::Object]);
|
||||
|
||||
const __POS__: SlotDef = SlotDef::new("Py_nb_positive", "unaryfunc");
|
||||
|
|
|
@ -66,12 +66,17 @@ impl ByteSequence {
|
|||
}
|
||||
}
|
||||
|
||||
fn __concat__(&self, other: PyRef<Self>) -> Self {
|
||||
fn __concat__(&self, other: &Self) -> Self {
|
||||
let mut elements = self.elements.clone();
|
||||
elements.extend_from_slice(&other.elements);
|
||||
Self { elements }
|
||||
}
|
||||
|
||||
fn __inplace_concat__(mut slf: PyRefMut<Self>, other: &Self) -> Py<Self> {
|
||||
slf.elements.extend_from_slice(&other.elements);
|
||||
slf.into()
|
||||
}
|
||||
|
||||
fn __repeat__(&self, count: isize) -> PyResult<Self> {
|
||||
if count >= 0 {
|
||||
let mut elements = Vec::with_capacity(self.elements.len() * count as usize);
|
||||
|
@ -83,6 +88,19 @@ impl ByteSequence {
|
|||
Err(PyValueError::new_err("invalid repeat count"))
|
||||
}
|
||||
}
|
||||
|
||||
fn __inplace_repeat__(mut slf: PyRefMut<Self>, count: isize) -> PyResult<Py<Self>> {
|
||||
if count >= 0 {
|
||||
let mut elements = Vec::with_capacity(slf.elements.len() * count as usize);
|
||||
for _ in 0..count {
|
||||
elements.extend(&slf.elements);
|
||||
}
|
||||
slf.elements = elements;
|
||||
Ok(slf.into())
|
||||
} else {
|
||||
Err(PyValueError::new_err("invalid repeat count"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a dict with `s = ByteSequence([1, 2, 3])`.
|
||||
|
|
Loading…
Reference in New Issue