Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support pyclass on tuple enums (closer but not there yet) #4135

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 13 additions & 10 deletions guide/src/class.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,18 @@ enum HttpResponse {
// ...
}

// PyO3 also supports enums with non-unit variants
// PyO3 also supports enums with Struct and Tuple variants
// These complex enums have sligtly different behavior from the simple enums above
// They are meant to work with instance checks and match statement patterns
// The variants can be mixed and matched
// Struct variants have named fields while tuple enums generate generic names for fields in order _0, _1, _2, ...
// Apart from this both types are functionally identical
#[pyclass]
enum Shape {
Circle { radius: f64 },
Rectangle { width: f64, height: f64 },
RegularPolygon { side_count: u32, radius: f64 },
Nothing {},
Rectangle { height: f64, width: f64 },
RegularPolygon(u32, f64),
Nothing(),
}
```

Expand Down Expand Up @@ -1178,7 +1181,7 @@ enum BadSubclass {

An enum is complex if it has any non-unit (struct or tuple) variants.

Currently PyO3 supports only struct variants in a complex enum. Support for unit and tuple variants is planned.
Currently PyO3 supports only struct and tuple variants in a complex enum. Support for unit variants is planned.

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.

Expand All @@ -1188,14 +1191,14 @@ PyO3 adds a class attribute for each variant, which may be used to construct val
enum Shape {
Circle { radius: f64 },
Rectangle { width: f64, height: f64 },
RegularPolygon { side_count: u32, radius: f64 },
RegularPolygon(u32, f64),
Nothing { },
}

# #[cfg(Py_3_10)]
Python::with_gil(|py| {
let circle = Shape::Circle { radius: 10.0 }.into_py(py);
let square = Shape::RegularPolygon { side_count: 4, radius: 10.0 }.into_py(py);
let square = Shape::RegularPolygon(4, 10.0).into_py(py);
let cls = py.get_type_bound::<Shape>();
pyo3::py_run!(py, circle square cls, r#"
assert isinstance(circle, cls)
Expand All @@ -1204,16 +1207,16 @@ Python::with_gil(|py| {

assert isinstance(square, cls)
assert isinstance(square, cls.RegularPolygon)
assert square.side_count == 4
assert square.radius == 10.0
assert square._0 == 4
assert square._1 == 10.0

def count_vertices(cls, shape):
match shape:
case cls.Circle():
return 0
case cls.Rectangle():
return 4
case cls.RegularPolygon(side_count=n):
case cls.RegularPolygon(_0=n):
return n
case cls.Nothing():
return 0
Expand Down
1 change: 1 addition & 0 deletions newsfragments/4135.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Support `#[pyclass]` on enums that have tuple variants.