From e4e7e6e51cae0cac3b422e4267bbf8ce67c6fea7 Mon Sep 17 00:00:00 2001 From: mejrs <> Date: Wed, 22 Jun 2022 01:47:40 +0200 Subject: [PATCH] Add frozen documentation --- .../docs => guide}/pyclass_parameters.md | 9 +++++++++ guide/src/class.md | 2 +- pyo3-macros/src/lib.rs | 15 --------------- src/lib.rs | 13 ++++++++++++- src/pyclass.rs | 19 +++++++++++-------- 5 files changed, 33 insertions(+), 25 deletions(-) rename {pyo3-macros/docs => guide}/pyclass_parameters.md (79%) diff --git a/pyo3-macros/docs/pyclass_parameters.md b/guide/pyclass_parameters.md similarity index 79% rename from pyo3-macros/docs/pyclass_parameters.md rename to guide/pyclass_parameters.md index 145d5ac8..87d81c94 100644 --- a/pyo3-macros/docs/pyclass_parameters.md +++ b/guide/pyclass_parameters.md @@ -6,6 +6,7 @@ | `dict` | Gives instances of this class an empty `__dict__` to store custom attributes. | | `extends = BaseType` | Use a custom baseclass. Defaults to [`PyAny`][params-1] | | `freelist = N` | Implements a [free list][params-2] of size N. This can improve performance for types that are often created and deleted in quick succession. Profile your code to see whether `freelist` is right for you. | +| `frozen` | Declares that your pyclass is immutable. It removes the borrowchecker overhead when retrieving a shared reference to the Rust struct, but disables the ability to get a mutable reference. | | `mapping` | Inform PyO3 that this class is a [`Mapping`][params-mapping], and so leave its implementation of sequence C-API slots empty. | | `module = "module_name"` | Python code will see the class as being defined in this module. Defaults to `builtins`. | | `name = "python_name"` | Sets the name that Python sees this class as. Defaults to the name of the Rust struct. | @@ -27,3 +28,11 @@ struct MyClass { } #[pyo3(name = "SomeName", subclass)] struct MyClass { } ``` + +[params-1]: ../prelude/struct.PyAny.html +[params-2]: https://en.wikipedia.org/wiki/Free_list +[params-3]: std::marker::Send +[params-4]: std::rc::Rc +[params-5]: std::sync::Arc +[params-6]: https://docs.python.org/3/library/weakref.html +[params-mapping]: https://pyo3.rs/latest/class/protocols.html#mapping--sequence-types \ No newline at end of file diff --git a/guide/src/class.md b/guide/src/class.md index 7124114a..cff3c51e 100644 --- a/guide/src/class.md +++ b/guide/src/class.md @@ -195,7 +195,7 @@ Python::with_gil(|py|{ ## Customizing the class -{{#include ../../pyo3-macros/docs/pyclass_parameters.md}} +{{#include ../pyclass_parameters.md}} [params-1]: {{#PYO3_DOCS_URL}}/pyo3/prelude/struct.PyAny.html [params-2]: https://en.wikipedia.org/wiki/Free_list diff --git a/pyo3-macros/src/lib.rs b/pyo3-macros/src/lib.rs index 65f85b55..33adcf86 100644 --- a/pyo3-macros/src/lib.rs +++ b/pyo3-macros/src/lib.rs @@ -79,21 +79,6 @@ pub fn pyproto(_: TokenStream, input: TokenStream) -> TokenStream { .into() } -/// A proc macro used to expose Rust structs and fieldless enums as Python objects. -/// -#[cfg_attr(docsrs, cfg_attr(docsrs, doc = include_str!("../docs/pyclass_parameters.md")))] -/// -/// For more on creating Python classes, -/// see the [class section of the guide][1]. -/// -/// [1]: https://pyo3.rs/latest/class.html -/// [params-1]: ../prelude/struct.PyAny.html -/// [params-2]: https://en.wikipedia.org/wiki/Free_list -/// [params-3]: std::marker::Send -/// [params-4]: std::rc::Rc -/// [params-5]: std::sync::Arc -/// [params-6]: https://docs.python.org/3/library/weakref.html -/// [params-mapping]: https://pyo3.rs/latest/class/protocols.html#mapping--sequence-types #[proc_macro_attribute] pub fn pyclass(attr: TokenStream, input: TokenStream) -> TokenStream { use syn::Item; diff --git a/src/lib.rs b/src/lib.rs index 8f7741ff..ca87bf2c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -405,7 +405,18 @@ pub mod proc_macro { #[cfg(all(feature = "macros", feature = "pyproto"))] pub use pyo3_macros::pyproto; #[cfg(feature = "macros")] -pub use pyo3_macros::{pyclass, pyfunction, pymethods, pymodule, FromPyObject}; +pub use pyo3_macros::{pyfunction, pymethods, pymodule, FromPyObject}; + +/// A proc macro used to expose Rust structs and fieldless enums as Python objects. +/// +#[cfg_attr(docsrs, cfg_attr(docsrs, doc = include_str!("../guide/pyclass_parameters.md")))] +/// +/// For more on creating Python classes, +/// see the [class section of the guide][1]. +/// +/// [1]: https://pyo3.rs/latest/class.html +#[cfg(feature = "macros")] +pub use pyo3_macros::pyclass; #[cfg(feature = "macros")] #[macro_use] diff --git a/src/pyclass.rs b/src/pyclass.rs index f7bbb0cd..4272471e 100644 --- a/src/pyclass.rs +++ b/src/pyclass.rs @@ -16,15 +16,16 @@ use std::{ ptr, }; -/// If `PyClass` is implemented for a Rust type `T`, then we can use `T` in the Python -/// world, via `PyCell`. +/// Types that can be used as Python classes. /// -/// The `#[pyclass]` attribute automatically implements this trait for your Rust struct, -/// so you normally don't have to use this trait directly. +/// The `#[pyclass]` attribute implements this trait for your Rust struct - +/// you shouldn't implement this trait directly. pub trait PyClass: PyTypeInfo> + PyClassImpl> { - /// Frozen or not + /// Whether the pyclass is frozen. + /// + /// This can be enabled via `#[pyclass(frozen)]`. type Frozen: Frozen; } @@ -574,10 +575,11 @@ pub(crate) unsafe extern "C" fn no_constructor_defined( }) } -/// A mechanism to have associated True / False values in the absence of -/// associated const equality. +/// A workaround for [associated const equality](https://github.com/rust-lang/rust/issues/92827). +/// +/// This serves to have True / False values in the [`PyClass`] trait's `Frozen` type. +#[doc(hidden)] pub mod boolean_struct { - pub(crate) mod private { use super::*; @@ -593,6 +595,7 @@ pub mod boolean_struct { } /// A trait which is used to describe whether a `#[pyclass]` is frozen. +#[doc(hidden)] pub trait Frozen: boolean_struct::private::Boolean {} impl Frozen for boolean_struct::True {}