Merge pull request #962 from Alexander-N/guide

Update README and remove Getting Started section from user guide
This commit is contained in:
Yuji Kanagawa 2020-06-07 22:13:32 +09:00 committed by GitHub
commit 798d72e6a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 11 additions and 159 deletions

View File

@ -23,7 +23,7 @@ If you have never used nightly Rust, the official guide has
about installing it. about installing it.
PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0. PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0.
Please refer to the guide for installation instruction against PyPy. Please refer to the [pypy section in the guide](https://pyo3.rs/master/pypy.html).
You can either write a native Python module in Rust, or use Python from a Rust binary. You can either write a native Python module in Rust, or use Python from a Rust binary.
@ -60,13 +60,13 @@ features = ["extension-module"]
use pyo3::prelude::*; use pyo3::prelude::*;
use pyo3::wrap_pyfunction; use pyo3::wrap_pyfunction;
/// Formats the sum of two numbers as string.
#[pyfunction] #[pyfunction]
/// Formats the sum of two numbers as string
fn sum_as_string(a: usize, b: usize) -> PyResult<String> { fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string()) Ok((a + b).to_string())
} }
/// This module is a python module implemented in Rust. /// A Python module implemented in Rust.
#[pymodule] #[pymodule]
fn string_sum(py: Python, m: &PyModule) -> PyResult<()> { fn string_sum(py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(sum_as_string))?; m.add_wrapped(wrap_pyfunction!(sum_as_string))?;
@ -85,13 +85,14 @@ rustflags = [
] ]
``` ```
For developing, you can copy and rename the shared library from the target folder: On MacOS, rename `libstring_sum.dylib` to `string_sum.so`, on Windows `libstring_sum.dll` to `string_sum.pyd` and on Linux `libstring_sum.so` to `string_sum.so`. Then open a Python shell in the same folder and you'll be able to `import string_sum`. While developing, you can symlink (or copy) and rename the shared library from the target folder: On MacOS, rename `libstring_sum.dylib` to `string_sum.so`, on Windows `libstring_sum.dll` to `string_sum.pyd`, and on Linux `libstring_sum.so` to `string_sum.so`. Then open a Python shell in the same folder and you'll be able to `import string_sum`.
To build, test and publish your crate as a Python module, you can use [maturin](https://github.com/PyO3/maturin) or [setuptools-rust](https://github.com/PyO3/setuptools-rust). You can find an example for setuptools-rust in [examples/word-count](examples/word-count), while maturin should work on your crate without any configuration. To build, test and publish your crate as a Python module, you can use [maturin](https://github.com/PyO3/maturin) or [setuptools-rust](https://github.com/PyO3/setuptools-rust). You can find an example for setuptools-rust in [examples/word-count](https://github.com/PyO3/pyo3/tree/master/examples/word-count), while maturin should work on your crate without any configuration.
## Using Python from Rust ## Using Python from Rust
Add `pyo3` to your `Cargo.toml` like this: If you want your Rust application to create a Python interpreter internally and
use it to run Python code, add `pyo3` to your `Cargo.toml` like this:
```toml ```toml
[dependencies] [dependencies]
@ -108,8 +109,8 @@ fn main() -> Result<(), ()> {
let gil = Python::acquire_gil(); let gil = Python::acquire_gil();
let py = gil.python(); let py = gil.python();
main_(py).map_err(|e| { main_(py).map_err(|e| {
// We can't display python error type via ::std::fmt::Display, // We can't display Python exceptions via std::fmt::Display,
// so print error here manually. // so print the error here manually.
e.print_and_set_sys_last_vars(py); e.print_and_set_sys_last_vars(py);
}) })
} }

View File

@ -1,6 +1,5 @@
# Summary # Summary
- [Getting Started](get_started.md)
- [Python Modules](module.md) - [Python Modules](module.md)
- [Python Functions](function.md) - [Python Functions](function.md)
- [Python Classes](class.md) - [Python Classes](class.md)

View File

