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