Change how enum fields are generated in the PYI
Reading an enum field returns an enum type according to the type hint. But assigning to it accepts either the enum type or an int. (Which is a real run-time behavior)
Before:
```python
cell_type: CellType
```
After:
```python
@property
def cell_type(self) -> CellType: ...
@cell_type.setter
def cell_type(self, value: _Union[CellType, int]) -> None: ...
```
PiperOrigin-RevId: 910665494
diff --git a/src/google/protobuf/compiler/python/pyi_generator.cc b/src/google/protobuf/compiler/python/pyi_generator.cc
index a787969..17b80f5 100644
--- a/src/google/protobuf/compiler/python/pyi_generator.cc
+++ b/src/google/protobuf/compiler/python/pyi_generator.cc
@@ -515,9 +515,23 @@
if (field_des.is_repeated()) {
absl::StrAppend(&field_type, "]");
}
- printer_->Print("$name$: $type$\n",
- "name", field_des.name(), "type", field_type);
- Annotate("name", &field_des);
+ if (field_des.cpp_type() == FieldDescriptor::CPPTYPE_ENUM &&
+ !field_des.is_repeated()) {
+ // Reading an enum field returns an enum type according to the type
+ // hint. But assigning to it accepts either the enum type or an int.
+ printer_->Print("@property\n");
+ printer_->Print("def $name$(self) -> $type$: ...\n", "name",
+ field_des.name(), "type", field_type);
+ Annotate("name", &field_des);
+ printer_->Print("@$name$.setter\n", "name", field_des.name());
+ printer_->Print(
+ "def $name$(self, value: _Union[$type$, int]) -> None: ...\n", "name",
+ field_des.name(), "type", field_type);
+ } else {
+ printer_->Print("$name$: $type$\n", "name", field_des.name(), "type",
+ field_type);
+ Annotate("name", &field_des);
+ }
}
// Prints __init__