Refer to PyO3 in a consistent way
This commit is contained in:
parent
310e597693
commit
438bd7f616
|
@ -2,6 +2,6 @@
|
|||
|
||||
## ffi
|
||||
|
||||
pyo3 exposes much of python's C api through the `ffi`.
|
||||
PyO3 exposes much of python's C api through the `ffi`.
|
||||
|
||||
The C api is naturally unsafe and requires you to manage reference counts, errors and specific invariants yourself. Please refer to the [C API Reference Manual](https://docs.python.org/3/c-api/) and [The Rustonomicon](https://doc.rust-lang.org/nightly/nomicon/ffi.html) before using any function from that api.
|
|
@ -2,13 +2,13 @@
|
|||
|
||||
## Python version
|
||||
|
||||
pyo3 uses a build script to determine the python version and set the correct linker arguments. By default it uses the `python3` executable. With the `python2` feature it uses the `python2` executable. You can override the python interpreter by setting `PYTHON_SYS_EXECUTABLE`.
|
||||
PyO3 uses a build script to determine the python version and set the correct linker arguments. By default it uses the `python3` executable. With the `python2` feature it uses the `python2` executable. You can override the python interpreter by setting `PYTHON_SYS_EXECUTABLE`.
|
||||
|
||||
## Linking
|
||||
|
||||
Different linker arguments must be set for libraries/extension modules and binaries, which includes both standalone binaries and tests. (More specifically, binaries must be told where to find libpython and libraries must not link to libpython for [manylinux](https://www.python.org/dev/peps/pep-0513/) compliance).
|
||||
|
||||
Since pyo3's build script can't know whether you're building a binary or a library, you have to activate the `extension-module` feature to get the build options for a library, or it'll default to binary.
|
||||
Since PyO3's build script can't know whether you're building a binary or a library, you have to activate the `extension-module` feature to get the build options for a library, or it'll default to binary.
|
||||
|
||||
If you have e.g. a library crate and a profiling crate alongside, you need to use optional features. E.g. you put the following in the library crate:
|
||||
|
||||
|
@ -40,7 +40,7 @@ There are two ways to distribute your module as python package: The old [setupto
|
|||
|
||||
## Cross Compiling
|
||||
|
||||
Cross compiling Pyo3 modules is relatively straightforward and requires a few pieces of software:
|
||||
Cross compiling PyO3 modules is relatively straightforward and requires a few pieces of software:
|
||||
|
||||
* A toolchain for your target.
|
||||
* The appropriate options in your Cargo `.config` for the platform you're targeting and the toolchain you are using.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Type Conversions
|
||||
|
||||
`PyO3` provides some handy traits to convert between Python types and Rust types.
|
||||
PyO3 provides some handy traits to convert between Python types and Rust types.
|
||||
|
||||
## `.extract()`
|
||||
|
||||
|
@ -104,7 +104,7 @@ fn main() {
|
|||
|
||||
## `IntoPy<T>`
|
||||
|
||||
Many conversions in pyo3 can't use `std::convert::Into` because they need a gil token. That's why the `IntoPy<T>` trait offers an `into_py` methods that works just like `into` except for taking a `Python<'_>` as argument.
|
||||
Many conversions in PyO3 can't use `std::convert::Into` because they need a gil token. That's why the `IntoPy<T>` trait offers an `into_py` methods that works just like `into` except for taking a `Python<'_>` as argument.
|
||||
|
||||
Eventually, traits such as `IntoPyObject` will be replaces by this trait and a `FromPy` trait will be added that will implement `IntoPy`, just like with `From` and `Into`.
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Macros
|
||||
|
||||
Pyo3's attributes, `#[pyclass]`, `#[pymodule]`, etc. are [procedural macros](https://doc.rust-lang.org/unstable-book/language-features/proc-macro.html), which means that rewrite the source of the annotated item. You can view the generated source with the following command, which also expands a few other things:
|
||||
PyO3's attributes, `#[pyclass]`, `#[pymodule]`, etc. are [procedural macros](https://doc.rust-lang.org/unstable-book/language-features/proc-macro.html), which means that rewrite the source of the annotated item. You can view the generated source with the following command, which also expands a few other things:
|
||||
|
||||
```bash
|
||||
cargo rustc --profile=check -- -Z unstable-options --pretty=expanded > expanded.rs; rustfmt expanded.rs
|
||||
|
|
|
@ -122,7 +122,7 @@ The vast majority of operations in this library will return [`PyResult<T>`](http
|
|||
This is an alias for the type `Result<T, PyErr>`.
|
||||
|
||||
A [`PyErr`](https://docs.rs/pyo3/0.2.7/struct.PyErr.html) represents a Python exception.
|
||||
Errors within the `Pyo3` library are also exposed as Python exceptions.
|
||||
Errors within the PyO3 library are also exposed as Python exceptions.
|
||||
|
||||
PyO3 library handles python exception in two stages. During first stage `PyErr` instance get
|
||||
created. At this stage python GIL is not required. During second stage, actual python
|
||||
|
|
|
@ -10,7 +10,7 @@ A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/maste
|
|||
|
||||
## Usage
|
||||
|
||||
Pyo3 supports python 2.7 as well as python 3.5 and up. The minimum required rust version is 1.30.0-nightly 2018-08-18.
|
||||
PyO3 supports python 2.7 as well as python 3.5 and up. The minimum required rust version is 1.30.0-nightly 2018-08-18.
|
||||
|
||||
You can either write a native python module in rust or use python from a rust binary.
|
||||
|
||||
|
@ -24,7 +24,7 @@ sudo apt install python3-dev python-dev
|
|||
|
||||
## Using rust from python
|
||||
|
||||
Pyo3 can be used to generate a native python module.
|
||||
PyO3 can be used to generate a native python module.
|
||||
|
||||
**`Cargo.toml`:**
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use pyo3::prelude::*;
|
|||
#[pymodule]
|
||||
fn rust2py(py: Python, m: &PyModule) -> PyResult<()> {
|
||||
|
||||
// pyo3 aware function. All of our python interface could be declared in a separate module.
|
||||
// PyO3 aware function. All of our python interface could be declared in a separate module.
|
||||
// Note that the `#[pyfn()]` annotation automatically converts the arguments from
|
||||
// Python objects to Rust values; and the Rust return value back into a Python object.
|
||||
#[pyfn(m, "sum_as_string")]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Parallelism
|
||||
|
||||
CPython has an infamous GIL(Global Interpreter Lock) prevents developers
|
||||
getting true parallelism. With `pyo3` you can release GIL when executing
|
||||
getting true parallelism. With PyO3 you can release GIL when executing
|
||||
Rust code to achieve true parallelism.
|
||||
|
||||
The [`Python::allow_threads`](https://docs.rs/pyo3/0.2.7/struct.Python.html#method.allow_threads)
|
||||
|
@ -47,7 +47,7 @@ fn word_count(py: Python, m: &PyModule) -> PyResult<()> {
|
|||
|
||||
## Benchmark
|
||||
|
||||
Let's benchmark the `word-count` example to verify that we did unlock true parallelism with `pyo3`.
|
||||
Let's benchmark the `word-count` example to verify that we did unlock true parallelism with PyO3.
|
||||
We are using `pytest-benchmark` to benchmark three word count functions:
|
||||
|
||||
1. [Pure Python version](https://github.com/PyO3/pyo3/blob/master/examples/word-count/word_count/__init__.py#L9)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# Appendix: pyo3 and rust-cpython
|
||||
# Appendix: PyO3 and rust-cpython
|
||||
|
||||
Pyo3 began as fork of [rust-cpython](https://github.com/dgrunwald/rust-cpython) when rust-cpython wasn't maintained. Over the time pyo3 has become fundamentally different from rust-cpython.
|
||||
PyO3 began as fork of [rust-cpython](https://github.com/dgrunwald/rust-cpython) when rust-cpython wasn't maintained. Over the time pyo3 has become fundamentally different from rust-cpython.
|
||||
|
||||
This chapter is based on the discussion in [PyO3/pyo3#55](https://github.com/PyO3/pyo3/issues/55).
|
||||
|
||||
## Macros
|
||||
|
||||
While rust-cpython has a macro based dsl for declaring modules and classes, pyo3 use proc macros and specialization. Pyo3 also doesn't change your struct and functions so you can still use them as normal rust functions. The disadvantage is that proc macros and specialization currently only work on nightly.
|
||||
While rust-cpython has a macro based dsl for declaring modules and classes, PyO3 use proc macros and specialization. PyO3 also doesn't change your struct and functions so you can still use them as normal rust functions. The disadvantage is that proc macros and specialization currently only work on nightly.
|
||||
|
||||
**rust-cpython**
|
||||
|
||||
|
@ -53,7 +53,7 @@ impl MyClass {
|
|||
|
||||
## Ownership and lifetimes
|
||||
|
||||
All objects are owned by pyo3 library and all apis available with references, while in rust-cpython, you own python objects.
|
||||
All objects are owned by PyO3 library and all apis available with references, while in rust-cpython, you own python objects.
|
||||
|
||||
Here is example of PyList api:
|
||||
|
||||
|
@ -79,10 +79,10 @@ impl PyList {
|
|||
}
|
||||
```
|
||||
|
||||
Because pyo3 allows only references to python object, all reference have the Gil lifetime. So the python object is not required, and it is safe to have functions like `fn py<'p>(&'p self) -> Python<'p> {}`.
|
||||
Because PyO3 allows only references to python object, all reference have the Gil lifetime. So the python object is not required, and it is safe to have functions like `fn py<'p>(&'p self) -> Python<'p> {}`.
|
||||
|
||||
## Error handling
|
||||
|
||||
rust-cpython requires a `Python` parameter for `PyErr`, so error handling ergonomics is pretty bad. It is not possible to use `?` with rust errors.
|
||||
|
||||
`pyo3` on other hand does not require `Python` for `PyErr`, it is only required if you want to raise an exception in python with the `PyErr::restore()` method. Due to the `std::convert::From<Err> for PyErr` trait `?` is supported automatically.
|
||||
PyO3 on other hand does not require `Python` for `PyErr`, it is only required if you want to raise an exception in python with the `PyErr::restore()` method. Due to the `std::convert::From<Err> for PyErr` trait `?` is supported automatically.
|
||||
|
|
Loading…
Reference in a new issue