back to home

PyO3 / maturin

Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages

5,485 stars
385 forks
46 issues
RustPythonShell

AI Architecture Analysis

This repository is indexed by RepoMind. By analyzing PyO3/maturin in our AI interface, you can instantly generate complete architecture diagrams, visualize control flows, and perform automated security audits across the entire codebase.

Our Agentic Context Augmented Generation (Agentic CAG) engine loads full source files into context on-demand, avoiding the fragmentation of traditional RAG systems. Ask questions about the architecture, dependencies, or specific features to see it in action.

Source files are only loaded when you start an analysis to optimize performance.

Embed this Badge

Showcase RepoMind's analysis directly in your repository's README.

[![Analyzed by RepoMind](https://img.shields.io/badge/Analyzed%20by-RepoMind-4F46E5?style=for-the-badge)](https://repomind.in/repo/PyO3/maturin)
Preview:Analyzed by RepoMind

Repository Overview (README excerpt)

Crawler view

Maturin _formerly pyo3-pack_ Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages with minimal configuration. It supports building wheels for python 3.8+ on Windows, Linux, macOS and FreeBSD, can upload them to pypi and has basic PyPy and GraalPy support. Check out the User Guide! Usage You can either download binaries from the latest release or install it with pipx or uv: > [!NOTE] > > should also work if you don't want to use pipx. There are three main commands: • creates a new cargo project with maturin configured. • builds the wheels and stores them in a folder ( by default), but doesn't upload them. It's recommended to publish packages with uv using . • builds the crate and installs it as a python module directly in the current virtualenv. Note that while is faster, it doesn't support all the feature that running after supports. maturin doesn't need extra configuration files and doesn't clash with an existing setuptools-rust configuration. You can even integrate it with testing tools such as tox. There are examples for the different bindings in the folder. The name of the package will be the name of the cargo project, i.e. the name field in the section of . The name of the module, which you are using when importing, will be the value in the section (which defaults to the name of the package). For binaries, it's simply the name of the binary generated by cargo. When using and commands, you can compile a performance-optimized program by adding the or flag. Python packaging basics Python packages come in two formats: A built form called wheel and source distributions (sdist), both of which are archives. A wheel can be compatible with any python version, interpreter (cpython and pypy, mainly), operating system and hardware architecture (for pure python wheels), can be limited to a specific platform and architecture (e.g. when using ctypes or cffi) or to a specific python interpreter and version on a specific architecture and operating system (e.g. with pyo3). When using on a package, pip tries to find a matching wheel and install that. If it doesn't find one, it downloads the source distribution and builds a wheel for the current platform, which requires the right compilers to be installed. Installing a wheel is much faster than installing a source distribution as building wheels is generally slow. When you publish a package to be installable with , you upload it to pypi, the official package repository. For testing, you can use test pypi instead, which you can use with . Note that for publishing for linux, you need to use the manylinux docker container or zig, while for publishing from your repository you can use the PyO3/maturin-action github action. Mixed rust/python projects To create a mixed rust/python project, create a folder with your module name (i.e. in Cargo.toml) next to your Cargo.toml and add your python sources there: You can specify a different python source directory in by setting , for example **pyproject.toml** then the project structure would look like this: > [!NOTE] > > This structure is recommended to avoid a common pitfall maturin will add the native extension as a module in your python folder. When using develop, maturin will copy the native library and for cffi also the glue code to your python folder. You should add those files to your gitignore. With cffi you can do and then use , with pyo3 you can directly . Example layout with pyo3 after : When doing this also be sure to set the module name in your code to match the last part of (don't include the package path): Python metadata maturin supports PEP 621, you can specify python package metadata in . maturin merges metadata from and , takes precedence over . To specify python dependencies, add a list in a section in the . This list is equivalent to in setuptools: You can add so called console scripts, which are shell commands that execute some function in your program in the section. The keys are the script names while the values are the path to the function in the format , where the part is optional. The function is called with no arguments. Example: You can also specify trove classifiers in your under : Source distribution maturin supports building through . To use it, create a next to your with the following content: If a with a entry is present, maturin can build a source distribution of your package when is specified. The source distribution will contain the same files as . To only build a source distribution, pass without any values. You can then e.g. install your package with . With you can see the output of cargo and maturin. You can use the options , , , and common Cargo build options such as under the same way you would when running maturin directly. The key is required for cffi and bin projects as those can't be automatically detected. Currently, all builds are in release mode (see this thread for details). For a non-manylinux build with cffi bindings you could use the following: option is also accepted as an alias of for backward compatibility with old version of maturin. To include arbitrary files in the sdist for use during compilation specify as an array of globs with set to : There's a command for only building a source distribution as workaround for pypa/pip#6041. Manylinux and auditwheel For portability reasons, native python modules on linux must only dynamically link a set of very few libraries which are installed basically everywhere, hence the name manylinux. The pypa offers special docker images and a tool called auditwheel to ensure compliance with the manylinux rules. If you want to publish widely usable wheels for linux pypi, **you need to use a manylinux docker image or build with zig**. The Rust compiler since version 1.64 requires at least glibc 2.17, so you need to use at least manylinux2014. For publishing, we recommend enforcing the same manylinux version as the image with the manylinux…