-
-
Notifications
You must be signed in to change notification settings - Fork 269
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add mdbook based user guide * Add netlify config file * Update guide/src/installation.md Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com> * Update installation guide * Update bindings guide * Update metadata guide * Add tutorial first draft. * Add project layout draft. * Correct informaton about Python type hints in project layout guide. * Add bindings section draft. * Update guide/src/bindings.md * Upgrade mdbook to 0.4.13 * Add repository metadata to mdbook configuration Co-authored-by: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Co-authored-by: Ashley Anderson <aanderson@hyperfine-research.com>
- Loading branch information
1 parent
0dee405
commit 26c0ffb
Showing
12 changed files
with
645 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
book |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[book] | ||
author = ["PyO3 Project and Contributors"] | ||
language = "en" | ||
multilingual = false | ||
src = "src" | ||
title = "Maturin User Guide" | ||
|
||
[output.html] | ||
git-repository-url = "https://github.com/PyO3/maturin/tree/main/guide" | ||
edit-url-template = "https://github.com/PyO3/maturin/edit/main/guide/{path}" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Summary | ||
|
||
[Introduction](index.md) | ||
|
||
--- | ||
|
||
- [Installation](./installation.md) | ||
- [Tutorial](./tutorial.md) | ||
- [Project Layout](./project_layout.md) | ||
- [Bindings](./bindings.md) | ||
- [Python Metadata](./metadata.md) | ||
- [Local Development](./develop.md) | ||
- [Distribution](./distribution.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# Bindings | ||
|
||
Maturin supports several kinds of bindings, some of which are automatically | ||
detected. You can also pass `-b` / `--bindings` command line option to manually | ||
specify which bindings to use. | ||
|
||
## `pyo3` | ||
|
||
[pyo3](https://github.com/PyO3/pyo3) is Rust bindings for Python, | ||
including tools for creating native Python extension modules. | ||
It supports both CPython and PyPy. | ||
|
||
maturin automatically detects pyo3 bindings when it's added as a dependency in `Cargo.toml`. | ||
|
||
### `Py_LIMITED_API`/abi3 | ||
|
||
pyo3 bindings has `Py_LIMITED_API`/abi3 support, enable the `abi3` feature of the `pyo3` crate to use it: | ||
|
||
```toml | ||
pyo3 = { version = "0.14", features = ["abi3"] } | ||
``` | ||
|
||
You may additionally specify a minimum Python version by using the `abi3-pyXX` | ||
format for the pyo3 features, where `XX` is corresponds to a Python verison. | ||
For example `abi3-py37` will indicate a minimum Python version of 3.7. | ||
|
||
> **Note**: Read more about abi3 support in [pyo3's | ||
> documentation](https://pyo3.rs/latest/building_and_distribution.html#py_limited_apiabi3). | ||
### Cross Compiling | ||
|
||
pyo3 bindings has decent cross compilation support. | ||
For manylinux support the [manylinux-cross](https://github.com/messense/manylinux-cross) docker images can be used. | ||
|
||
> **Note**: Read more about cross compiling in [pyo3's | ||
> documentation](https://pyo3.rs/latest/building_and_distribution.html#cross-compiling). | ||
## `cffi` | ||
|
||
Cffi wheels are compatible with all python versions including pypy. If `cffi` | ||
isn't installed and python is running inside a virtualenv, maturin will install | ||
it, otherwise you have to install it yourself (`pip install cffi`). | ||
|
||
Maturin uses cbindgen to generate a header file for [supported Rust | ||
types](https://github.com/eqrion/cbindgen/blob/master/docs.md#supported-types). | ||
The header file can be customized by configuring cbindgen through a | ||
`cbindgen.toml` file inside your project root. Aternatively you can use a build | ||
script that writes a header file to `$PROJECT_ROOT/target/header.h`, like so: | ||
|
||
```rust | ||
use cbindgen; | ||
use std::env; | ||
use std::path::Path; | ||
|
||
fn main() { | ||
let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); | ||
|
||
let bindings = cbindgen::Builder::new() | ||
.with_no_includes() | ||
.with_language(cbindgen::Language::C) | ||
.with_crate(crate_dir) | ||
.generate() | ||
.unwrap(); | ||
bindings.write_to_file(Path::new("target").join("header.h")); | ||
} | ||
``` | ||
|
||
Maturin uses the cbindgen-generated header to create a module that exposes `ffi` and | ||
`lib` objects as attributes. See the [cffi docs](https://cffi.readthedocs.io/en/latest/using.html) | ||
for more information on using theses `ffi`/`lib` objects to call the Rust code | ||
from Python. | ||
|
||
> **Note**: Maturin _does not_ automatically detect `cffi` bindings. You _must_ | ||
> specify them via either command line with `-b cffi` or in `pyproject.toml`. | ||
## `rust-cpython` | ||
|
||
[rust-cpython](https://github.com/dgrunwald/rust-cpython) is Rust bindings for | ||
the Python interperter. Currently it only supports CPython. | ||
|
||
Maturin automatically detects rust-cpython bindings when it's added as a | ||
dependency in `Cargo.toml`. | ||
|
||
## `bin` | ||
|
||
Maturin also supports distributing binary applications written in Rust as | ||
Python packages using the `bin` bindings. Binaries are packaged into the wheel | ||
as "scripts" and are available on the user's `PATH` (e.g. in the `bin` | ||
directory of a virtual environment) once installed. | ||
|
||
> **Note**: Maturin _does not_ automatically detect `bin` bindings. You _must_ | ||
> specify them via either command line with `-b bin` or in `pyproject.toml`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Local Development | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# Distribution | ||
|
||
## Source Distribution | ||
|
||
TODO | ||
|
||
## Build Wheels | ||
|
||
TODO |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Maturin User Guide | ||
|
||
Welcome to the maturin user guide! It contains examples and documentation to explain all of maturin's use cases in detail. | ||
|
||
Please choose from the chapters on the left to jump to individual topics, or continue below to start with maturin's README. | ||
|
||
{{#include ../../Readme.md}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# Installation | ||
|
||
## Install from package managers | ||
|
||
### PyPI | ||
|
||
maturin is published as Python binary wheel to PyPI, you can install it using pip: | ||
|
||
```bash | ||
pip install maturin | ||
``` | ||
|
||
### Homebrew | ||
|
||
On macOS [maturin is in Homebrew](https://formulae.brew.sh/formula/maturin#default) and you can install maturin from Homebrew: | ||
|
||
```bash | ||
brew install maturin | ||
``` | ||
|
||
### conda | ||
|
||
Installing from the `conda-forge` channel can be achieved by adding `conda-forge` to your conda channels with: | ||
|
||
``` | ||
conda config --add channels conda-forge | ||
conda config --set channel_priority strict | ||
``` | ||
|
||
Once the `conda-forge` channel has been enabled, `maturin` can be installed with: | ||
|
||
``` | ||
conda install maturin | ||
``` | ||
|
||
### Alpine Linux | ||
|
||
On Alpine Linux, [maturin is in community repository](https://pkgs.alpinelinux.org/packages?name=maturin&branch=edge&repo=community) | ||
and can be installed with `apk` after [enabling the community repository](https://wiki.alpinelinux.org/wiki/Enable_Community_Repository): | ||
|
||
```bash | ||
apk add maturin | ||
``` | ||
|
||
## Download from GitHub Releases | ||
|
||
You can download precompiled maturin binaries from the latest [GitHub Releases](https://github.com/PyO3/maturin/releases/latest). | ||
|
||
## Build from source | ||
|
||
### crates.io | ||
|
||
You can install maturin from [crates.io](https://crates.io/crates/maturin) using cargo: | ||
|
||
```bash | ||
cargo install maturin | ||
``` | ||
|
||
### Git repository | ||
|
||
```bash | ||
cargo install --git https://github.com/PyO3/maturin.git maturin | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Python Project Metadata | ||
|
||
maturin supports [PEP 621](https://www.python.org/dev/peps/pep-0621/), | ||
you can specify python package metadata in `pyproject.toml`. | ||
maturin merges metadata from `Cargo.toml` and `pyproject.toml`, `pyproject.toml` take precedence over `Cargo.toml`. | ||
|
||
## Add Python dependencies | ||
|
||
To specify python dependencies, add a list `dependencies` in a `[project]` section in the `pyproject.toml`. This list is equivalent to `install_requires` in setuptools: | ||
|
||
```toml | ||
[project] | ||
dependencies = ["flask~=1.1.0", "toml==0.10.0"] | ||
``` | ||
|
||
## Add console scripts | ||
|
||
Pip allows adding so called console scripts, which are shell commands that execute some function in you program. You can add console scripts in a section `[project.scripts]`. | ||
The keys are the script names while the values are the path to the function in the format `some.module.path:class.function`, where the `class` part is optional. The function is called with no arguments. Example: | ||
|
||
```toml | ||
[project.scripts] | ||
get_42 = "my_project:DummyClass.get_42" | ||
``` | ||
|
||
## Add trove classifiers | ||
|
||
You can also specify [trove classifiers](https://pypi.org/classifiers/) in your Cargo.toml under `project.classifiers`: | ||
|
||
```toml | ||
[project] | ||
classifiers = ["Programming Language :: Python"] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
# Project Layout | ||
|
||
Maturin expects a particular project layout depending on the contents of the | ||
package. | ||
|
||
## Pure Rust project | ||
|
||
For a pure Rust project, the structure is as expected and what you get from `cargo new`: | ||
|
||
``` | ||
my-rust-project/ | ||
├── Cargo.toml | ||
├── pyproject.toml # required for maturin configuration | ||
└── src | ||
├── lib.rs # default for library crates | ||
└── main.rs # default for binary crates | ||
``` | ||
|
||
Maturin will add a necessary `__init__.py` to the package when building the | ||
wheel. For convenience, this file includes the following: | ||
|
||
```python | ||
from .my_project import * | ||
|
||
__doc__ = .my_project.__doc__ | ||
``` | ||
|
||
such that the module functions may be called directly with: | ||
|
||
```python | ||
import my_project | ||
my_project.foo() | ||
``` | ||
|
||
rather than: | ||
|
||
```python | ||
from my_project import my_project | ||
``` | ||
|
||
> **Note**: there is currently no way to tell maturin to include extra data (e.g. | ||
`package_data` in setuptools) for a pure Rust project. Instead, consider using | ||
the layout described below for the mixed Rust/Python project. | ||
|
||
## Mixed Rust/Python project | ||
|
||
To create a mixed Rust/Python project, add a directory with your package name | ||
(i.e. matching `lib.name` in your `Cargo.toml`) to contain the Python source: | ||
|
||
``` | ||
my-rust-and-python-project | ||
├── Cargo.toml | ||
├── my_project # <<< add this directory and put Python code in here | ||
│ ├── __init__.py | ||
│ └── bar.py | ||
├── pyproject.toml | ||
├── Readme.md | ||
└── src | ||
└── lib.rs | ||
``` | ||
|
||
Note that in a mixed Rust/Python project, maturin _does not_ modify the | ||
existing `__init__.py` in the root package, so now to import the rust module in | ||
Python you must use: | ||
|
||
```python | ||
from my_project import my_project | ||
``` | ||
|
||
You can modify `__init__.py` yourself (see above) if you would like to import | ||
functions Rust functions from a higher-level namespace. | ||
|
||
### Alternate Python source directory (src layout) | ||
|
||
Having a directory with `package_name` in the root of the project can | ||
occasionally cause confusion as Python allows importing local packages and | ||
modules. A popular way to avoid this is with the `src`-layout, where the Python | ||
package is nested within a `src` directory. Unfortunately this interferes with | ||
the structure of a typical Rust project. Fortunately, Python is nor particular | ||
about the name of the parent source directory. You tell maturin to use a | ||
different Python source directory in `Cargo.toml` by setting | ||
`package.metadata.maturin.python-source`. For example: | ||
|
||
```toml | ||
[package.metadata.maturin] | ||
python-source = "python" | ||
``` | ||
|
||
then the project structure would look like this: | ||
|
||
``` | ||
my-rust-and-python-project | ||
├── Cargo.toml | ||
├── python | ||
│ └── my_project | ||
│ ├── __init__.py | ||
│ └── bar.py | ||
├── pyproject.toml | ||
├── README.md | ||
└── src | ||
└── lib.rs | ||
``` | ||
|
||
## Adding Python type information | ||
|
||
To distribute typing information, you need to add: | ||
|
||
* an empty marker file called `py.typed` in the root of the Python package | ||
* inline types in Python files and/or `.pyi` "stub" files | ||
|
||
In a pure Rust project, add type stubs in a `<module_name>.pyi` file in the | ||
project root. Maturin will automatically include this file along with the | ||
required `py.typed` file for you. | ||
|
||
``` | ||
my-rust-project/ | ||
├── Cargo.toml | ||
├── my_project.pyi # <<< add type stubs for Rust functions in the my_project module here | ||
├── pyproject.toml | ||
└── src | ||
└── lib.rs | ||
``` | ||
|
||
In a mixed Rust/Python project, additional files in the Python source dir (but | ||
not in `.gitignore`) will be automatically included in the build outputs | ||
(source distribution and/or wheel). Type information can be therefore added to | ||
the root Python package directory as you might do in a pure Python package. | ||
This requires you to add the `py.typed` marker file yourself. | ||
|
||
``` | ||
my-project | ||
├── Cargo.toml | ||
├── python | ||
│ └── my_project | ||
│ ├── __init__.py | ||
│ ├── py.typed # <<< add this empty file | ||
│ ├── my_project.pyi # <<< add type stubs for Rust functions in the my_project module here | ||
│ ├── bar.pyi # <<< add type stubs for bar.py here OR type bar.py inline | ||
│ └── bar.py | ||
├── pyproject.toml | ||
├── README.md | ||
└── src | ||
└── lib.rs | ||
``` |
Oops, something went wrong.