Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mdbook based user guide #658

Merged
merged 16 commits into from
Nov 6, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions guide/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
book
6 changes: 6 additions & 0 deletions guide/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[book]
author = ["PyO3 Project and Contributors"]
language = "en"
multilingual = false
src = "src"
title = "maturin user guide"
13 changes: 13 additions & 0 deletions guide/src/SUMMARY.md
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)
45 changes: 45 additions & 0 deletions guide/src/bindings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Bindings

maturin supports several kind of bindings, some of them are automatically
detected. You can also pass `-b` / `--bindings` command line option to manually
specify it.

## `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"] }
```

> **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`

TODO

## `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`

TODO
3 changes: 3 additions & 0 deletions guide/src/develop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Local Development

TODO
9 changes: 9 additions & 0 deletions guide/src/distribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Distribution

## Source Distribution

TODO

## Build Wheels

TODO
7 changes: 7 additions & 0 deletions guide/src/index.md
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}}
63 changes: 63 additions & 0 deletions guide/src/installation.md
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
```
33 changes: 33 additions & 0 deletions guide/src/metadata.md
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"]
```
130 changes: 130 additions & 0 deletions guide/src/project_layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# 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 maturing 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
```

N.B.: there is currently no way to tell maturin to include extra data (e.g.
type stubs or `package_data` in setuptools) for a pure Rust project. Instead,
messense marked this conversation as resolved.
Show resolved Hide resolved
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 type information

The simplest way to add type information for distribution is to use the mixed
Rust/Python projcet layout. In this layout, additional files in the Python
source dir (but not in `.gitignore`) will be automatically included in the
build outputs (source distribution and/or wheel).

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

```
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
```
Loading