Ligações Rust para Python, incluindo ferramentas para criar módulos de extensão nativos do Python. A execução e interação com código Python de um binário Rust também é suportada.
Guia do usuário: estável | principal
Documentação API: estável | principal
Requer Rust 1.63 ou superior.
PyO3 oferece suporte às seguintes distribuições Python:
Você pode usar PyO3 para escrever um módulo Python nativo em Rust ou para incorporar Python em um binário Rust. As seções a seguir explicam cada um deles por vez.
PyO3 pode ser usado para gerar um módulo Python nativo. A maneira mais fácil de experimentar pela primeira vez é usar maturin
. maturin
é uma ferramenta para construir e publicar pacotes Python baseados em Rust com configuração mínima. As etapas a seguir instalam maturin
, usam-no para gerar e construir um novo pacote Python e, em seguida, iniciam o Python para importar e executar uma função do pacote.
Primeiro, siga os comandos abaixo para criar um novo diretório contendo um novo Python virtualenv
e instale maturin
no virtualenv usando o gerenciador de pacotes do Python, pip
:
# (replace string_sum with the desired package name)
$ mkdir string_sum
$ cd string_sum
$ python -m venv .env
$ source .env/bin/activate
$ pip install maturin
Ainda dentro deste diretório string_sum
, agora execute maturin init
. Isso irá gerar a nova fonte do pacote. Quando tiver a opção de vinculações a serem usadas, selecione as vinculações pyo3:
$ maturin init
✔ ? What kind of bindings to use ? · pyo3
Done ! New project created string_sum
Os arquivos mais importantes gerados por este comando são Cargo.toml
e lib.rs
, que serão mais ou menos assim:
Cargo.toml
[ package ]
name = " string_sum "
version = " 0.1.0 "
edition = " 2021 "
[ lib ]
# The name of the native library. This is the name which will be used in Python to import the
# library (i.e. `import string_sum`). If you change this, you must also change the name of the
# `#[pymodule]` in `src/lib.rs`.
name = " string_sum "
# "cdylib" is necessary to produce a shared library for Python to import from.
#
# Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
# to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
# crate-type = ["cdylib", "rlib"]
crate-type = [ " cdylib " ]
[ dependencies ]
pyo3 = { version = " 0.23.3 " , features = [ " extension-module " ] }
src/lib.rs
use pyo3 :: prelude :: * ;
/// Formats the sum of two numbers as string.
# [ pyfunction ]
fn sum_as_string ( a : usize , b : usize ) -> PyResult < String > {
Ok ( ( a + b ) . to_string ( ) )
}
/// A Python module implemented in Rust. The name of this function must match
/// the `lib.name` setting in the `Cargo.toml`, else Python will not be able to
/// import the module.
# [ pymodule ]
fn string_sum ( m : & Bound < ' _ , PyModule > ) -> PyResult < ( ) > {
m . add_function ( wrap_pyfunction ! ( sum_as_string , m ) ? ) ? ;
Ok ( ( ) )
}
Finalmente, execute maturin develop
. Isso irá construir o pacote e instalá-lo no virtualenv Python criado e ativado anteriormente. O pacote está então pronto para ser usado em python
:
$ maturin develop
# lots of progress output as maturin runs the compilation...
$ python
>>> import string_sum
>>> string_sum.sum_as_string(5, 20)
' 25 '
Para fazer alterações no pacote, basta editar o código-fonte do Rust e executar novamente maturin develop
para recompilar.
Para executar tudo isso como um único copiar e colar, use o script bash abaixo (substitua string_sum
no primeiro comando pelo nome do pacote desejado):
mkdir string_sum && cd " $_ "
python -m venv .env
source .env/bin/activate
pip install maturin
maturin init --bindings pyo3
maturin develop
Se você quiser executar cargo test
ou usar este projeto em um espaço de trabalho Cargo e estiver enfrentando problemas de vinculador, há algumas soluções alternativas nas Perguntas frequentes.
Assim como com maturin
, é possível construir usando setuptools-rust
ou manualmente. Ambos oferecem mais flexibilidade que maturin
, mas exigem mais configuração para começar.
Para incorporar Python em um binário Rust, você precisa garantir que sua instalação do Python contenha uma biblioteca compartilhada. As etapas a seguir demonstram como garantir isso (para Ubuntu) e, em seguida, fornecem alguns exemplos de código que executam um interpretador Python incorporado.
Para instalar a biblioteca compartilhada Python no Ubuntu:
sudo apt install python3-dev
Para instalar a biblioteca compartilhada Python em distribuições baseadas em RPM (por exemplo, Fedora, Red Hat, SuSE), instale o pacote python3-devel
.
Inicie um novo projeto com cargo new
e adicione pyo3
ao Cargo.toml
assim:
[ dependencies . pyo3 ]
version = " 0.23.3 "
features = [ " auto-initialize " ]
Programa de exemplo exibindo o valor de sys.version
e o nome do usuário atual:
use pyo3 :: prelude :: * ;
use pyo3 :: types :: IntoPyDict ;
use pyo3 :: ffi :: c_str ;
fn main ( ) -> PyResult < ( ) > {
Python :: with_gil ( |py| {
let sys = py . import ( "sys" ) ? ;
let version : String = sys . getattr ( "version" ) ? . extract ( ) ? ;
let locals = [ ( "os" , py . import ( "os" ) ? ) ] . into_py_dict ( py ) ? ;
let code = c_str ! ( "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 ( ( ) )
} )
}
O guia possui uma seção com muitos exemplos sobre este assunto.
built
como um PyDict
Todos são bem-vindos para contribuir com o PyO3! Existem muitas maneiras de apoiar o projeto, como:
Nossas notas de contribuição e guia de arquitetura têm mais recursos se você deseja dedicar tempo voluntário ao PyO3 e está procurando por onde começar.
Se você não tem tempo para contribuir, mas ainda deseja apoiar o sucesso futuro do projeto, alguns de nossos mantenedores têm páginas de patrocínio no GitHub:
PyO3 é licenciado sob a licença Apache-2.0 ou licença MIT, conforme sua opção.
Python é licenciado sob a Licença Python.
A menos que você declare explicitamente o contrário, qualquer contribuição enviada intencionalmente para inclusão no PyO3 por você, conforme definido na Licença Apache, deverá ser licenciada duplamente conforme acima, sem quaisquer termos ou condições adicionais.