clean up lib.rs
This commit is contained in:
parent
68cba78a44
commit
d6973b1b6a
|
@ -1,3 +1,5 @@
|
|||
#![cfg(not(Py_LIMITED_API))]
|
||||
#![cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
|
||||
// Copyright (c) 2017 Daniel Grunwald
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
//! Conversions between various states of Rust and Python types and their wrappers.
|
||||
//! Defines conversions between Rust and Python types.
|
||||
use crate::err::{self, PyDowncastError, PyResult};
|
||||
use crate::type_object::PyTypeInfo;
|
||||
use crate::types::PyTuple;
|
||||
|
|
|
@ -7,3 +7,4 @@ pub mod num_bigint;
|
|||
pub mod num_complex;
|
||||
mod osstr;
|
||||
mod path;
|
||||
pub mod serde;
|
||||
|
|
|
@ -1,3 +1,23 @@
|
|||
#![cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
#![cfg(feature = "serde")]
|
||||
|
||||
//! Enables (de)serialization of [`Py`]`<T>` objects via [serde](https://docs.rs/serde).
|
||||
//!
|
||||
//! # Setup
|
||||
//!
|
||||
//! To use this feature, add this to your **`Cargo.toml`**:
|
||||
//!
|
||||
//! ```toml
|
||||
//! [dependencies]
|
||||
//! serde = "1.0"
|
||||
// workaround for `extended_key_value_attributes`: https://github.com/rust-lang/rust/issues/82768#issuecomment-803935643
|
||||
#![cfg_attr(docsrs, cfg_attr(docsrs, doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"serde\"] }")))]
|
||||
#![cfg_attr(
|
||||
not(docsrs),
|
||||
doc = "pyo3 = { version = \"*\", features = [\"serde\"] }"
|
||||
)]
|
||||
//! ```
|
||||
|
||||
use crate::{Py, PyAny, PyClass, Python};
|
||||
use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
|
@ -23,15 +23,15 @@ extern "C" {
|
|||
pub fn PyInterpreterState_Delete(arg1: *mut PyInterpreterState);
|
||||
|
||||
#[cfg(all(Py_3_9, not(PyPy)))]
|
||||
#[cfg_attr(docsrs, doc(all(Py_3_9, not(PyPy))))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all(Py_3_9, not(PyPy)))))]
|
||||
pub fn PyInterpreterState_Get() -> *mut PyInterpreterState;
|
||||
|
||||
#[cfg(all(Py_3_8, not(PyPy)))]
|
||||
#[cfg_attr(docsrs, doc(all(Py_3_8, not(PyPy))))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all(Py_3_8, not(PyPy)))))]
|
||||
pub fn PyInterpreterState_GetDict(arg1: *mut PyInterpreterState) -> *mut PyObject;
|
||||
|
||||
#[cfg(all(Py_3_7, not(PyPy)))]
|
||||
#[cfg_attr(docsrs, doc(all(Py_3_7, not(PyPy))))]
|
||||
#[cfg_attr(docsrs, doc(cfg(all(Py_3_7, not(PyPy)))))]
|
||||
pub fn PyInterpreterState_GetID(arg1: *mut PyInterpreterState) -> i64;
|
||||
|
||||
#[cfg(not(PyPy))]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
//! Internals of PyO3 which are accessed by code expanded from PyO3's procedural macros. Usage of
|
||||
//! any of these APIs in downstream code is implicitly acknowledging that these APIs may change at
|
||||
//! any time without documentation in the CHANGELOG and without breaking semver guarantees.
|
||||
//! Internals of PyO3 which are accessed by code expanded from PyO3's procedural macros.
|
||||
//!
|
||||
//! Usage of any of these APIs in downstream code is implicitly acknowledging that these
|
||||
//! APIs may may change at any time without documentation in the CHANGELOG and without
|
||||
//! breaking semver guarantees.
|
||||
|
||||
pub mod deprecations;
|
||||
pub mod freelist;
|
||||
|
|
348
src/lib.rs
348
src/lib.rs
|
@ -1,11 +1,15 @@
|
|||
#![cfg_attr(feature = "nightly", feature(specialization))]
|
||||
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||
|
||||
#![deny(
|
||||
invalid_doc_attributes,
|
||||
rustdoc::broken_intra_doc_links,
|
||||
rustdoc::bare_urls
|
||||
)]
|
||||
//! Rust bindings to the Python interpreter.
|
||||
//!
|
||||
//! PyO3 can be used to write native Python modules or run Python code and modules from Rust.
|
||||
//!
|
||||
//! See [the guide](https://pyo3.rs/) for a detailed introduction.
|
||||
//! See [the guide] for a detailed introduction.
|
||||
//!
|
||||
//! # PyO3's object types
|
||||
//!
|
||||
|
@ -13,42 +17,38 @@
|
|||
//!
|
||||
//! ## The Python<'py> object
|
||||
//!
|
||||
//! Holding the [global interpreter lock](https://docs.python.org/3/glossary.html#term-global-interpreter-lock)
|
||||
//! (GIL) is modeled with the [`Python<'py>`](crate::Python) token.
|
||||
//! All APIs that require that the GIL is held require this token as proof
|
||||
//! that you really are holding the GIL. It can be explicitly acquired and
|
||||
//! is also implicitly acquired by PyO3 as it wraps Rust functions and structs
|
||||
//! into Python functions and objects.
|
||||
//! Holding the [global interpreter lock] (GIL) is modeled with the [`Python<'py>`] token. All APIs
|
||||
//! that require that the GIL is held require this token as proof that you really are holding the
|
||||
//! GIL. It can be explicitly acquired and is also implicitly acquired by PyO3 as it wraps Rust
|
||||
//! functions and structs into Python functions and objects.
|
||||
//!
|
||||
//! ## The GIL-dependent types
|
||||
//!
|
||||
//! For example `&`[`PyAny`](crate::types::PyAny).
|
||||
//! These are only ever seen as references, with a lifetime that is only valid for as long
|
||||
//! as the GIL is held, which is why using them doesn't require a [`Python<'py>`](crate::Python) token.
|
||||
//! The underlying Python object, if mutable, can be mutated through any reference.
|
||||
//! For example `&`[`PyAny`]. These are only ever seen as references, with a lifetime that is only
|
||||
//! valid for as long as the GIL is held, which is why using them doesn't require a [`Python<'py>`]
|
||||
//! token. The underlying Python object, if mutable, can be mutated through any reference.
|
||||
//!
|
||||
//! See the [guide](https://pyo3.rs/latest/types.html) for an explanation of the different Python object types.
|
||||
//! See the [guide][types] for an explanation of the different Python object types.
|
||||
//!
|
||||
//! ## The GIL-independent types
|
||||
//!
|
||||
//! When wrapped in [`Py`]`<...>`, like with [`Py`]`<`[`PyAny`](crate::types::PyAny)`>` or [`Py`]`<SomePyClass>`, Python objects
|
||||
//! no longer have a limited lifetime which makes them easier to store in structs and pass between functions.
|
||||
//! However, you cannot do much with them without a
|
||||
//! [`Python<'py>`](crate::Python) token, for which you’d need to reacquire the GIL.
|
||||
//! When wrapped in [`Py`]`<...>`, like with [`Py`]`<`[`PyAny`]`>` or [`Py`]`<SomePyClass>`, Python
|
||||
//! objects no longer have a limited lifetime which makes them easier to store in structs and pass
|
||||
//! between functions. However, you cannot do much with them without a [`Python<'py>`] token, for
|
||||
//! which you’d need to reacquire the GIL.
|
||||
//!
|
||||
//! ## PyErr
|
||||
//!
|
||||
//! The vast majority of operations in this library will return [`PyResult<...>`](PyResult).
|
||||
//! This is an alias for the type `Result<..., PyErr>`.
|
||||
//!
|
||||
//! A `PyErr` represents a Python exception. A `PyErr` returned to Python code will be raised as a Python exception.
|
||||
//! Errors from `PyO3` itself are also exposed as Python exceptions.
|
||||
//! A `PyErr` represents a Python exception. A `PyErr` returned to Python code will be raised as a
|
||||
//! Python exception. Errors from `PyO3` itself are also exposed as Python exceptions.
|
||||
//!
|
||||
//! # Feature flags
|
||||
//!
|
||||
//! PyO3 uses [feature flags](https://doc.rust-lang.org/cargo/reference/features.html)
|
||||
//! to enable you to opt-in to additional functionality. For a detailed description, see
|
||||
//! the [Features Reference chapter of the guide](https://pyo3.rs/latest/features.html#features-reference).
|
||||
//! PyO3 uses [feature flags] to enable you to opt-in to additional functionality.For a detailed
|
||||
//! description, see the [Features chapter of the guide].
|
||||
//!
|
||||
//! ## Default feature flags
|
||||
//!
|
||||
|
@ -57,63 +57,44 @@
|
|||
//!
|
||||
//! ## Optional feature flags
|
||||
//!
|
||||
//! The following features are optional:
|
||||
//! - `abi3`: Restricts PyO3's API to a subset of the full Python API which is guaranteed
|
||||
//! by [PEP 384](https://www.python.org/dev/peps/pep-0384/) to be forward-compatible with future Python versions.
|
||||
//! The following features customize PyO3's behavior:
|
||||
//!
|
||||
//! - `abi3`: Restricts PyO3's API to a subset of the full Python API which is guaranteed by
|
||||
//! [PEP 384] to be forward-compatible with future Python versions.
|
||||
//! - `auto-initialize`: Changes [`Python::with_gil`] and [`Python::acquire_gil`] to automatically
|
||||
//! initialize the Python interpreter if needed.
|
||||
//! - `extension-module`: This will tell the linker to keep the Python symbols unresolved, so that
|
||||
//! your module can also be used with statically linked Python interpreters. Use this feature when
|
||||
//! building an extension module.
|
||||
//! - `multiple-pymethods`: Enables the use of multiple [`#[pymethods]`] blocks per [`#[pyclass]`].
|
||||
//! This adds a dependency on the [inventory][inventory] crate, which is not supported on all
|
||||
//! platforms.
|
||||
//!
|
||||
//! The following features enable interactions with other crates in the Rust ecosystem:
|
||||
//
|
||||
//! - `auto-initialize`: Changes [`Python::with_gil`](crate::Python::with_gil) and
|
||||
//! [`Python::acquire_gil`](crate::Python::acquire_gil) to automatically initialize the
|
||||
//! Python interpreter if needed.
|
||||
//
|
||||
//! - `extension-module`: This will tell the linker to keep the Python symbols unresolved,
|
||||
//! so that your module can also be used with statically linked Python interpreters.
|
||||
//! Use this feature when building an extension module.
|
||||
//
|
||||
//! - [`hashbrown`](./hashbrown/index.html): Enables conversions between Python objects and
|
||||
//! [hashbrown](https://docs.rs/hashbrown)'s
|
||||
//! [`HashMap`](https://docs.rs/hashbrown/latest/hashbrown/struct.HashMap.html) and
|
||||
//! [`HashSet`](https://docs.rs/hashbrown/latest/hashbrown/struct.HashSet.html) types.
|
||||
//
|
||||
//! - [`indexmap`](./indexmap/index.html): Enables conversions between Python dictionary and
|
||||
//! [indexmap](https://docs.rs/indexmap)'s
|
||||
//! [`IndexMap`](https://docs.rs/indexmap/latest/indexmap/map/struct.IndexMap.html).
|
||||
//
|
||||
//! - `multiple-pymethods`: Enables the use of multiple
|
||||
//! [`#[pymethods]`](crate::proc_macro::pymethods) blocks per
|
||||
//! [`#[pyclass]`](crate::proc_macro::pyclass). This adds a dependency on the
|
||||
//! [`inventory`](https://docs.rs/inventory) crate, which is not supported on all platforms.
|
||||
//
|
||||
//! - [`num-bigint`](./num_bigint/index.html): Enables conversions between Python objects and
|
||||
//! [num-bigint](https://docs.rs/num-bigint)'s
|
||||
//! [`BigInt`](https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html) and
|
||||
//! [`BigUint`](https://docs.rs/num-bigint/latest/num_bigint/struct.BigUint.html) types.
|
||||
//
|
||||
//! - [`num-complex`](./num_complex/index.html): Enables conversions between Python objects and
|
||||
//! [num-complex](https://docs.rs/num-complex)'s
|
||||
//! [`Complex`](https://docs.rs/num-complex/latest/num_complex/struct.Complex.html) type.
|
||||
//
|
||||
//! - `serde`: Allows implementing [serde](https://docs.rs/serde)'s
|
||||
//! [`Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html) and
|
||||
//! [`Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html) traits for
|
||||
//! [`Py`]`<T>` for all `T` that implement
|
||||
//! [`Serialize`](https://docs.rs/serde/latest/serde/trait.Serialize.html) and
|
||||
//! [`Deserialize`](https://docs.rs/serde/latest/serde/trait.Deserialize.html).
|
||||
//! - [`hashbrown`]: Enables conversions between Python objects and [hashbrown]'s [`HashMap`] and
|
||||
//! [`HashSet`] types.
|
||||
//! - [`indexmap`]: Enables conversions between Python dictionary and [indexmap]'s [`IndexMap`].
|
||||
//! - [`num-bigint`]: Enables conversions between Python objects and [num-bigint]'s [`BigInt`] and
|
||||
//! [`BigUint`] types.
|
||||
//! - [`num-complex`]: Enables conversions between Python objects and [num-complex]'s [`Complex`]
|
||||
//! type.
|
||||
//! - [`serde`]: Allows implementing [serde]'s [`Serialize`] and [`Deserialize`] traits for
|
||||
//! [`Py`]`<T>` for all `T` that implement [`Serialize`] and [`Deserialize`].
|
||||
//!
|
||||
//! ## Unstable features
|
||||
//!
|
||||
//! - `nightly`: Gates some optimizations that rely on
|
||||
//! [`#![feature(specialization)]`](https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md),
|
||||
//! for which you'd also need nightly Rust. You should not use this feature.
|
||||
//! - `nightly`: Gates some optimizations that rely on [`#![feature(specialization)]`], for which
|
||||
//! you'd also need nightly Rust. You should not use this feature.
|
||||
//
|
||||
//! ## `rustc` environment flags
|
||||
//!
|
||||
//! PyO3 uses `rustc`'s `--cfg` flags to enable or disable code used for different Python versions.
|
||||
//! If you want to do this for your own crate, you can do so with the [`pyo3-build-config`](https://docs.rs/pyo3-build-config) crate.
|
||||
//! If you want to do this for your own crate, you can do so with the [`pyo3-build-config`] crate.
|
||||
//!
|
||||
//! - `Py_3_6`, `Py_3_7`, `Py_3_8`, `Py_3_9`, `Py_3_10`: Marks code that is only enabled when compiling for a given minimum Python version.
|
||||
//
|
||||
//! - `Py_3_6`, `Py_3_7`, `Py_3_8`, `Py_3_9`, `Py_3_10`: Marks code that is only enabled when
|
||||
//! compiling for a given minimum Python version.
|
||||
//! - `Py_LIMITED_API`: Marks code enabled when the `abi3` feature flag is enabled.
|
||||
//
|
||||
//! - `PyPy` - Marks code enabled when compiling for PyPy.
|
||||
//!
|
||||
//! # Minimum supported Rust and Python versions
|
||||
|
@ -125,10 +106,9 @@
|
|||
//! # Example: Building a native Python module
|
||||
//!
|
||||
//! PyO3 can be used to generate a native Python module. The easiest way to try this out for the
|
||||
//! first time is to use [`maturin`](https://github.com/PyO3/maturin). `maturin` is a tool for
|
||||
//! building and publishing Rust-based Python packages with minimal configuration. The following
|
||||
//! steps set up some files for an example Python module, install `maturin`, and then show how build
|
||||
//! and import the Python module.
|
||||
//! first time is to use [`maturin`]. `maturin` is a tool for building and publishing Rust-based
|
||||
//! Python packages with minimal configuration. The following steps set up some files for an example
|
||||
//! Python module, install `maturin`, and then show how build and import the Python module.
|
||||
//!
|
||||
//! First, create a new folder (let's call it `string_sum`) containing the following two files:
|
||||
//!
|
||||
|
@ -198,10 +178,9 @@
|
|||
//! '25'
|
||||
//! ```
|
||||
//!
|
||||
//! As well as with `maturin`, it is possible to build using
|
||||
//! [`setuptools-rust`](https://github.com/PyO3/setuptools-rust) or
|
||||
//! [manually](https://pyo3.rs/latest/building_and_distribution.html#manual-builds). Both offer more
|
||||
//! flexibility than `maturin` but require further configuration.
|
||||
//! As well as with `maturin`, it is possible to build using [setuptools-rust] or
|
||||
//! [manually][manual_builds]. Both offer more flexibility than `maturin` but require further
|
||||
//! configuration.
|
||||
//!
|
||||
//! # Example: Using Python from Rust
|
||||
//!
|
||||
|
@ -247,21 +226,54 @@
|
|||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! The guide has [a section](https://pyo3.rs/latest/python_from_rust.html) with lots of examples
|
||||
//! about this topic.
|
||||
//! The guide has [a section][calling_rust] with lots of examples about this topic.
|
||||
//!
|
||||
//! # Other Examples
|
||||
//!
|
||||
//! The PyO3 [README](https://github.com/PyO3/pyo3#readme) contains quick-start examples for both
|
||||
//! using [Rust from Python](https://github.com/PyO3/pyo3#using-rust-from-python) and
|
||||
//! [Python from Rust](https://github.com/PyO3/pyo3#using-python-from-rust).
|
||||
//! using [Rust from Python] and [Python from Rust].
|
||||
//!
|
||||
//! The PyO3 repository's [examples subdirectory](https://github.com/PyO3/pyo3/tree/main/examples)
|
||||
//! The PyO3 repository's [examples subdirectory]
|
||||
//! contains some basic packages to demonstrate usage of PyO3.
|
||||
//!
|
||||
//! There are many projects using PyO3 - see a list of some at
|
||||
//! <https://github.com/PyO3/pyo3#examples>
|
||||
|
||||
//! <https://github.com/PyO3/pyo3#examples>.
|
||||
//!
|
||||
//! [inventory]: https://docs.rs/inventory
|
||||
//! [`HashMap`]: https://docs.rs/hashbrown/latest/hashbrown/struct.HashMap.html
|
||||
//! [`HashSet`]: https://docs.rs/hashbrown/latest/hashbrown/struct.HashSet.html
|
||||
//! [`IndexMap`]: https://docs.rs/indexmap/latest/indexmap/map/struct.IndexMap.html
|
||||
//! [`BigInt`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigInt.html
|
||||
//! [`BigUint`]: https://docs.rs/num-bigint/latest/num_bigint/struct.BigUint.html
|
||||
//! [`Complex`]: https://docs.rs/num-complex/latest/num_complex/struct.Complex.html
|
||||
//! [`Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html
|
||||
//! [`Serialize`]: https://docs.rs/serde/latest/serde/trait.Serialize.html
|
||||
//! [`hashbrown`]: ./hashbrown/index.html
|
||||
//! [`indexmap`]: <./indexmap/index.html>
|
||||
//! [`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"
|
||||
//! [`num-bigint`]: ./num_bigint/index.html
|
||||
//! [`num-complex`]: ./num_complex/index.html
|
||||
//! [`pyo3-build-config`]: https://docs.rs/pyo3-build-config
|
||||
//! [`serde`]: <./serde/index.html>
|
||||
//! [calling_rust]: https://pyo3.rs/latest/python_from_rust.html "Calling Python from Rust - PyO3 user guide"
|
||||
//! [examples subdirectory]: https://github.com/PyO3/pyo3/tree/main/examples
|
||||
//! [feature flags]: https://doc.rust-lang.org/cargo/reference/features.html "Features - The Cargo Book"
|
||||
//! [global interpreter lock]: https://docs.python.org/3/glossary.html#term-global-interpreter-lock
|
||||
//! [hashbrown]: https://docs.rs/hashbrown
|
||||
//! [indexmap]: https://docs.rs/indexmap
|
||||
//! [manual_builds]: https://pyo3.rs/latest/building_and_distribution.html#manual-builds "Manual builds - Building and Distribution - PyO3 user guide"
|
||||
//! [num-bigint]: https://docs.rs/num-bigint
|
||||
//! [num-complex]: https://docs.rs/num-complex
|
||||
//! [serde]: https://docs.rs/serde
|
||||
//! [setuptools-rust]: https://github.com/PyO3/setuptools-rust "Setuptools plugin for Rust extensions"
|
||||
//! [the guide]: https://pyo3.rs "PyO3 user guide"
|
||||
//! [types]: https://pyo3.rs/latest/types.html "GIL lifetimes, mutability and Python object types"
|
||||
//! [PEP 384]: https://www.python.org/dev/peps/pep-0384 "PEP 384 -- Defining a Stable ABI"
|
||||
//! [Python from Rust]: https://github.com/PyO3/pyo3#using-python-from-rust
|
||||
//! [Rust from Python]: https://github.com/PyO3/pyo3#using-rust-from-python
|
||||
//! [`#![feature(specialization)]`]: <https://github.com/rust-lang/rfcs/blob/master/text/1210-impl-specialization.md>
|
||||
//! [Features chapter of the guide]: <https://pyo3.rs/latest/features.html#features-reference> "Features Reference - PyO3 user guide"
|
||||
//! [`#[pyclass]`]: macro@crate::pyclass
|
||||
pub use crate::class::*;
|
||||
pub use crate::conversion::{
|
||||
AsPyPointer, FromPyObject, FromPyPointer, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto,
|
||||
|
@ -278,7 +290,6 @@ pub use crate::pyclass::PyClass;
|
|||
pub use crate::pyclass_init::PyClassInitializer;
|
||||
pub use crate::python::{Python, PythonVersionInfo};
|
||||
pub use crate::type_object::PyTypeInfo;
|
||||
// Since PyAny is as important as PyObject, we expose it to the top level.
|
||||
pub use crate::types::PyAny;
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
|
@ -290,16 +301,13 @@ pub use {
|
|||
};
|
||||
|
||||
#[cfg(all(feature = "macros", feature = "multiple-pymethods"))]
|
||||
#[doc(hidden)]
|
||||
pub use inventory; // Re-exported for `#[pyclass]` and `#[pymethods]` with `multiple-pymethods`.
|
||||
|
||||
#[macro_use]
|
||||
mod internal_tricks;
|
||||
|
||||
// The CPython stable ABI does not include PyBuffer.
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
|
||||
pub mod buffer;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub mod callback;
|
||||
pub mod class;
|
||||
|
@ -312,13 +320,10 @@ mod err;
|
|||
pub mod exceptions;
|
||||
pub mod ffi;
|
||||
mod gil;
|
||||
#[doc(hidden)]
|
||||
pub mod impl_;
|
||||
mod instance;
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
|
||||
pub mod marshal;
|
||||
|
||||
pub mod once_cell;
|
||||
pub mod panic;
|
||||
pub mod prelude;
|
||||
|
@ -327,166 +332,27 @@ pub mod pyclass;
|
|||
pub mod pyclass_init;
|
||||
pub mod pyclass_slots;
|
||||
mod python;
|
||||
|
||||
pub mod type_object;
|
||||
pub mod types;
|
||||
|
||||
pub use crate::conversions::*;
|
||||
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
|
||||
#[cfg(feature = "serde")]
|
||||
pub mod serde;
|
||||
|
||||
/// The proc macros, all of which are part of the prelude.
|
||||
///
|
||||
/// Import these with `use pyo3::prelude::*;`
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
||||
#[doc(hidden)]
|
||||
#[deprecated(
|
||||
since = "0.15.0",
|
||||
note = "please import this with `use pyo3::...` or from the prelude instead"
|
||||
)]
|
||||
#[cfg(feature = "macros")]
|
||||
pub mod proc_macro {
|
||||
pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, pyproto};
|
||||
}
|
||||
|
||||
/// Returns a function that takes a [Python] instance and returns a Python function.
|
||||
///
|
||||
/// Use this together with `#[pyfunction]` and [types::PyModule::add_wrapped].
|
||||
#[macro_export]
|
||||
macro_rules! wrap_pyfunction {
|
||||
($function_name: ident) => {{
|
||||
&|py| $crate::paste::expr! { [<__pyo3_get_function_ $function_name>] }(py)
|
||||
}};
|
||||
|
||||
($function_name: ident, $arg: expr) => {
|
||||
$crate::wrap_pyfunction!($function_name)(
|
||||
<$crate::derive_utils::PyFunctionArguments as ::std::convert::From<_>>::from($arg),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns a function that takes a [Python] instance and returns a Python module.
|
||||
///
|
||||
/// Use this together with `#[pymodule]` and [types::PyModule::add_wrapped].
|
||||
#[macro_export]
|
||||
macro_rules! wrap_pymodule {
|
||||
($module_name:ident) => {{
|
||||
$crate::paste::expr! {
|
||||
&|py| unsafe { $crate::PyObject::from_owned_ptr(py, [<PyInit_ $module_name>]()) }
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// A convenient macro to execute a Python code snippet, with some local variables set.
|
||||
///
|
||||
/// # Panics
|
||||
/// This macro internally calls [`Python::run`](struct.Python.html#method.run) and panics
|
||||
/// if it returns `Err`, after printing the error to stdout.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use pyo3::{prelude::*, py_run, types::PyList};
|
||||
/// Python::with_gil(|py| {
|
||||
/// let list = PyList::new(py, &[1, 2, 3]);
|
||||
/// py_run!(py, list, "assert list == [1, 2, 3]");
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// You can use this macro to test pyfunctions or pyclasses quickly.
|
||||
///
|
||||
/// ```
|
||||
/// use pyo3::{prelude::*, py_run, PyCell};
|
||||
/// #[pyclass]
|
||||
/// #[derive(Debug)]
|
||||
/// struct Time {
|
||||
/// hour: u32,
|
||||
/// minute: u32,
|
||||
/// second: u32,
|
||||
/// }
|
||||
/// #[pymethods]
|
||||
/// impl Time {
|
||||
/// fn repl_japanese(&self) -> String {
|
||||
/// format!("{}時{}分{}秒", self.hour, self.minute, self.second)
|
||||
/// }
|
||||
/// #[getter]
|
||||
/// fn hour(&self) -> u32 {
|
||||
/// self.hour
|
||||
/// }
|
||||
/// fn as_tuple(&self) -> (u32, u32, u32) {
|
||||
/// (self.hour, self.minute, self.second)
|
||||
/// }
|
||||
/// }
|
||||
/// Python::with_gil(|py| {
|
||||
/// let time = PyCell::new(py, Time {hour: 8, minute: 43, second: 16}).unwrap();
|
||||
/// let time_as_tuple = (8, 43, 16);
|
||||
/// py_run!(py, time time_as_tuple, r#"
|
||||
/// assert time.hour == 8
|
||||
/// assert time.repl_japanese() == "8時43分16秒"
|
||||
/// assert time.as_tuple() == time_as_tuple
|
||||
/// "#);
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// If you need to prepare the `locals` dict by yourself, you can pass it as `*locals`.
|
||||
///
|
||||
/// ```
|
||||
/// use pyo3::prelude::*;
|
||||
/// use pyo3::types::IntoPyDict;
|
||||
/// #[pyclass]
|
||||
/// struct MyClass {}
|
||||
/// #[pymethods]
|
||||
/// impl MyClass {
|
||||
/// #[new]
|
||||
/// fn new() -> Self { MyClass {} }
|
||||
/// }
|
||||
/// Python::with_gil(|py| {
|
||||
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict(py);
|
||||
/// pyo3::py_run!(py, *locals, "c = C()");
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// **Note**
|
||||
/// Since this macro is intended to use for testing, it **causes panic** when
|
||||
/// [Python::run] returns `Err` internally.
|
||||
/// If you need to handle failures, please use [Python::run] directly.
|
||||
///
|
||||
#[macro_export]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
||||
#[cfg(feature = "macros")]
|
||||
macro_rules! py_run {
|
||||
($py:expr, $($val:ident)+, $code:literal) => {{
|
||||
$crate::py_run_impl!($py, $($val)+, $crate::indoc::indoc!($code))
|
||||
}};
|
||||
($py:expr, $($val:ident)+, $code:expr) => {{
|
||||
$crate::py_run_impl!($py, $($val)+, &$crate::unindent::unindent($code))
|
||||
}};
|
||||
($py:expr, *$dict:expr, $code:literal) => {{
|
||||
$crate::py_run_impl!($py, *$dict, $crate::indoc::indoc!($code))
|
||||
}};
|
||||
($py:expr, *$dict:expr, $code:expr) => {{
|
||||
$crate::py_run_impl!($py, *$dict, &$crate::unindent::unindent($code))
|
||||
}};
|
||||
}
|
||||
pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, pyproto};
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "macros")]
|
||||
macro_rules! py_run_impl {
|
||||
($py:expr, $($val:ident)+, $code:expr) => {{
|
||||
use $crate::types::IntoPyDict;
|
||||
use $crate::ToPyObject;
|
||||
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
|
||||
$crate::py_run_impl!($py, *d, $code)
|
||||
}};
|
||||
($py:expr, *$dict:expr, $code:expr) => {{
|
||||
use ::std::option::Option::*;
|
||||
if let ::std::result::Result::Err(e) = $py.run($code, None, Some($dict)) {
|
||||
e.print($py);
|
||||
// So when this c api function the last line called printed the error to stderr,
|
||||
// the output is only written into a buffer which is never flushed because we
|
||||
// panic before flushing. This is where this hack comes into place
|
||||
$py.run("import sys; sys.stderr.flush()", None, None)
|
||||
.unwrap();
|
||||
::std::panic!("{}", $code)
|
||||
}
|
||||
}};
|
||||
}
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
/// Test readme and user guide
|
||||
#[cfg(doctest)]
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/// Wraps a Rust function annotated with [`#[pyfunction]`](crate::pyfunction), turning it into a
|
||||
/// [`PyCFunction`](crate::types::PyCFunction).
|
||||
///
|
||||
/// This can be used with [`PyModule::add_function`](crate::types::PyModule::add_function) to add
|
||||
/// free functions to a [`PyModule`](crate::types::PyModule) - see its documention for more information.
|
||||
#[macro_export]
|
||||
macro_rules! wrap_pyfunction {
|
||||
($function_name: ident) => {{
|
||||
&|py| $crate::paste::expr! { [<__pyo3_get_function_ $function_name>] }(py)
|
||||
}};
|
||||
|
||||
($function_name: ident, $arg: expr) => {
|
||||
$crate::wrap_pyfunction!($function_name)(
|
||||
<$crate::derive_utils::PyFunctionArguments as ::std::convert::From<_>>::from($arg),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// Returns a function that takes a [`Python`](crate::python::Python) instance and returns a Python module.
|
||||
///
|
||||
/// Use this together with [`#[pymodule]`](crate::pymodule) and [crate::types::PyModule::add_wrapped].
|
||||
#[macro_export]
|
||||
macro_rules! wrap_pymodule {
|
||||
($module_name:ident) => {{
|
||||
$crate::paste::expr! {
|
||||
&|py| unsafe { $crate::PyObject::from_owned_ptr(py, [<PyInit_ $module_name>]()) }
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
/// A convenient macro to execute a Python code snippet, with some local variables set.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This macro internally calls [`Python::run`](crate::Python::run) and panics
|
||||
/// if it returns `Err`, after printing the error to stdout.
|
||||
///
|
||||
/// If you need to handle failures, please use [`Python::run`](crate::python::Python::run) instead.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
/// use pyo3::{prelude::*, py_run, types::PyList};
|
||||
///
|
||||
/// Python::with_gil(|py| {
|
||||
/// let list = PyList::new(py, &[1, 2, 3]);
|
||||
/// py_run!(py, list, "assert list == [1, 2, 3]");
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// You can use this macro to test pyfunctions or pyclasses quickly.
|
||||
///
|
||||
/// ```
|
||||
/// use pyo3::{prelude::*, py_run, PyCell};
|
||||
///
|
||||
/// #[pyclass]
|
||||
/// #[derive(Debug)]
|
||||
/// struct Time {
|
||||
/// hour: u32,
|
||||
/// minute: u32,
|
||||
/// second: u32,
|
||||
/// }
|
||||
///
|
||||
/// #[pymethods]
|
||||
/// impl Time {
|
||||
/// fn repl_japanese(&self) -> String {
|
||||
/// format!("{}時{}分{}秒", self.hour, self.minute, self.second)
|
||||
/// }
|
||||
/// #[getter]
|
||||
/// fn hour(&self) -> u32 {
|
||||
/// self.hour
|
||||
/// }
|
||||
/// fn as_tuple(&self) -> (u32, u32, u32) {
|
||||
/// (self.hour, self.minute, self.second)
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// Python::with_gil(|py| {
|
||||
/// let time = PyCell::new(py, Time {hour: 8, minute: 43, second: 16}).unwrap();
|
||||
/// let time_as_tuple = (8, 43, 16);
|
||||
/// py_run!(py, time time_as_tuple, r#"
|
||||
/// assert time.hour == 8
|
||||
/// assert time.repl_japanese() == "8時43分16秒"
|
||||
/// assert time.as_tuple() == time_as_tuple
|
||||
/// "#);
|
||||
/// });
|
||||
/// ```
|
||||
///
|
||||
/// If you need to prepare the `locals` dict by yourself, you can pass it as `*locals`.
|
||||
///
|
||||
/// ```
|
||||
/// use pyo3::prelude::*;
|
||||
/// use pyo3::types::IntoPyDict;
|
||||
///
|
||||
/// #[pyclass]
|
||||
/// struct MyClass;
|
||||
///
|
||||
/// #[pymethods]
|
||||
/// impl MyClass {
|
||||
/// #[new]
|
||||
/// fn new() -> Self { MyClass {} }
|
||||
/// }
|
||||
///
|
||||
/// Python::with_gil(|py| {
|
||||
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict(py);
|
||||
/// pyo3::py_run!(py, *locals, "c = C()");
|
||||
/// });
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[cfg(feature = "macros")]
|
||||
macro_rules! py_run {
|
||||
($py:expr, $($val:ident)+, $code:literal) => {{
|
||||
$crate::py_run_impl!($py, $($val)+, $crate::indoc::indoc!($code))
|
||||
}};
|
||||
($py:expr, $($val:ident)+, $code:expr) => {{
|
||||
$crate::py_run_impl!($py, $($val)+, &$crate::unindent::unindent($code))
|
||||
}};
|
||||
($py:expr, *$dict:expr, $code:literal) => {{
|
||||
$crate::py_run_impl!($py, *$dict, $crate::indoc::indoc!($code))
|
||||
}};
|
||||
($py:expr, *$dict:expr, $code:expr) => {{
|
||||
$crate::py_run_impl!($py, *$dict, &$crate::unindent::unindent($code))
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
#[cfg(feature = "macros")]
|
||||
macro_rules! py_run_impl {
|
||||
($py:expr, $($val:ident)+, $code:expr) => {{
|
||||
use $crate::types::IntoPyDict;
|
||||
use $crate::ToPyObject;
|
||||
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
|
||||
$crate::py_run_impl!($py, *d, $code)
|
||||
}};
|
||||
($py:expr, *$dict:expr, $code:expr) => {{
|
||||
use ::std::option::Option::*;
|
||||
if let ::std::result::Result::Err(e) = $py.run($code, None, Some($dict)) {
|
||||
e.print($py);
|
||||
// So when this c api function the last line called printed the error to stderr,
|
||||
// the output is only written into a buffer which is never flushed because we
|
||||
// panic before flushing. This is where this hack comes into place
|
||||
$py.run("import sys; sys.stderr.flush()", None, None)
|
||||
.unwrap();
|
||||
::std::panic!("{}", $code)
|
||||
}
|
||||
}};
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#![cfg(not(Py_LIMITED_API))]
|
||||
//! Support for the Python `marshal` format. Not supported in limited API
|
||||
//! builds.
|
||||
#![cfg_attr(docsrs, doc(cfg(not(Py_LIMITED_API))))]
|
||||
//! Support for the Python `marshal` format.
|
||||
|
||||
use crate::ffi;
|
||||
use crate::types::{PyAny, PyBytes};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// Copyright (c) 2017-present PyO3 Project and Contributors
|
||||
|
||||
//! A collection of items you most likely want to have in scope when working with pyo3
|
||||
//! PyO3's prelude.
|
||||
//!
|
||||
//! The purpose of this module is to alleviate imports of many common pyo3 traits
|
||||
//! The purpose of this module is to alleviate imports of many commonly used items of the PyO3 crate
|
||||
//! by adding a glob import to the top of pyo3 heavy modules:
|
||||
//!
|
||||
//! ```
|
||||
|
@ -16,9 +16,10 @@ pub use crate::instance::{Py, PyObject};
|
|||
pub use crate::pycell::{PyCell, PyRef, PyRefMut};
|
||||
pub use crate::pyclass_init::PyClassInitializer;
|
||||
pub use crate::python::Python;
|
||||
pub use crate::{FromPyObject, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto, ToPyObject};
|
||||
// PyModule is only part of the prelude because we need it for the pymodule function
|
||||
pub use crate::types::{PyAny, PyModule};
|
||||
pub use crate::wrap_pyfunction;
|
||||
pub use crate::{FromPyObject, IntoPy, IntoPyPointer, PyTryFrom, PyTryInto, ToPyObject};
|
||||
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
|
||||
#[cfg(feature = "macros")]
|
||||
pub use {crate::proc_macro::*, pyo3_macros::FromPyObject};
|
||||
pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, pyproto, FromPyObject};
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
//! Includes `PyCell` implementation.
|
||||
//! PyO3's interior mutability primitive.
|
||||
//!
|
||||
//! For more information see the [guide](https://pyo3.rs/latest/class.html?highlight=pycell#pycell-and-interior-mutability "PyCell and interior mutability")
|
||||
|
||||
use crate::exceptions::PyRuntimeError;
|
||||
use crate::pyclass::PyClass;
|
||||
use crate::pyclass_init::PyClassInitializer;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//! Initialization utilities for `#[pyclass]`.
|
||||
//! Contains initialization utilities for `#[pyclass]`.
|
||||
use crate::class::impl_::PyClassThreadChecker;
|
||||
use crate::pyclass_slots::{PyClassDict, PyClassWeakRef};
|
||||
use crate::{callback::IntoPyCallbackOutput, class::impl_::PyClassBaseType};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//! This module contains additional fields for `#[pyclass]`.
|
||||
//! Contains additional fields for `#[pyclass]`.
|
||||
//!
|
||||
//! Mainly used by PyO3's proc-macro code.
|
||||
use crate::{ffi, Python};
|
||||
|
||||
|
|
|
@ -21,14 +21,14 @@ enum Derive4 {
|
|||
B { f: i32 },
|
||||
} // enum case
|
||||
|
||||
#[::pyo3::proc_macro::pyclass]
|
||||
#[::pyo3::pyclass]
|
||||
#[derive(::std::clone::Clone)]
|
||||
pub struct Foo;
|
||||
|
||||
#[::pyo3::proc_macro::pyclass]
|
||||
#[::pyo3::pyclass]
|
||||
pub struct Foo2;
|
||||
|
||||
#[::pyo3::proc_macro::pyclass(
|
||||
#[::pyo3::pyclass(
|
||||
name = "ActuallyBar",
|
||||
freelist = 8,
|
||||
weakref,
|
||||
|
@ -47,7 +47,7 @@ pub struct Bar {
|
|||
c: ::std::option::Option<::pyo3::Py<Foo2>>,
|
||||
}
|
||||
|
||||
#[::pyo3::proc_macro::pymethods]
|
||||
#[::pyo3::pymethods]
|
||||
impl Bar {
|
||||
#[args(x = "1", "*", _z = "2")]
|
||||
fn test(&self, _y: &Bar, _z: i32) {}
|
||||
|
@ -84,7 +84,7 @@ impl Bar {
|
|||
}
|
||||
}
|
||||
|
||||
#[::pyo3::proc_macro::pyproto]
|
||||
#[::pyo3::pyproto]
|
||||
impl ::pyo3::class::gc::PyGCProtocol for Bar {
|
||||
fn __traverse__(
|
||||
&self,
|
||||
|
@ -102,7 +102,7 @@ impl ::pyo3::class::gc::PyGCProtocol for Bar {
|
|||
}
|
||||
|
||||
#[cfg(not(Py_LIMITED_API))]
|
||||
#[::pyo3::proc_macro::pyproto]
|
||||
#[::pyo3::pyproto]
|
||||
impl ::pyo3::class::PyBufferProtocol for Bar {
|
||||
fn bf_getbuffer(
|
||||
_s: ::pyo3::PyRefMut<Self>,
|
||||
|
@ -114,12 +114,12 @@ impl ::pyo3::class::PyBufferProtocol for Bar {
|
|||
fn bf_releasebuffer(_s: ::pyo3::PyRefMut<Self>, _v: *mut ::pyo3::ffi::Py_buffer) {}
|
||||
}
|
||||
|
||||
#[::pyo3::proc_macro::pyfunction]
|
||||
#[::pyo3::pyfunction]
|
||||
fn do_something(x: i32) -> ::pyo3::PyResult<i32> {
|
||||
::std::result::Result::Ok(x)
|
||||
}
|
||||
|
||||
#[::pyo3::proc_macro::pymodule]
|
||||
#[::pyo3::pymodule]
|
||||
fn my_module(_py: ::pyo3::Python, m: &::pyo3::types::PyModule) -> ::pyo3::PyResult<()> {
|
||||
m.add_function(::pyo3::wrap_pyfunction!(do_something, m)?)?;
|
||||
::std::result::Result::Ok(())
|
||||
|
|
Loading…
Reference in New Issue