Apply suggestions from davidhewitt
Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
This commit is contained in:
parent
7c1cc29612
commit
cca560649e
|
@ -2,10 +2,10 @@
|
|||
<!-- Please do not make descriptions too specific, so that we can easily -->
|
||||
<!-- keep this file in sync with the codebase. -->
|
||||
|
||||
# PyO3: Architecture.md
|
||||
# PyO3: Architecture
|
||||
|
||||
This document roughly describes the high-level architecture of PyO3.
|
||||
If you want to become familiar with the codebase, you are in the right place!
|
||||
If you want to become familiar with the codebase you are in the right place!
|
||||
|
||||
## Overview
|
||||
|
||||
|
@ -14,9 +14,9 @@ Thus, PyO3 has low-level bindings of these API as its core.
|
|||
On top of that, we have higher-level bindings to operate Python objects safely.
|
||||
Also, to define Python classes and functions in Rust code, we have `trait PyClass<T>` and a set of
|
||||
protocol traits (e.g., `PyIterProtocol`) for supporting object protocols (i.e., `__dunder__` methods).
|
||||
Since implementing `PyClass` requires lots of boilerplates, we have a proc-macro `#[pyclass]`.
|
||||
Since implementing `PyClass` requires lots of boilerplate, we have a proc-macro `#[pyclass]`.
|
||||
|
||||
To summarize, we have mainly four parts in the PyO3 codebase.
|
||||
To summarize, there are five main parts to the PyO3 codebase.
|
||||
1. Low-level bindings of Python C/API.
|
||||
- [`src/ffi`]
|
||||
2. Bindings to Python objects.
|
||||
|
@ -25,7 +25,7 @@ To summarize, we have mainly four parts in the PyO3 codebase.
|
|||
- [`src/pycell.rs`], [`src/pyclass.rs`]
|
||||
4. Protocol methods like `__getitem__`.
|
||||
- [`src/class`]
|
||||
5. Defining a Python class requires lots of glue code, so we provide proc-macros to simplify the procedure.
|
||||
5. Procedural macros to simplify usage for users.
|
||||
- [`src/derive_utils.rs`]
|
||||
- [`pyo3-macros`], [`pyo3-macros-backend`]
|
||||
|
||||
|
@ -35,15 +35,15 @@ To summarize, we have mainly four parts in the PyO3 codebase.
|
|||
We aim to provide straight-forward Rust wrappers resembling the file structure of
|
||||
[`cpython/Include`](https://github.com/python/cpython/tree/v3.9.2/Include).
|
||||
|
||||
However, we still lack some API and continue to refactor the module to completely resemble
|
||||
the CPython's file structure.
|
||||
However, we still lack some APIs and are continuously updating the the module to match
|
||||
the file contents upstream in CPython.
|
||||
The tracking issue is [#1289](https://github.com/PyO3/pyo3/issues/1289), and contribution is welcome.
|
||||
|
||||
## Bindings to Python Objects
|
||||
## Bindings to Python objects
|
||||
[`src/types`] contains bindings to [built-in types](https://docs.python.org/3/library/stdtypes.html)
|
||||
of Python, such as `dict` and `list`.
|
||||
Due to historical reasons, Python's `object` is called `PyAny` and placed in [`src/types/any.rs`].
|
||||
Currently, `PyAny` is a straight-forward wrapper of `ffi::PyObject`, like:
|
||||
For historical reasons, Python's `object` is called `PyAny` in PyO3 and located in [`src/types/any.rs`].
|
||||
Currently, `PyAny` is a straightforward wrapper of `ffi::PyObject`, defined as:
|
||||
```rust
|
||||
#[repr(transparent)]
|
||||
pub struct PyAny(UnsafeCell<ffi::PyObject>);
|
||||
|
@ -65,7 +65,7 @@ typedef struct {
|
|||
```
|
||||
|
||||
However, we cannot access such a specific data structure with `#[cfg(Py_LIMITED_API)]` set.
|
||||
Thus, all builtin objects are implemented as opaque types by wrapping `PyAny`, like:
|
||||
Thus, all builtin objects are implemented as opaque types by wrapping `PyAny`, e.g.,:
|
||||
```rust
|
||||
#[repr(transparent)]
|
||||
pub struct PyDict(PyAny);
|
||||
|
@ -81,7 +81,7 @@ Since we need lots of boilerplate for implementing common traits for these types
|
|||
[`src/types/mod.rs`].
|
||||
|
||||
## PyClass
|
||||
[`src/pycell.rs`], [`src/pyclass.rs`], and [`src/type_object.rs`] contains types and
|
||||
[`src/pycell.rs`], [`src/pyclass.rs`], and [`src/type_object.rs`] contain types and
|
||||
traits to make `#[pyclass]` work.
|
||||
Also, [`src/pyclass_init.rs`] and [`src/pyclass_slots.rs`] have related functionalities.
|
||||
|
||||
|
@ -106,10 +106,10 @@ pub struct PyCell<T: PyClass> {
|
|||
}
|
||||
```
|
||||
Thus, when copying a Rust struct to a Python object, we first allocate `PyCell` on the Python heap and then
|
||||
copy `T`.
|
||||
move `T` into it.
|
||||
Also, `PyCell` provides [RefCell](https://doc.rust-lang.org/std/cell/struct.RefCell.html)-like methods
|
||||
to ensure Rust's borrow rules.
|
||||
See [the document](https://docs.rs/pyo3/latest/pyo3/pycell/struct.PyCell.html) for more.
|
||||
See [the documentation](https://docs.rs/pyo3/latest/pyo3/pycell/struct.PyCell.html) for more.
|
||||
|
||||
`PyCell<T>` requires that `T` implements `PyClass`.
|
||||
This trait is somewhat complex and derives many traits, but the most important one is `PyTypeObject`
|
||||
|
@ -135,11 +135,11 @@ sets `iter<T>` on the type object of `T`.
|
|||
Also, [`src/class/methods.rs`] has utilities for `#[pyfunction]` and [`src/class/impl_.rs`] has
|
||||
some internal tricks for making `#[pyproto]` flexible.
|
||||
|
||||
## Proc-macros
|
||||
## Procedural macros
|
||||
[`pyo3-macros`] provides six proc-macro APIs: `pymodule`, `pyproto`, `pyfunction`, `pyclass`,
|
||||
`pymethods`, and `#[derive(FromPyObject)]`.
|
||||
[`pyo3-macros-backend`] has the actual implementations of these APIs.
|
||||
[`src/derive_utils.rs`] contains some utilities used in codes generated by these proc-macros,
|
||||
[`src/derive_utils.rs`] contains some utilities used in code generated by these proc-macros,
|
||||
such as parsing function arguments.
|
||||
|
||||
<!-- External Links -->
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
* Contributing Notes: [github](https://github.com/PyO3/pyo3/blob/master/Contributing.md)
|
||||
|
||||
* Brief Architecture Guide: [github](https://github.com/PyO3/pyo3/blob/master/Architecture.md)
|
||||
* Architecture Guide: [github](https://github.com/PyO3/pyo3/blob/master/Architecture.md)
|
||||
|
||||
A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/master/rust_cpython.html).
|
||||
|
||||
|
|
Loading…
Reference in New Issue