more docs
This commit is contained in:
parent
01d688fc98
commit
c6067b90c1
|
@ -4,7 +4,7 @@ Python class generation is powered by unstable [Procedural Macros](https://doc.r
|
|||
[Specialization](https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md) features, so you need to turn on `proc_macro` and `specialization` features:
|
||||
|
||||
```rust
|
||||
#![feature(proc_macro, specialization, associated_consts)]
|
||||
#![feature(proc_macro, specialization)]
|
||||
|
||||
extern crate pyo3;
|
||||
```
|
||||
|
@ -223,11 +223,7 @@ impl MyClass {
|
|||
}
|
||||
```
|
||||
|
||||
## Method arguments
|
||||
|
||||
## Class customizations
|
||||
|
||||
### Callable object
|
||||
## Callable object
|
||||
|
||||
To specify custom `__call__` method for custom class, call method needs to be annotated
|
||||
with `#[call]` attribute. Arguments of the method are speficied same as for instance method.
|
||||
|
@ -243,3 +239,187 @@ impl MyClass {
|
|||
Ok(self.num)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Method arguments
|
||||
|
||||
By default pyo3 library uses function signature to determine which arguments are required.
|
||||
Then it scans incoming `args` parameter and then incoming `kwargs` parameter. If it can not
|
||||
find all required parameters, it raises `TypeError` exception.
|
||||
It is possible to override default bahavior with `#[args(...)]` attribute. `args` attribute
|
||||
accept comma separated list of parameters in form `attr_name="default value"`. Each parameter
|
||||
has to match method parameter by name.
|
||||
|
||||
Each parameter could one of following type:
|
||||
|
||||
* "\*": var arguments separator, each parameter defined after "*" is keyword only paramters.
|
||||
coresponds to python's `def meth(*, arg1.., arg2=..)`
|
||||
* args="\*": "args" is var args, coresponds to python's `def meth(*args)`. Type of `args`
|
||||
parameter has to be `&PyTuple`.
|
||||
* kwargs="\*\*": "kwargs" is kwyword arguments, coresponds to python's `def meth(**kwargs)`.
|
||||
Type of `kwargs` parameter has to be `Option<&PyDict>`.
|
||||
* arg="Value": arguments with default value. coresponds to python's `def meth(arg=Value)`.
|
||||
if `arg` argument is defined after var arguments it is treated as keyword argument.
|
||||
Note that `Value` has to be valid rust code, pyo3 just inserts it into generated
|
||||
code unmodified.
|
||||
|
||||
Example:
|
||||
```rust
|
||||
#[py::methods]
|
||||
impl MyClass {
|
||||
|
||||
#[args(arg1=true, args="*", arg2=10, kwargs="**")]
|
||||
fn method(&self, arg1: bool, args: &PyTuple, arg2: i32, kwargs: Option<&PyTuple>) -> PyResult<i32> {
|
||||
Ok(1)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Class customizations
|
||||
|
||||
Python object model defines several protocols for different object behavior,
|
||||
like sequence, mapping or number protocols. pyo3 library defines separate trait for each
|
||||
of them. To provide specific python object behavior you need to implement specific trait
|
||||
for your struct. Important note, each protocol implementation block has to be annotated
|
||||
with `#[py::proto]` attribute.
|
||||
|
||||
### Basic object customization
|
||||
|
||||
[`PyObjectProtocol`](https://pyo3.github.io/pyo3/pyo3/class/basic/trait.PyObjectProtocol.html) trait provide several basic customizations.
|
||||
|
||||
#### Attribute access
|
||||
|
||||
To customize object attribute access define following methods:
|
||||
|
||||
* `fn __getattr__(&self, name: FromPyObject) -> PyResult<impl IntoPyObject>`
|
||||
* `fn __setattr__(&mut self, name: FromPyObject, value: FromPyObject) -> PyResult<()>`
|
||||
* `fn __delattr__(&mut self, name: FromPyObject) -> PyResult<()>`
|
||||
|
||||
Each methods coresponds to python's `self.attr`, `self.attr = value` and `del self.attr` code.
|
||||
|
||||
#### String Conversions
|
||||
|
||||
* `fn __repr__(&self) -> PyResult<impl ToPyObject<ObjectType=PyString>>`
|
||||
* `fn __str__(&self) -> PyResult<impl ToPyObject<ObjectType=PyString>>`
|
||||
|
||||
Possible return types for `__str__` and `__repr__` are `PyResult<String>` or `PyResult<PyString>`.
|
||||
In Python 2.7, Unicode strings returned by `__str__` and `__repr__` will be converted to byte strings
|
||||
by the Python runtime, which results in an exception if the string contains non-ASCII characters.
|
||||
|
||||
* `fn __bytes__(&self) -> PyResult<PyBytes>`
|
||||
|
||||
On Python 3.x, provides the conversion to `bytes`.
|
||||
On Python 2.7, `__bytes__` is allowed but has no effect.
|
||||
|
||||
* `fn __unicode__(&self) -> PyResult<PyUnicode>`
|
||||
|
||||
On Python 2.7, provides the conversion to `unicode`.
|
||||
On Python 3.x, `__unicode__` is allowed but has no effect.
|
||||
|
||||
* `fn __format__(&self, format_spec: &str) -> PyResult<impl ToPyObject<ObjectType=PyString>>`
|
||||
|
||||
Special method that is used by the `format()` builtin and the `str.format()` method.
|
||||
Possible return types are `PyResult<String>` or `PyResult<PyString>`.
|
||||
|
||||
#### Comparison operators
|
||||
|
||||
* `fn __richcmp__(&self, other: impl FromPyObject, op: CompareOp) -> PyResult<impl ToPyObject>`
|
||||
|
||||
Overloads Python comparison operations (`==`, `!=`, `<`, `<=`, `>`, and `>=`).
|
||||
The `op` argument indicates the comparison operation being performed.
|
||||
The return type will normally be `PyResult<bool>`, but any Python object can be returned.
|
||||
If `other` is not of the type specified in the signature, the generated code will
|
||||
automatically `return NotImplemented`.
|
||||
|
||||
* `fn __hash__(&self) -> PyResult<impl PrimInt>`
|
||||
|
||||
Objects that compare equal must have the same hash value.
|
||||
The return type must be `PyResult<T>` where `T` is one of Rust's primitive integer types.
|
||||
|
||||
#### Other methods
|
||||
|
||||
* `fn __bool__(&self) -> PyResult<bool>`
|
||||
|
||||
Determines the "truthyness" of the object.
|
||||
This method works for both python 3 and python 2,
|
||||
even on Python 2.7 where the Python spelling was `__nonzero__`.
|
||||
|
||||
### Garbage Collector Integration
|
||||
|
||||
If your type owns references to other python objects, you will need to
|
||||
integrate with Python's garbage collector so that the GC is aware of
|
||||
those references.
|
||||
To do this, implement [`PyGCProtocol`](https://pyo3.github.io/pyo3/pyo3/class/gc/trait.PyGCProtocol.html) trait for your struct.
|
||||
It includes two methods `__traverse__` and `__clear__`.
|
||||
These correspond to the slots `tp_traverse` and `tp_clear` in the Python C API.
|
||||
`__traverse__` must call `visit.call()` for each reference to another python object.
|
||||
`__clear__` must clear out any mutable references to other python objects
|
||||
(thus breaking reference cycles). Immutable references do not have to be cleared,
|
||||
as every cycle must contain at least one mutable reference.
|
||||
Example:
|
||||
```rust
|
||||
#![feature(proc_macro, specialization)]
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::{py, PyObject, PyGCProtocol, PyVisit, PyTraverseError};
|
||||
|
||||
#[py::class]
|
||||
struct ClassWithGCSupport {
|
||||
obj: Option<PyObject>,
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
impl PyGCProtocol for ClassWithGCSupport {
|
||||
fn __traverse__(&self, visit: PyVisit) -> Result<(), PyTraverseError> {
|
||||
if let Some(ref obj) = self.obj {
|
||||
visit.call(obj)?
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn __clear__(&mut self) {
|
||||
if let Some(obj) = self.obj.take() {
|
||||
// Release reference, this decrements ref counter.
|
||||
self.py().release(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Special protocol trait implementation has to be annotated with `#[py::proto]` attribute.
|
||||
|
||||
### Iterator Types
|
||||
|
||||
Iterators can be defined using the
|
||||
[`PyIterProtocol`](https://pyo3.github.io/pyo3/pyo3/class/iter/trait.PyIterProtocol.html) trait.
|
||||
It includes two methods `__iter__` and `__next__`:
|
||||
* `fn __iter__(&mut self) -> PyResult<impl IntoPyObject>`
|
||||
* `fn __next__(&mut self) -> PyResult<Option<impl IntoPyObject>>`
|
||||
|
||||
Returning `Ok(None)` from `__next__` indicates that that there are no further items.
|
||||
|
||||
Example:
|
||||
```rust
|
||||
#![feature(proc_macro, specialization)]
|
||||
extern crate pyo3;
|
||||
|
||||
use pyo3::{py, PyObject, PyResult, PyIterProtocol};
|
||||
|
||||
#[py::class]
|
||||
struct MyIterator {
|
||||
iter: Box<Iterator<Item=PyObject> + Send>
|
||||
}
|
||||
|
||||
#[py::proto]
|
||||
impl PyIterProtocol {
|
||||
|
||||
fn __iter__(&mut self) -> PyResult<PyObject> {
|
||||
Ok(self.into())
|
||||
}
|
||||
fn __next__(&mut self) -> PyResult<Option<PyObject>> {
|
||||
Ok(self.iter.next())
|
||||
}
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
||||
|
|
|
@ -15,6 +15,9 @@ use callback::UnitCallbackConverter;
|
|||
|
||||
|
||||
/// Buffer protocol interface
|
||||
///
|
||||
/// more information on buffer protocol can be found
|
||||
/// https://docs.python.org/3/c-api/buffer.html
|
||||
#[allow(unused_variables)]
|
||||
pub trait PyBufferProtocol<'p> : PyTypeInfo + PyDowncastFrom
|
||||
{
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
//! Python Iterator Interface
|
||||
//! Python Iterator Interface.
|
||||
//! Trait and support implementation for implementing iterators
|
||||
//!
|
||||
//! more information
|
||||
//! https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_iter
|
||||
|
||||
use std::ptr;
|
||||
|
||||
|
@ -16,7 +12,10 @@ use conversion::IntoPyObject;
|
|||
use callback::{CallbackConverter, PyObjectCallbackConverter};
|
||||
|
||||
|
||||
/// Iterator protocol
|
||||
/// Python Iterator Interface.
|
||||
///
|
||||
/// more information
|
||||
/// https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_iter
|
||||
#[allow(unused_variables)]
|
||||
pub trait PyIterProtocol<'p> : PyTypeInfo + PyDowncastFrom {
|
||||
fn __iter__(&'p mut self)
|
||||
|
|
Loading…
Reference in New Issue