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