Merge pull request #1964 from PyO3/pymethods-args

guide: add hints for the signature of pymethods protos
This commit is contained in:
David Hewitt 2021-11-03 08:15:27 +00:00 committed by GitHub
commit 64df791741
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 91 additions and 73 deletions

View File

@ -22,21 +22,39 @@ The magic methods handled by PyO3 are very similar to the standard Python ones o
When PyO3 handles a magic method, a couple of changes apply compared to other `#[pymethods]`: When PyO3 handles a magic method, a couple of changes apply compared to other `#[pymethods]`:
- The `#[pyo3(text_signature = "...")]` attribute is not allowed - The `#[pyo3(text_signature = "...")]` attribute is not allowed
- The types of the arguments are fixed according to the magic method - 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 `<self>`. It can be
`&self`, `&mut self` or a `PyCell` reference like `self_: PyRef<Self>` and
`self_: PyRefMut<Self>`, 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 #### Basic object customization
- `__str__` - `__str__(<self>) -> object (str)`
- `__repr__` - `__repr__(<self>) -> object (str)`
- `__hash__` - `__hash__(<self>) -> isize`
- `__richcmp__` - `__richcmp__(<self>, object, pyo3::basic::CompareOp) -> object`
- `__getattr__` - `__getattr__(<self>, object) -> object`
- `__setattr__` - `__setattr__(<self>, object, object) -> ()`
- `__delattr__` - `__delattr__(<self>, object) -> ()`
- `__bool__` - `__bool__(<self>) -> bool`
- `__call__`
- `__call__(<self>, ...) -> object` - here, any argument list can be defined
as for normal `pymethods`
##### Example: Callable objects ##### Example: Callable objects
@ -105,14 +123,14 @@ hello
#### Iterable objects #### Iterable objects
- `__iter__` - `__iter__(<self>) -> object`
- `__next__` - `__next__(<self>) -> Option<object> or IterNextOutput` ([see details](#returning-a-value-from-iteration))
#### Awaitable objects #### Awaitable objects
- `__await__` - `__await__(<self>) -> object`
- `__aiter__` - `__aiter__(<self>) -> object`
- `__anext__` - `__anext__(<self>) -> Option<object> or IterANextOutput`
#### Sequence types #### Sequence types
@ -120,68 +138,68 @@ TODO; see [#1884](https://github.com/PyO3/pyo3/issues/1884)
#### Mapping types #### Mapping types
- `__len__` - `__len__(<self>) -> usize`
- `__contains__` - `__contains__(<self>, object) -> bool`
- `__getitem__` - `__getitem__(<self>, object) -> object`
- `__setitem__` - `__setitem__(<self>, object, object) -> ()`
- `__delitem__` - `__delitem__(<self>, object) -> ()`
#### Descriptors #### Descriptors
- `__get__` - `__get__(<self>, object, object) -> object`
- `__set__` - `__set__(<self>, object, object) -> ()`
- `__delete__` - `__delete__(<self>, object) -> ()`
#### Numeric types #### Numeric types
- `__pos__` - `__pos__(<self>) -> object`
- `__neg__` - `__neg__(<self>) -> object`
- `__abs__` - `__abs__(<self>) -> object`
- `__invert__` - `__invert__(<self>) -> object`
- `__index__` - `__index__(<self>) -> object (int)`
- `__int__` - `__int__(<self>) -> object (int)`
- `__float__` - `__float__(<self>) -> object (float)`
- `__iadd__` - `__iadd__(<self>, object) -> ()`
- `__isub__` - `__isub__(<self>, object) -> ()`
- `__imul__` - `__imul__(<self>, object) -> ()`
- `__imatmul__` - `__imatmul__(<self>, object) -> ()`
- `__itruediv__` - `__itruediv__(<self>, object) -> ()`
- `__ifloordiv__` - `__ifloordiv__(<self>, object) -> ()`
- `__imod__` - `__imod__(<self>, object) -> ()`
- `__ipow__` - `__ipow__(<self>, object, object) -> ()`
- `__ilshift__` - `__ilshift__(<self>, object) -> ()`
- `__irshift__` - `__irshift__(<self>, object) -> ()`
- `__iand__` - `__iand__(<self>, object) -> ()`
- `__ixor__` - `__ixor__(<self>, object) -> ()`
- `__ior__` - `__ior__(<self>, object) -> ()`
- `__add__` - `__add__(<self>, object) -> object`
- `__radd__` - `__radd__(<self>, object) -> object`
- `__sub__` - `__sub__(<self>, object) -> object`
- `__rsub__` - `__rsub__(<self>, object) -> object`
- `__mul__` - `__mul__(<self>, object) -> object`
- `__rmul__` - `__rmul__(<self>, object) -> object`
- `__matmul__` - `__matmul__(<self>, object) -> object`
- `__rmatmul__` - `__rmatmul__(<self>, object) -> object`
- `__floordiv__` - `__floordiv__(<self>, object) -> object`
- `__rfloordiv__` - `__rfloordiv__(<self>, object) -> object`
- `__truediv__` - `__truediv__(<self>, object) -> object`
- `__rtruediv__` - `__rtruediv__(<self>, object) -> object`
- `__divmod__` - `__divmod__(<self>, object) -> object`
- `__rdivmod__` - `__rdivmod__(<self>, object) -> object`
- `__mod__` - `__mod__(<self>, object) -> object`
- `__rmod__` - `__rmod__(<self>, object) -> object`
- `__lshift__` - `__lshift__(<self>, object) -> object`
- `__rlshift__` - `__rlshift__(<self>, object) -> object`
- `__rshift__` - `__rshift__(<self>, object) -> object`
- `__rrshift__` - `__rrshift__(<self>, object) -> object`
- `__and__` - `__and__(<self>, object) -> object`
- `__rand__` - `__rand__(<self>, object) -> object`
- `__xor__` - `__xor__(<self>, object) -> object`
- `__rxor__` - `__rxor__(<self>, object) -> object`
- `__or__` - `__or__(<self>, object) -> object`
- `__ror__` - `__ror__(<self>, object) -> object`
- `__pow__` - `__pow__(<self>, object, object) -> object`
- `__rpow__` - `__rpow__(<self>, object, object) -> object`
#### Buffer objects #### Buffer objects