You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: guide/src/class.md
+97-10Lines changed: 97 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,7 +2,7 @@
2
2
3
3
PyO3 exposes a group of attributes powered by Rust's proc macro system for defining Python classes as Rust structs.
4
4
5
-
The main attribute is `#[pyclass]`, which is placed upon a Rust `struct` or a fieldless `enum` (a.k.a. C-like enum) to generate a Python type for it. They will usually also have *one*`#[pymethods]`-annotated `impl` block for the struct, which is used to define Python methods and constants for the generated Python type. (If the [`multiple-pymethods`] feature is enabled, each `#[pyclass]` is allowed to have multiple `#[pymethods]` blocks.) `#[pymethods]` may also have implementations for Python magic methods such as `__str__`.
5
+
The main attribute is `#[pyclass]`, which is placed upon a Rust `struct` or `enum` to generate a Python type for it. They will usually also have *one*`#[pymethods]`-annotated `impl` block for the struct, which is used to define Python methods and constants for the generated Python type. (If the [`multiple-pymethods`] feature is enabled, each `#[pyclass]` is allowed to have multiple `#[pymethods]` blocks.) `#[pymethods]` may also have implementations for Python magic methods such as `__str__`.
6
6
7
7
This chapter will discuss the functionality and configuration these attributes offer. Below is a list of links to the relevant section of this chapter for each:
8
8
@@ -21,21 +21,29 @@ This chapter will discuss the functionality and configuration these attributes o
21
21
22
22
## Defining a new class
23
23
24
-
To define a custom Python class, add the `#[pyclass]` attribute to a Rust struct or a fieldless enum.
24
+
To define a custom Python class, add the `#[pyclass]` attribute to a Rust struct or enum.
25
25
```rust
26
26
# #![allow(dead_code)]
27
27
usepyo3::prelude::*;
28
28
29
29
#[pyclass]
30
-
structInteger {
30
+
structMyClass {
31
31
inner:i32,
32
32
}
33
33
34
34
// A "tuple" struct
35
35
#[pyclass]
36
36
structNumber(i32);
37
37
38
-
// PyO3 supports custom discriminants in enums
38
+
// PyO3 supports unit-only enums (which contain only unit variants)
39
+
// These simple enums behave similarly to Python's enumerations (enum.Enum)
The above example generates implementations for [`PyTypeInfo`] and [`PyClass`] for `MyClass` and`MyEnum`. To see these generated implementations, refer to the [implementation details](#implementation-details) at the end of this chapter.
67
+
The above example generates implementations for [`PyTypeInfo`] and [`PyClass`] for `MyClass`, `Number`,`MyEnum`, `HttpResponse`, and `Shape`. To see these generated implementations, refer to the [implementation details](#implementation-details) at the end of this chapter.
55
68
56
69
### Restrictions
57
70
@@ -964,7 +977,13 @@ Note that `text_signature` on `#[new]` is not compatible with compilation in
964
977
965
978
## #[pyclass] enums
966
979
967
-
Currently PyO3 only supports fieldless enums. PyO3 adds a class attribute for each variant, so you can access them in Python without defining `#[new]`. PyO3 also provides default implementations of `__richcmp__` and `__int__`, so they can be compared using `==`:
980
+
Enum support in PyO3 comes in two flavors, depending on what kind of variants the enum has: simple and complex.
981
+
982
+
### Simple enums
983
+
984
+
A simple enum (a.k.a. C-like enum) has only unit variants.
985
+
986
+
PyO3 adds a class attribute for each variant, so you can access them in Python without defining `#[new]`. PyO3 also provides default implementations of `__richcmp__` and `__int__`, so they can be compared using `==`:
968
987
969
988
```rust
970
989
# usepyo3::prelude::*;
@@ -986,7 +1005,7 @@ Python::with_gil(|py| {
986
1005
})
987
1006
```
988
1007
989
-
You can also convert your enums into `int`:
1008
+
You can also convert your simple enums into `int`:
990
1009
991
1010
```rust
992
1011
# usepyo3::prelude::*;
@@ -1094,6 +1113,74 @@ enum BadSubclass {
1094
1113
1095
1114
`#[pyclass]` enums are currently not interoperable with `IntEnum` in Python.
1096
1115
1116
+
### Complex enums
1117
+
1118
+
An enum is complex if it has any non-unit (struct or tuple) variants.
1119
+
1120
+
Currently PyO3 supports only struct variants in a complex enum. Support for unit and tuple variants is planned.
1121
+
1122
+
PyO3 adds a class attribute for each variant, which may be used to construct values and in match patterns. PyO3 also provides getter methods for all fields of each variant.
WARNING: `Py::new` and `.into_py` are currently inconsistent. Note how the constructed value is _not_ an instance of the specific variant. For this reason, constructing values is only recommended using `.into_py`.
0 commit comments