diff --git a/guide/src/class/protocols.md b/guide/src/class/protocols.md index 4facb49b9eb..251447be1a6 100644 --- a/guide/src/class/protocols.md +++ b/guide/src/class/protocols.md @@ -21,22 +21,40 @@ The magic methods handled by PyO3 are very similar to the standard Python ones o - Magic methods for the sequence protocol When PyO3 handles a magic method, a couple of changes apply compared to other `#[pymethods]`: - - The `#[pyo3(text_signature = "...")]` attribute is not allowed - - The types of the arguments are fixed according to the magic method + - The `#[pyo3(text_signature = "...")]` attribute is not allowed + - The signature is restricted to match the magic method + +The following sections list of all magic methods PyO3 currently handles. The +given signatures should be interpreted as follows: + - All methods take a receiver as first argument, shown as ``. It can be + `&self`, `&mut self` or a `PyCell` reference like `self_: PyRef` and + `self_: PyRefMut`, as described [here](../class.md#inheritance). + - An optional `Python<'py>` argument is always allowed as the first argument. + - Return values can be optionally wrapped in `PyResult`. + - `object` means that any type is allowed that can be extracted from a Python + object (if argument) or converted to a Python object (if return value). + - Other types must match what's given, e.g. `pyo3::basic::CompareOp` for + `__richcmp__`'s second argument. + - For the comparison and arithmetic methods, extraction errors are not + propagated as exceptions, but lead to a return of `NotImplemented`. + - For some magic methods, the return values are not restricted by PyO3, but + checked by the Python interpreter. For example, `__str__` needs to return a + string object. This is indicated by `object (Python type)`. -The following sections list of all magic methods PyO3 currently handles: #### Basic object customization - - `__str__` - - `__repr__` - - `__hash__` - - `__richcmp__` - - `__getattr__` - - `__setattr__` - - `__delattr__` - - `__bool__` - - `__call__` + - `__str__() -> object (str)` + - `__repr__() -> object (str)` + - `__hash__() -> isize` + - `__richcmp__(, object, pyo3::basic::CompareOp) -> object` + - `__getattr__(, object) -> object` + - `__setattr__(, object, object) -> ()` + - `__delattr__(, object) -> ()` + - `__bool__() -> bool` + + - `__call__(, ...) -> object` - here, any argument list can be defined + as for normal `pymethods` ##### Example: Callable objects @@ -105,14 +123,14 @@ hello #### Iterable objects - - `__iter__` - - `__next__` + - `__iter__() -> object` + - `__next__() -> Option or IterNextOutput` ([see details](#returning-a-value-from-iteration)) #### Awaitable objects - - `__await__` - - `__aiter__` - - `__anext__` + - `__await__() -> object` + - `__aiter__() -> object` + - `__anext__() -> Option or IterANextOutput` #### Sequence types @@ -120,68 +138,68 @@ TODO; see [#1884](https://github.com/PyO3/pyo3/issues/1884) #### Mapping types - - `__len__` - - `__contains__` - - `__getitem__` - - `__setitem__` - - `__delitem__` + - `__len__() -> usize` + - `__contains__(, object) -> bool` + - `__getitem__(, object) -> object` + - `__setitem__(, object, object) -> ()` + - `__delitem__(, object) -> ()` #### Descriptors - - `__get__` - - `__set__` - - `__delete__` + - `__get__(, object, object) -> object` + - `__set__(, object, object) -> ()` + - `__delete__(, object) -> ()` #### Numeric types - - `__pos__` - - `__neg__` - - `__abs__` - - `__invert__` - - `__index__` - - `__int__` - - `__float__` - - `__iadd__` - - `__isub__` - - `__imul__` - - `__imatmul__` - - `__itruediv__` - - `__ifloordiv__` - - `__imod__` - - `__ipow__` - - `__ilshift__` - - `__irshift__` - - `__iand__` - - `__ixor__` - - `__ior__` - - `__add__` - - `__radd__` - - `__sub__` - - `__rsub__` - - `__mul__` - - `__rmul__` - - `__matmul__` - - `__rmatmul__` - - `__floordiv__` - - `__rfloordiv__` - - `__truediv__` - - `__rtruediv__` - - `__divmod__` - - `__rdivmod__` - - `__mod__` - - `__rmod__` - - `__lshift__` - - `__rlshift__` - - `__rshift__` - - `__rrshift__` - - `__and__` - - `__rand__` - - `__xor__` - - `__rxor__` - - `__or__` - - `__ror__` - - `__pow__` - - `__rpow__` + - `__pos__() -> object` + - `__neg__() -> object` + - `__abs__() -> object` + - `__invert__() -> object` + - `__index__() -> object (int)` + - `__int__() -> object (int)` + - `__float__() -> object (float)` + - `__iadd__(, object) -> ()` + - `__isub__(, object) -> ()` + - `__imul__(, object) -> ()` + - `__imatmul__(, object) -> ()` + - `__itruediv__(, object) -> ()` + - `__ifloordiv__(, object) -> ()` + - `__imod__(, object) -> ()` + - `__ipow__(, object, object) -> ()` + - `__ilshift__(, object) -> ()` + - `__irshift__(, object) -> ()` + - `__iand__(, object) -> ()` + - `__ixor__(, object) -> ()` + - `__ior__(, object) -> ()` + - `__add__(, object) -> object` + - `__radd__(, object) -> object` + - `__sub__(, object) -> object` + - `__rsub__(, object) -> object` + - `__mul__(, object) -> object` + - `__rmul__(, object) -> object` + - `__matmul__(, object) -> object` + - `__rmatmul__(, object) -> object` + - `__floordiv__(, object) -> object` + - `__rfloordiv__(, object) -> object` + - `__truediv__(, object) -> object` + - `__rtruediv__(, object) -> object` + - `__divmod__(, object) -> object` + - `__rdivmod__(, object) -> object` + - `__mod__(, object) -> object` + - `__rmod__(, object) -> object` + - `__lshift__(, object) -> object` + - `__rlshift__(, object) -> object` + - `__rshift__(, object) -> object` + - `__rrshift__(, object) -> object` + - `__and__(, object) -> object` + - `__rand__(, object) -> object` + - `__xor__(, object) -> object` + - `__rxor__(, object) -> object` + - `__or__(, object) -> object` + - `__ror__(, object) -> object` + - `__pow__(, object, object) -> object` + - `__rpow__(, object, object) -> object` #### Buffer objects