1#![warn(missing_docs)]
2#![cfg_attr(feature = "nightly", feature(auto_traits, negative_impls))]
3#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
4// Deny some lints in doctests.
5// Use `#[allow(...)]` locally to override.
6#![doc(test(attr(
7 deny(
8 rust_2018_idioms,
9 unused_lifetimes,
10 rust_2021_prelude_collisions,
11 warnings
12 ),
13 allow(
14 unused_variables,
15 unused_assignments,
16 unused_extern_crates,
17 unused_imports,
18 dead_code,
19 )
20)))]
21
22//! Rust bindings to the Python interpreter.
23//!
24//! PyO3 can be used to write native Python modules or run Python code and modules from Rust.
25//!
26//! See [the guide] for a detailed introduction.
27//!
28//! # PyO3's object types
29//!
30//! PyO3 has several core types that you should familiarize yourself with:
31//!
32//! ## The Python<'py> object
33//!
34//! Holding the [global interpreter lock] (GIL) is modeled with the [`Python<'py>`](crate::Python)
35//! token. All APIs that require that the GIL is held require this token as proof that you really
36//! are holding the GIL. It can be explicitly acquired and is also implicitly acquired by PyO3 as
37//! it wraps Rust functions and structs into Python functions and objects.
38//!
39//! ## The GIL-dependent types
40//!
41//! For example `&`[`PyAny`]. These are only ever seen as references, with a lifetime that is only
42//! valid for as long as the GIL is held, which is why using them doesn't require a
43//! [`Python<'py>`](crate::Python) token. The underlying Python object, if mutable, can be mutated
44//! through any reference.
45//!
46//! See the [guide][types] for an explanation of the different Python object types.
47//!
48//! ## The GIL-independent types
49//!
50//! When wrapped in [`Py`]`<...>`, like with [`Py`]`<`[`PyAny`]`>` or [`Py`]`<SomePyClass>`, Python
51//! objects no longer have a limited lifetime which makes them easier to store in structs and pass
52//! between functions. However, you cannot do much with them without a
53//! [`Python<'py>`](crate::Python) token, for which you’d need to reacquire the GIL.
54//!
55//! ## PyErr
56//!
57//! The vast majority of operations in this library will return [`PyResult<...>`](PyResult).
58//! This is an alias for the type `Result<..., PyErr>`.
59//!
60//! A `PyErr` represents a Python exception. A `PyErr` returned to Python code will be raised as a
61//! Python exception. Errors from `PyO3` itself are also exposed as Python exceptions.
62//!
63//! # Feature flags
64//!
65//! PyO3 uses [feature flags] to enable you to opt-in to additional functionality. For a detailed
66//! description, see the [Features chapter of the guide].
67//!
68//! ## Default feature flags
69//!
70//! The following features are turned on by default:
71//! - `macros`: Enables various macros, including all the attribute macros.
72//!
73//! ## Optional feature flags
74//!
75//! The following features customize PyO3's behavior:
76//!
77//! - `abi3`: Restricts PyO3's API to a subset of the full Python API which is guaranteed by
78//! [PEP 384] to be forward-compatible with future Python versions.
79//! - `auto-initialize`: Changes [`Python::with_gil`] to automatically initialize the Python
80//! interpreter if needed.
81//! - `extension-module`: This will tell the linker to keep the Python symbols unresolved, so that
82//! your module can also be used with statically linked Python interpreters. Use this feature when
83//! building an extension module.
84//! - `multiple-pymethods`: Enables the use of multiple [`#[pymethods]`](macro@crate::pymethods)
85//! blocks per [`#[pyclass]`](macro@crate::pyclass). This adds a dependency on the [inventory]
86//! crate, which is not supported on all platforms.
87//!
88//! The following features enable interactions with other crates in the Rust ecosystem:
89//! - [`anyhow`]: Enables a conversion from [anyhow]’s [`Error`][anyhow_error] type to [`PyErr`].
90//! - [`chrono`]: Enables a conversion from [chrono]'s structures to the equivalent Python ones.
91//! - [`either`]: Enables conversions between Python objects and [either]'s [`Either`] type.
92//! - [`eyre`]: Enables a conversion from [eyre]’s [`Report`] type to [`PyErr`].
93//! - [`hashbrown`]: Enables conversions between Python objects and [hashbrown]'s [`HashMap`] and
94//! [`HashSet`] types.
95//! - [`indexmap`][indexmap_feature]: Enables conversions between Python dictionary and [indexmap]'s [`IndexMap`].
96//! - [`num-bigint`]: Enables conversions between Python objects and [num-bigint]'s [`BigInt`] and
97//! [`BigUint`] types.
98//! - [`num-complex`]: Enables conversions between Python objects and [num-complex]'s [`Complex`]
99//! type.
100//! - [`rust_decimal`]: Enables conversions between Python's decimal.Decimal and [rust_decimal]'s
101//! [`Decimal`] type.
102//! - [`serde`]: Allows implementing [serde]'s [`Serialize`] and [`Deserialize`] traits for
103//! [`Py`]`<T>` for all `T` that implement [`Serialize`] and [`Deserialize`].
104//! - [`smallvec`][smallvec]: Enables conversions between Python list and [smallvec]'s [`SmallVec`].
105//!
106//! ## Unstable features
107//!
108//! - `nightly`: Uses `#![feature(auto_traits, negative_impls)]` to define [`Ungil`] as an auto trait.
109//
110//! ## `rustc` environment flags
111//!
112//! PyO3 uses `rustc`'s `--cfg` flags to enable or disable code used for different Python versions.
113//! If you want to do this for your own crate, you can do so with the [`pyo3-build-config`] crate.
114//!
115//! - `Py_3_7`, `Py_3_8`, `Py_3_9`, `Py_3_10`: Marks code that is only enabled when
116//! compiling for a given minimum Python version.
117//! - `Py_LIMITED_API`: Marks code enabled when the `abi3` feature flag is enabled.
118//! - `PyPy` - Marks code enabled when compiling for PyPy.
119//!
120//! # Minimum supported Rust and Python versions
121//!
122//! PyO3 supports the following software versions:
123//! - Python 3.7 and up (CPython and PyPy)
124//! - Rust 1.56 and up
125//!
126//! # Example: Building a native Python module
127//!
128//! PyO3 can be used to generate a native Python module. The easiest way to try this out for the
129//! first time is to use [`maturin`]. `maturin` is a tool for building and publishing Rust-based
130//! Python packages with minimal configuration. The following steps set up some files for an example
131//! Python module, install `maturin`, and then show how to build and import the Python module.
132//!
133//! First, create a new folder (let's call it `string_sum`) containing the following two files:
134//!
135//! **`Cargo.toml`**
136//!
137//! ```toml
138//! [package]
139//! name = "string-sum"
140//! version = "0.1.0"
141//! edition = "2021"
142//!
143//! [lib]
144//! name = "string_sum"
145//! # "cdylib" is necessary to produce a shared library for Python to import from.
146//! #
147//! # Downstream Rust code (including code in `bin/`, `examples/`, and `tests/`) will not be able
148//! # to `use string_sum;` unless the "rlib" or "lib" crate type is also included, e.g.:
149//! # crate-type = ["cdylib", "rlib"]
150//! crate-type = ["cdylib"]
151//!
152//! [dependencies.pyo3]
153#![doc = concat!("version = \"", env!("CARGO_PKG_VERSION"), "\"")]
154//! features = ["extension-module"]
155//! ```
156//!
157//! **`src/lib.rs`**
158//! ```rust
159//! use pyo3::prelude::*;
160//!
161//! /// Formats the sum of two numbers as string.
162//! #[pyfunction]
163//! fn sum_as_string(a: usize, b: usize) -> PyResult<String> {
164//! Ok((a + b).to_string())
165//! }
166//!
167//! /// A Python module implemented in Rust.
168//! #[pymodule]
169//! fn string_sum(py: Python<'_>, m: &PyModule) -> PyResult<()> {
170//! m.add_function(wrap_pyfunction!(sum_as_string, m)?)?;
171//!
172//! Ok(())
173//! }
174//! ```
175//!
176//! With those two files in place, now `maturin` needs to be installed. This can be done using
177//! Python's package manager `pip`. First, load up a new Python `virtualenv`, and install `maturin`
178//! into it:
179//! ```bash
180//! $ cd string_sum
181//! $ python -m venv .env
182//! $ source .env/bin/activate
183//! $ pip install maturin
184//! ```
185//!
186//! Now build and execute the module:
187//! ```bash
188//! $ maturin develop
189//! # lots of progress output as maturin runs the compilation...
190//! $ python
191//! >>> import string_sum
192//! >>> string_sum.sum_as_string(5, 20)
193//! '25'
194//! ```
195//!
196//! As well as with `maturin`, it is possible to build using [setuptools-rust] or
197//! [manually][manual_builds]. Both offer more flexibility than `maturin` but require further
198//! configuration.
199//!
200//! # Example: Using Python from Rust
201//!
202//! To embed Python into a Rust binary, you need to ensure that your Python installation contains a
203//! shared library. The following steps demonstrate how to ensure this (for Ubuntu), and then give
204//! some example code which runs an embedded Python interpreter.
205//!
206//! To install the Python shared library on Ubuntu:
207//! ```bash
208//! sudo apt install python3-dev
209//! ```
210//!
211//! Start a new project with `cargo new` and add `pyo3` to the `Cargo.toml` like this:
212//! ```toml
213//! [dependencies.pyo3]
214#![doc = concat!("version = \"", env!("CARGO_PKG_VERSION"), "\"")]
215//! # this is necessary to automatically initialize the Python interpreter
216//! features = ["auto-initialize"]
217//! ```
218//!
219//! Example program displaying the value of `sys.version` and the current user name:
220//! ```rust
221//! use pyo3::prelude::*;
222//! use pyo3::types::IntoPyDict;
223//!
224//! fn main() -> PyResult<()> {
225//! Python::with_gil(|py| {
226//! let sys = py.import("sys")?;
227//! let version: String = sys.getattr("version")?.extract()?;
228//!
229//! let locals = [("os", py.import("os")?)].into_py_dict(py);
230//! let code = "os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'";
231//! let user: String = py.eval(code, None, Some(&locals))?.extract()?;
232//!
233//! println!("Hello {}, I'm Python {}", user, version);
234//! Ok(())
235//! })
236//! }
237//! ```
238//!
239//! The guide has [a section][calling_rust] with lots of examples about this topic.
240//!
241//! # Other Examples
242//!
243//! The PyO3 [README](https://github.com/PyO3/pyo3#readme) contains quick-start examples for both
244//! using [Rust from Python] and [Python from Rust].
245//!
246//! The PyO3 repository's [examples subdirectory]
247//! contains some basic packages to demonstrate usage of PyO3.
248//!
249//! There are many projects using PyO3 - see a list of some at
250//! <https://github.com/PyO3/pyo3#examples>.
251//!
252//! [anyhow]: https://docs.rs/anyhow/ "A trait object based error system for easy idiomatic error handling in Rust applications."
253//! [anyhow_error]: https://docs.rs/anyhow/latest/anyhow/struct.Error.html "Anyhows `Error` type, a wrapper around a dynamic error type"
254//! [`anyhow`]: ./anyhow/index.html "Documentation about the `anyhow` feature."
255//! [inventory]: https://docs.rs/inventory
256//! [`HashMap`]: https://docs.rs/hashbrown/latest/hashbrown/struct.HashMap.html
257//! [`HashSet`]: https://docs.rs/hashbrown/latest/hashbrown/struct.HashSet.html
258//! [`SmallVec`]: https://docs.rs/smallvec/latest/smallvec/struct.SmallVec.html
259//! [`IndexMap`]: https://docs.rs/indexmap/latest/indexmap/map/struct.IndexMap.html
260//! [`BigInt`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html
261//! [`BigUint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigUint.html
262//! [`Complex`]: https://docs.rs/num-complex/latest/num_complex/struct.Complex.html
263//! [`Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html
264//! [`Serialize`]: https://docs.rs/serde/latest/serde/trait.Serialize.html
265//! [chrono]: https://docs.rs/chrono/ "Date and Time for Rust."
266//! [`chrono`]: ./chrono/index.html "Documentation about the `chrono` feature."
267//! [either]: https://docs.rs/either/ "A type that represents one of two alternatives."
268//! [`either`]: ./either/index.html "Documentation about the `either` feature."
269//! [`Either`]: https://docs.rs/either/latest/either/enum.Either.html
270//! [eyre]: https://docs.rs/eyre/ "A library for easy idiomatic error handling and reporting in Rust applications."
271//! [`Report`]: https://docs.rs/eyre/latest/eyre/struct.Report.html
272//! [`eyre`]: ./eyre/index.html "Documentation about the `eyre` feature."
273//! [`hashbrown`]: ./hashbrown/index.html "Documentation about the `hashbrown` feature."
274//! [indexmap_feature]: ./indexmap/index.html "Documentation about the `indexmap` feature."
275//! [`maturin`]: https://github.com/PyO3/maturin "Build and publish crates with pyo3, rust-cpython and cffi bindings as well as rust binaries as python packages"
276//! [`num-bigint`]: ./num_bigint/index.html "Documentation about the `num-bigint` feature."
277//! [`num-complex`]: ./num_complex/index.html "Documentation about the `num-complex` feature."
278//! [`pyo3-build-config`]: https://docs.rs/pyo3-build-config
279//! [rust_decimal]: https://docs.rs/rust_decimal
280//! [`rust_decimal`]: ./rust_decimal/index.html "Documenation about the `rust_decimal` feature."
281//! [`Decimal`]: https://docs.rs/rust_decimal/latest/rust_decimal/struct.Decimal.html
282//! [`serde`]: <./serde/index.html> "Documentation about the `serde` feature."
283//! [calling_rust]: https://pyo3.rs/latest/python_from_rust.html "Calling Python from Rust - PyO3 user guide"
284//! [examples subdirectory]: https://github.com/PyO3/pyo3/tree/main/examples
285//! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book"
286//! [global interpreter lock]: https://docs.python.org/3/glossary.html#term-global-interpreter-lock
287//! [hashbrown]: https://docs.rs/hashbrown
288//! [smallvec]: https://docs.rs/smallvec
289//! [indexmap]: https://docs.rs/indexmap
290//! [manual_builds]: https://pyo3.rs/latest/building_and_distribution.html#manual-builds "Manual builds - Building and Distribution - PyO3 user guide"
291//! [num-bigint]: https://docs.rs/num-bigint
292//! [num-complex]: https://docs.rs/num-complex
293//! [serde]: https://docs.rs/serde
294//! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions"
295//! [the guide]: https://pyo3.rs "PyO3 user guide"
296//! [types]: https://pyo3.rs/latest/types.html "GIL lifetimes, mutability and Python object types"
297//! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI"
298//! [Python from Rust]: https://github.com/PyO3/pyo3#using-python-from-rust
299//! [Rust from Python]: https://github.com/PyO3/pyo3#using-rust-from-python
300//! [Features chapter of the guide]: https://pyo3.rs/latest/features.html#features-reference "Features Reference - PyO3 user guide"
301//! [`Ungil`]: crate::marker::Ungil
302pub use crate::class::*;
303pub use crate::conversion::{
304 AsPyPointer, FromPyObject, FromPyPointer, IntoPy, PyTryFrom, PyTryInto, ToPyObject,
305};
306pub use crate::err::{PyDowncastError, PyErr, PyErrArguments, PyResult};
307pub use crate::gil::GILPool;
308#[cfg(not(PyPy))]
309pub use crate::gil::{prepare_freethreaded_python, with_embedded_python_interpreter};
310pub use crate::instance::{Py, PyNativeType, PyObject};
311pub use crate::marker::Python;
312pub use crate::pycell::{PyCell, PyRef, PyRefMut};
313pub use crate::pyclass::PyClass;
314pub use crate::pyclass_init::PyClassInitializer;
315pub use crate::type_object::PyTypeInfo;
316pub use crate::types::PyAny;
317pub use crate::version::PythonVersionInfo;
318
319/// Old module which contained some implementation details of the `#[pyproto]` module.
320///
321/// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::CompareOp` instead
322/// of `use pyo3::class::basic::CompareOp`.
323///
324/// For compatibility reasons this has not yet been removed, however will be done so
325/// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
326pub mod class {
327 #[doc(hidden)]
328 pub use crate::impl_::pymethods as methods;
329
330 pub use self::gc::{PyTraverseError, PyVisit};
331
332 #[doc(hidden)]
333 pub use self::methods::{
334 PyClassAttributeDef, PyGetterDef, PyMethodDef, PyMethodDefType, PyMethodType, PySetterDef,
335 };
336
337 /// Old module which contained some implementation details of the `#[pyproto]` module.
338 ///
339 /// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::CompareOp` instead
340 /// of `use pyo3::class::basic::CompareOp`.
341 ///
342 /// For compatibility reasons this has not yet been removed, however will be done so
343 /// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
344 pub mod basic {
345 pub use crate::pyclass::CompareOp;
346 }
347
348 /// Old module which contained some implementation details of the `#[pyproto]` module.
349 ///
350 /// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::IterANextOutput` instead
351 /// of `use pyo3::class::pyasync::IterANextOutput`.
352 ///
353 /// For compatibility reasons this has not yet been removed, however will be done so
354 /// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
355 pub mod pyasync {
356 pub use crate::pyclass::{IterANextOutput, PyIterANextOutput};
357 }
358
359 /// Old module which contained some implementation details of the `#[pyproto]` module.
360 ///
361 /// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::IterNextOutput` instead
362 /// of `use pyo3::class::pyasync::IterNextOutput`.
363 ///
364 /// For compatibility reasons this has not yet been removed, however will be done so
365 /// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
366 pub mod iter {
367 pub use crate::pyclass::{IterNextOutput, PyIterNextOutput};
368 }
369
370 /// Old module which contained some implementation details of the `#[pyproto]` module.
371 ///
372 /// Prefer using the same content from `pyo3::pyclass`, e.g. `use pyo3::pyclass::PyTraverseError` instead
373 /// of `use pyo3::class::gc::PyTraverseError`.
374 ///
375 /// For compatibility reasons this has not yet been removed, however will be done so
376 /// once <https://github.com/rust-lang/rust/issues/30827> is resolved.
377 pub mod gc {
378 pub use crate::pyclass::{PyTraverseError, PyVisit};
379 }
380}
381
382#[cfg(feature = "macros")]
383#[doc(hidden)]
384pub use {
385 indoc, // Re-exported for py_run
386 unindent, // Re-exported for py_run
387};
388
389#[cfg(all(feature = "macros", feature = "multiple-pymethods"))]
390#[doc(hidden)]
391pub use inventory; // Re-exported for `#[pyclass]` and `#[pymethods]` with `multiple-pymethods`.
392
393/// Tests and helpers which reside inside PyO3's main library. Declared first so that macros
394/// are available in unit tests.
395#[cfg(test)]
396#[macro_use]
397mod tests;
398
399#[macro_use]
400mod internal_tricks;
401
402pub mod buffer;
403#[doc(hidden)]
404pub mod callback;
405pub mod conversion;
406mod conversions;
407#[macro_use]
408#[doc(hidden)]
409pub mod derive_utils;
410mod err;
411pub mod exceptions;
412pub mod ffi;
413mod gil;
414#[doc(hidden)]
415pub mod impl_;
416mod instance;
417pub mod marker;
418pub mod marshal;
419#[macro_use]
420pub mod sync;
421pub mod panic;
422pub mod prelude;
423pub mod pycell;
424pub mod pyclass;
425pub mod pyclass_init;
426
427pub mod type_object;
428pub mod types;
429mod version;
430
431#[doc(hidden)]
432#[deprecated(since = "0.19.0", note = "Please use the `sync` module instead.")]
433pub mod once_cell {
434 // FIXME: We want to deprecate these,
435 // but that does not yet work for re-exports,
436 // c.f. https://github.com/rust-lang/rust/issues/30827
437 pub use crate::sync::{GILOnceCell, Interned};
438}
439
440#[allow(unused_imports)] // with no features enabled this module has no public exports
441pub use crate::conversions::*;
442
443#[cfg(feature = "macros")]
444pub use pyo3_macros::{pyfunction, pymethods, pymodule, FromPyObject};
445
446/// A proc macro used to expose Rust structs and fieldless enums as Python objects.
447///
448#[doc = include_str!("../guide/pyclass_parameters.md")]
449///
450/// For more on creating Python classes,
451/// see the [class section of the guide][1].
452///
453/// [1]: https://pyo3.rs/latest/class.html
454#[cfg(feature = "macros")]
455pub use pyo3_macros::pyclass;
456
457#[cfg(feature = "macros")]
458#[macro_use]
459mod macros;
460
461#[cfg(feature = "experimental-inspect")]
462pub mod inspect;
463
464/// Test readme and user guide
465#[cfg(doctest)]
466pub mod doc_test {
467 macro_rules! doctests {
468 ($($path:expr => $mod:ident),* $(,)?) => {
469 $(
470 #[doc = include_str!(concat!("../", $path))]
471 mod $mod{}
472 )*
473 };
474 }
475
476 doctests! {
477 "README.md" => readme_md,
478 "guide/src/advanced.md" => guide_advanced_md,
479 "guide/src/building_and_distribution.md" => guide_building_and_distribution_md,
480 "guide/src/building_and_distribution/multiple_python_versions.md" => guide_bnd_multiple_python_versions_md,
481 "guide/src/class.md" => guide_class_md,
482 "guide/src/class/call.md" => guide_class_call,
483 "guide/src/class/object.md" => guide_class_object,
484 "guide/src/class/numeric.md" => guide_class_numeric,
485 "guide/src/class/protocols.md" => guide_class_protocols_md,
486 "guide/src/conversions.md" => guide_conversions_md,
487 "guide/src/conversions/tables.md" => guide_conversions_tables_md,
488 "guide/src/conversions/traits.md" => guide_conversions_traits_md,
489 "guide/src/debugging.md" => guide_debugging_md,
490
491 // deliberate choice not to test guide/ecosystem because those pages depend on external
492 // crates such as pyo3_asyncio.
493
494 "guide/src/exception.md" => guide_exception_md,
495 "guide/src/faq.md" => guide_faq_md,
496 "guide/src/features.md" => guide_features_md,
497 "guide/src/function.md" => guide_function_md,
498 "guide/src/function/error_handling.md" => guide_function_error_handling_md,
499 "guide/src/function/signature.md" => guide_function_signature_md,
500 "guide/src/memory.md" => guide_memory_md,
501 "guide/src/migration.md" => guide_migration_md,
502 "guide/src/module.md" => guide_module_md,
503 "guide/src/parallelism.md" => guide_parallelism_md,
504 "guide/src/performance.md" => guide_performance_md,
505 "guide/src/python_from_rust.md" => guide_python_from_rust_md,
506 "guide/src/python_typing_hints.md" => guide_python_typing_hints_md,
507 "guide/src/trait_bounds.md" => guide_trait_bounds_md,
508 "guide/src/types.md" => guide_types_md,
509 }
510}
511