@ -1,147 +0,0 @@
# PyO3
[Rust](http://www.rust-lang.org/) bindings for [Python](https://www.python.org/). This includes running and interacting with Python code from a Rust binary, as well as writing native Python modules.
* User Guide: [stable](https://pyo3.rs) | [master](https://pyo3.rs/master)
* API Documentation: [master](https://pyo3.rs/master/doc)
A comparison with rust-cpython can be found [in the guide](https://pyo3.rs/master/rust_cpython.html).
## Usage
PyO3 supports Python 3.5 and up. The minimum required Rust version is 1.42.0-nightly 2019-01-21.
If you have never used nightly Rust, the official guide has
[a great section](https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#rustup-and-the-role-of-rust-nightly)
about installing it.
PyPy is also supported (via cpyext) for Python 3.5 only, targeted PyPy version is 7.0.0.
Please refer to the [pypy section](https://pyo3.rs/master/pypy.html).
You can either write a native Python module in Rust, or use Python from a Rust binary.
However, on some OSs, you need some additional packages. E.g. if you are on *Ubuntu 18.04*, please run
```bash
sudo apt install python3-dev python-dev
```
## Using Rust from Python
PyO3 can be used to generate a native Python module.
**`Cargo.toml`**
```toml
[package]
name = "string-sum"
version = "0.1.0"
edition = "2018"
[lib]
name = "string_sum"
crate-type = ["cdylib"]
[dependencies.pyo3]
version = "0.10.1"
features = ["extension-module"]
```
**`src/lib.rs`**
```rust
use pyo3::prelude::*;
use pyo3::wrap_pyfunction;
#[pyfunction]
/// Formats the sum of two numbers as string.
fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
Ok((a + b).to_string())
}
#[pymodule]
/// A Python module implemented in Rust.
fn string_sum(py: Python, m: &PyModule) -> PyResult<()> {
m.add_wrapped(wrap_pyfunction!(sum_as_string))?;
Ok(())
}
```
On Windows and Linux, you can build normally with `cargo build --release`. On macOS, you need to set additional linker arguments. One option is to compile with `cargo rustc --release -- -C link-arg=-undefined -C link-arg=dynamic_lookup`, the other is to create a `.cargo/config` with the following content:
```toml
[target.x86_64-apple-darwin]
rustflags = [
"-C", "link-arg=-undefined",
"-C", "link-arg=dynamic_lookup",
]
```
While developing, you can symlink (or copy) and rename the shared library from the target folder: On MacOS, rename `libstring_sum.dylib` to `string_sum.so`, on Windows `libstring_sum.dll` to `string_sum.pyd`, and on Linux `libstring_sum.so` to `string_sum.so`. Then open a Python shell in the same folder and you'll be able to `import string_sum`.
To build, test and publish your crate as a Python module, you can use [maturin](https://github.com/PyO3/maturin) or [setuptools-rust](https://github.com/PyO3/setuptools-rust). You can find an example for setuptools-rust in [examples/word-count](https://github.com/PyO3/pyo3/tree/master/examples/word-count), while maturin should work on your crate without any configuration.
## Using Python from Rust
If you want your Rust application to create a Python interpreter internally and
use it to run Python code, add `pyo3` to your `Cargo.toml` like this:
```toml
[dependencies]
pyo3 = "0.10.1"
```
Example program displaying the value of `sys.version` and the current user name:
```rust
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
fn main() -> Result<(), ()> {
let gil = Python::acquire_gil();
let py = gil.python();
main_(py).map_err(|e| {
// We can't display Python exceptions via std::fmt::Display,
// so print the error here manually.
e.print_and_set_sys_last_vars(py);
})
}
fn main_(py: Python) -> PyResult<()> {
let sys = py.import("sys")?;
let version: String = sys.get("version")?.extract()?;
let locals = [("os", py.import("os")?)].into_py_dict(py);
let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
let user: String = py.eval(code, None, Some(&locals))?.extract()?;
println!("Hello {}, I'm Python {}", user, version);
Ok(())
}
```
Our guide has [a section](https://pyo3.rs/master/python_from_rust.html) with lots of examples
about this topic.
## Tools and libraries
* [maturin](https://github.com/PyO3/maturin) _Zero configuration build tool for Rust-made Python extensions_.
* [setuptools-rust](https://github.com/PyO3/setuptools-rust) _Setuptools plugin for Rust support_.
* [pyo3-built](https://github.com/PyO3/pyo3-built) _Simple macro to expose metadata obtained with the [`built`](https://crates.io/crates/built) crate as a [`PyDict`](https://pyo3.github.io/pyo3/pyo3/struct.PyDict.html)_
* [rust-numpy](https://github.com/PyO3/rust-numpy) _Rust binding of NumPy C-API_
* [dict-derive](https://github.com/gperinazzo/dict-derive) _Derive FromPyObject to automatically transform Python dicts into Rust structs_
## Examples
* [hyperjson](https://github.com/mre/hyperjson) _A hyper-fast Python module for reading/writing JSON data using Rust's serde-json_
* [html-py-ever](https://github.com/PyO3/setuptools-rust/tree/master/html-py-ever) _Using [html5ever](https://github.com/servo/html5ever) through [kuchiki](https://github.com/kuchiki-rs/kuchiki) to speed up html parsing and css-selecting._
* [point-process](https://github.com/ManifoldFR/point-process-rust/tree/master/pylib) _High level API for pointprocesses as a Python library_
* [autopy](https://github.com/autopilot-rs/autopy) _A simple, cross-platform GUI automation library for Python and Rust._
* Contains an example of building wheels on TravisCI and appveyor using [cibuildwheel](https://github.com/joerick/cibuildwheel)
* [orjson](https://github.com/ijl/orjson) _Fast Python JSON library_
* [inline-python](https://github.com/dronesforwork/inline-python) _Inline Python code directly in your Rust code_
* [Rogue-Gym](https://github.com/kngwyu/rogue-gym) _Customizable rogue-like game for AI experiments_
* Contains an example of building wheels on Azure Pipelines
* [fastuuid](https://github.com/thedrow/fastuuid/) _Python bindings to Rust's UUID library_
* [python-ext-wasm](https://github.com/wasmerio/python-ext-wasm) _Python library to run WebAssembly binaries_
* [mocpy](https://github.com/cds-astro/mocpy) _Astronomical Python library offering data structures for describing any arbitrary coverage regions on the unit sphere_
* [tokenizers](https://github.com/huggingface/tokenizers/tree/master/bindings/python) _Python bindings to the Hugging Face tokenizers (NLP) written in Rust_

View File

@ -1,6 +1,6 @@
# Python Modules # Python Modules
As shown in the Getting Started chapter, you can create a module as follows: You can create a module as follows:
```rust ```rust
use pyo3::prelude::*; use pyo3::prelude::*;
@ -34,7 +34,7 @@ fn sum_as_string(a: i64, b: i64) -> String {
The `#[pymodule]` procedural macro attribute takes care of exporting the initialization function of your module to Python. It can take as an argument the name of your module, which must be the name of the `.so` or `.pyd` file; the default is the Rust function's name. The `#[pymodule]` procedural macro attribute takes care of exporting the initialization function of your module to Python. It can take as an argument the name of your module, which must be the name of the `.so` or `.pyd` file; the default is the Rust function's name.
To import the module, either copy the shared library as described in [Get Started](./get_started.md) or use a tool, e.g. `maturin develop` with [maturin](https://github.com/PyO3/maturin) or `python setup.py develop` with [setuptools-rust](https://github.com/PyO3/setuptools-rust). To import the module, either copy the shared library as described in [the README](https://github.com/PyO3/pyo3) or use a tool, e.g. `maturin develop` with [maturin](https://github.com/PyO3/maturin) or `python setup.py develop` with [setuptools-rust](https://github.com/PyO3/setuptools-rust).
## Documentation ## Documentation

View File

@ -335,7 +335,6 @@ pub mod doc_test {
doctest!("../guide/src/debugging.md", guide_debugging_md); doctest!("../guide/src/debugging.md", guide_debugging_md);
doctest!("../guide/src/exception.md", guide_exception_md); doctest!("../guide/src/exception.md", guide_exception_md);
doctest!("../guide/src/function.md", guide_function_md); doctest!("../guide/src/function.md", guide_function_md);
doctest!("../guide/src/get_started.md", guide_get_started_md);
doctest!("../guide/src/migration.md", guide_migration_md); doctest!("../guide/src/migration.md", guide_migration_md);
doctest!("../guide/src/module.md", guide_module_md); doctest!("../guide/src/module.md", guide_module_md);
doctest!( doctest!(