Documentation enhancement
This commit is contained in:
parent
58590393c5
commit
766a520a10
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue