This commit is contained in:
David Hewitt 2022-03-22 10:38:36 +00:00
parent 5cc3ce99f1
commit 49c1d22606
4 changed files with 50 additions and 54 deletions

View File

@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Changed
- Allow `#[pyo3(crate = "...", text_signature = "...")]` options to be used directly in `#[pyclass(crate = "...", text_signature = "...")]`. [#2234](https://github.com/PyO3/pyo3/pull/2234)
### Fixed
- Considered `PYTHONFRAMEWORK` when cross compiling in order that on macos cross compiling against a [Framework bundle](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html) is considered shared. [#2233](https://github.com/PyO3/pyo3/pull/2233)

View File

@ -195,22 +195,16 @@ Python::with_gil(|py|{
## Customizing the class
The `#[pyclass]` macro accepts the following parameters:
{{#include ../../pyo3-macros/docs/pyclass_parameters.md}}
* `name="XXX"` - Set the class name shown in Python code. By default, the struct name is used as the class name.
* `freelist=XXX` - The `freelist` parameter adds support of free allocation list to custom class.
The performance improvement applies to types that are often created and deleted in a row,
so that they can benefit from a freelist. `XXX` is a number of items for the free list.
* `gc` - Classes with the `gc` parameter participate in Python garbage collection.
If a custom class contains references to other Python objects that can be collected, the [`PyGCProtocol`]({{#PYO3_DOCS_URL}}/pyo3/class/gc/trait.PyGCProtocol.html) trait has to be implemented.
* `weakref` - Adds support for Python weak references.
* `extends=BaseType` - Use a custom base class. The base `BaseType` must implement `PyTypeInfo`. `enum` pyclasses can't use a custom base class.
* `subclass` - Allows Python classes to inherit from this class. `enum` pyclasses can't be inherited from.
* `dict` - Adds `__dict__` support, so that the instances of this type have a dictionary containing arbitrary instance variables.
* `unsendable` - Making it safe to expose `!Send` structs to Python, where all object can be accessed
by multiple threads. A class marked with `unsendable` panics when accessed by another thread.
* `module="XXX"` - Set the name of the module the class will be shown as defined in. If not given, the class
will be a virtual member of the `builtins` module.
[params-1]: {{#PYO3_DOCS_URL}}/pyo3/prelude/struct.PyAny.html
[params-2]: https://en.wikipedia.org/wiki/Free_list
[params-3]: https://doc.rust-lang.org/stable/std/marker/trait.Send.html
[params-4]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html
[params-5]: https://doc.rust-lang.org/stable/std/sync/struct.Rc.html
[params-6]: https://docs.python.org/3/library/weakref.html
These parameters are covered in various sections of this guide.
### Return type
@ -716,7 +710,7 @@ num=-1
## Making class method signatures available to Python
The [`#[pyo3(text_signature = "...")]`](./function.md#text_signature) option for `#[pyfunction]` also works for classes and methods:
The [`text_signature = "..."`](./function.md#text_signature) option for `#[pyfunction]` also works for classes and methods:
```rust
# #![allow(dead_code)]
@ -724,8 +718,7 @@ use pyo3::prelude::*;
use pyo3::types::PyType;
// it works even if the item is not documented:
#[pyclass]
#[pyo3(text_signature = "(c, d, /)")]
#[pyclass(text_signature = "(c, d, /)")]
struct MyClass {}
#[pymethods]

View File

@ -0,0 +1,28 @@
`#[pyclass]` can be used with the following parameters:
| Parameter | Description |
| :- | :- |
| <span style="white-space: pre">`crate = "some::path"`</span> | Path to import the `pyo3` crate, if it's not accessible at `::pyo3`. |
| `dict` | Gives instances of this class an empty `__dict__` to store custom attributes. |
| <span style="white-space: pre">`extends = BaseType`</span> | Use a custom baseclass. Defaults to [`PyAny`][params-1] |
| <span style="white-space: pre">`freelist = N`</span> | 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. |
| <span style="white-space: pre">`module = "module_name"`</span> | Python code will see the class as being defined in this module. Defaults to `builtins`. |
| <span style="white-space: pre">`name = "python_name"`</span> | Sets the name that Python sees this class as. Defaults to the name of the Rust struct. |
| <span style="white-space: pre">`text_signature = "(arg1, arg2, ...)"`</span> | Sets the text signature for the Python class' `__new__` method. |
| `subclass` | Allows other Python classes and `#[pyclass]` to inherit from this class. Enums cannot be subclassed. |
| `unsendable` | Required if your struct is not [`Send`][params-3]. Rather than using `unsendable`, consider implementing your struct in a threadsafe way by e.g. substituting [`Rc`][params-4] with [`Arc`][params-5]. By using `unsendable`, your class will panic when accessed by another thread.|
| `weakref` | Allows this class to be [weakly referenceable][params-6]. |
All of these parameters can either be passed directly on the `#[pyclass(...)]` annotation, or as one or
more accompanying `#[pyo3(...)]` annotations, e.g.:
```rust,ignore
// Argument supplied directly to the `#[pyclass]` annotation.
#[pyclass(name = "SomeName", subclass)]
struct MyClass { }
// Argument supplied as a separate annotation.
#[pyclass]
#[pyo3(name = "SomeName", subclass)]
struct MyClass { }
```

View File

@ -81,47 +81,18 @@ pub fn pyproto(_: TokenStream, input: TokenStream) -> TokenStream {
/// A proc macro used to expose Rust structs and fieldless enums as Python objects.
///
/// `#[pyclass]` can be used the following [parameters][2]:
///
/// | Parameter | Description |
/// | :- | :- |
/// | <span style="white-space: pre">`crate = "some::path"`</span> | Path to import the `pyo3` crate, if it's not accessible at `::pyo3`. |
/// | `dict` | Gives instances of this class an empty `__dict__` to store custom attributes. |
/// | <span style="white-space: pre">`extends = BaseType`</span> | Use a custom baseclass. Defaults to [`PyAny`][4] |
/// | <span style="white-space: pre">`freelist = N`</span> | Implements a [free list][9] 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. |
/// | <span style="white-space: pre">`module = "module_name"`</span> | Python code will see the class as being defined in this module. Defaults to `builtins`. |
/// | <span style="white-space: pre">`name = "python_name"`</span> | Sets the name that Python sees this class as. Defaults to the name of the Rust struct. |
/// | <span style="white-space: pre">`text_signature = "(arg1, arg2, ...)"`</span> | Sets the text signature for the Python class' `__new__` method. |
/// | `subclass` | Allows other Python classes and `#[pyclass]` to inherit from this class. Enums cannot be subclassed. |
/// | `unsendable` | Required if your struct is not [`Send`][3]. Rather than using `unsendable`, consider implementing your struct in a threadsafe way by e.g. substituting [`Rc`][7] with [`Arc`][8]. By using `unsendable`, your class will panic when accessed by another thread.|
/// | `weakref` | Allows this class to be [weakly referenceable][6]. |
///
/// All of these parameters can either be passed directly on the `#[pyclass(...)]` annotation, or as one or
/// more accompanying `#[pyo3(...)]` annotations, e.g.:
///
/// ```rust,ignore
/// // Argument supplied directly to the `#[pyclass]` annotation.
/// #[pyclass(name = "SomeName", subclass)]
/// struct MyClass { }
///
/// // Argument supplied as a separate annotation.
/// #[pyclass]
/// #[pyo3(name = "SomeName", subclass)]
/// struct MyClass { }
/// ```
#[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
/// [2]: https://pyo3.rs/latest/class.html#customizing-the-class
/// [3]: std::marker::Send
/// [4]: ../prelude/struct.PyAny.html
/// [5]: https://pyo3.rs/latest/class/protocols.html#garbage-collector-integration
/// [6]: https://docs.python.org/3/library/weakref.html
/// [7]: std::rc::Rc
/// [8]: std::sync::Arc
/// [9]: https://en.wikipedia.org/wiki/Free_list
/// [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
#[proc_macro_attribute]
pub fn pyclass(attr: TokenStream, input: TokenStream) -> TokenStream {
use syn::Item;