Documentation enhancement

This commit is contained in:
kngwyu 2019-12-28 16:40:45 +09:00
parent 58590393c5
commit 766a520a10
2 changed files with 31 additions and 26 deletions

View File

@ -18,12 +18,13 @@ struct MyClass {
The above example generates implementations for `PyTypeInfo`, `PyTypeObject`
and `PyClass` for `MyClass`.
Specifically, the following implementation is generated.
Specifically, the following implementation is generated:
```rust
use pyo3::prelude::*;
use pyo3::{PyClassShell, PyTypeInfo};
/// Class for demonstration
struct MyClass {
num: i32,
debug: bool,
@ -38,7 +39,7 @@ impl PyTypeInfo for MyClass {
const NAME: &'static str = "MyClass";
const MODULE: Option<&'static str> = None;
const DESCRIPTION: &'static str = "This is a demo class";
const DESCRIPTION: &'static str = "Class for demonstration";
const FLAGS: usize = 0;
#[inline]
@ -89,14 +90,14 @@ pyo3::inventory::collect!(MyClassGeneratedPyo3Inventory);
## Get Python objects from `pyclass`
You sometimes need to convert your `pyclass` into a Python object in Rust code (e.g., for testing it).
For getting *GIL-bounded*(i.e., with `'py` lifetime) references of `pyclass`,
For getting *GIL-bounded* (i.e., with `'py` lifetime) references of `pyclass`,
you can use `PyClassShell<T>`.
Or you can use `Py<T>` directly, for *not-GIL-bounded* references.
### `PyClassShell`
`PyClassShell` represents the actual layout of `pyclass` on the Python heap.
If you want to instantiate `pyclass` in Python and get the the reference,
If you want to instantiate `pyclass` in Python and get the reference,
you can use `PyClassShell::new_ref` or `PyClassShell::new_mut`.
```rust
@ -182,21 +183,24 @@ impl MyClass {
}
```
Rules for the `new` method:
If no method marked with `#[new]` is declared, object instances can only be
created from Rust, but not from Python.
* If no method marked with `#[new]` is declared, object instances can only be created
from Rust, but not from Python.
* All parameters are from Python.
* It can return one of these types:
- `T`
- `PyResult<T>`
- `PyClassInitializer<T>`
- `PyResult<PyClassInitializer<T>>`
* If you pyclass declared with `#[pyclass(extends=BaseType)]` and `BaseType`
is also `#[pyclass]`, you have to return `PyClassInitializer<T>` or
`PyResult<PyClassInitializer<T>>` with the baseclass initialized. See the
below Inheritance section for detail.
* For details on the parameter list, see the `Method arguments` section below.
For arguments, see the `Method arguments` section below.
### Return type
If your pyclass is declared with baseclass(i.e., you use `#[pyclass(extends=...)])`),
you must return a `PyClassInitializer` with the base class initialized.
For constructors that may fail, you should wrap the return type in a PyResult as well.
Consult the table below to determine which type your constructor should return:
| | **Cannot fail** | **May fail** |
|--------------------|-------------------------|-----------------------------------|
| **No inheritance** | `T` | `PyResult<T>` |
| **Inheritance** | `PyClassInitializer<T>` | `PyResult<PyClassInitializer<T>>` |
## Inheritance

View File

@ -26,7 +26,7 @@ pub(crate) unsafe fn default_alloc<T: PyTypeInfo>() -> *mut ffi::PyObject {
alloc(tp_ptr, 0)
}
/// A trait that enables custome alloc/dealloc implementations for pyclasses.
/// A trait that enables custom alloc/dealloc implementations for pyclasses.
pub trait PyClassAlloc: PyTypeInfo + Sized {
unsafe fn alloc(_py: Python) -> *mut Self::ConcreteLayout {
default_alloc::<Self>() as _
@ -65,7 +65,7 @@ pub unsafe fn tp_free_fallback(obj: *mut ffi::PyObject) {
/// If `PyClass` is implemented for `T`, then we can use `T` in the Python world,
/// via `PyClassShell`.
///
/// `#[pyclass]` attribute automatically implement this trait for your Rust struct,
/// The `#[pyclass]` attribute automatically implements this trait for your Rust struct,
/// so you don't have to use this trait directly.
pub trait PyClass:
PyTypeInfo<ConcreteLayout = PyClassShell<Self>> + Sized + PyClassAlloc + PyMethodsProtocol
@ -96,9 +96,10 @@ where
}
}
/// `PyClassShell` represents the concrete layout of `PyClass` in the Python heap.
/// `PyClassShell` represents the concrete layout of `T: PyClass` when it is converted
/// to a Python class.
///
/// You can use it for testing your `#[pyclass]` correctly works.
/// You can use it to test your `#[pyclass]` correctly works.
///
/// ```
/// # use pyo3::prelude::*;
@ -268,7 +269,7 @@ where
}
}
/// A speciall initializer for `PyClassShell<T>`, which enables `super().__init__`
/// A special initializer for `PyClassShell<T>`, which enables `super().__init__`
/// in Rust code.
///
/// You have to use it only when your `#[pyclass]` extends another `#[pyclass]`.
@ -387,9 +388,9 @@ impl<T: PyTypeInfo> PyClassInitializer<T> {
}
}
/// Represets that we can convert the type to `PyClassInitializer`.
/// Represents that we can convert the type to `PyClassInitializer`.
///
/// It is mainly used in our proc-macro code.
/// This is mainly used in our proc-macro code.
pub trait IntoInitializer<T: PyClass> {
fn into_initializer(self) -> PyResult<PyClassInitializer<T>>;
}
@ -418,7 +419,7 @@ impl<T: PyClass> IntoInitializer<T> for PyResult<PyClassInitializer<T>> {
}
}
/// Register new type in python object system.
/// Register new type in the python object system.
#[cfg(not(Py_LIMITED_API))]
pub fn initialize_type<T>(py: Python, module_name: Option<&str>) -> PyResult<*mut ffi::PyTypeObject>
where