Skip to content

Commit b5dcfc2

Browse files
committed
Rename *NamesType to *ArgType
Add WhichOneofArgType and WhichOneofReturnType aliases Signed-off-by: Aidan Jensen <aidandj.github@gmail.com>
1 parent 3d681ce commit b5dcfc2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+352
-280
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
- Protobuf <6.32 still had the edition enums and field options, so it *should* still work. But is untested
88
- Add support for editions (up to 2024)
99
- Add `generate_concrete_servicer_stubs` option to generate concrete instead of abstract servicer stubs
10-
- Add `_HasFieldNamesType` and `_ClearFieldNamesType` aliases to allow for typing field manipulation functions
10+
- Add `_HasFieldArgType` and `_ClearFieldArgType` aliases to allow for typing field manipulation functions
11+
- Add `_WhichOneofArgType_<field_name>` and `_WhichOneofReturnType_<field_name>` type aliases
1112

1213
## 3.7.0
1314

README.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ See [Changelog](CHANGELOG.md) for full listing
101101
* `mypy-protobuf` generates correctly typed constructors dependinding on field presence.
102102
* `mypy-protobuf` generates correctly typed `HasField`, `WhichOneof`, and `ClearField` methods.
103103
* There are differences in how `mypy-protobuf` and `pyi_out` generate enums. See [this issue](https://github.com/protocolbuffers/protobuf/issues/8175) for details
104+
* Type aliases exported for `HasField`, `WhichOneof` and `ClearField` arguments
104105

105106
#### Examples
106107

@@ -370,20 +371,28 @@ protoc \
370371
Note that generated code for grpc will work only together with code for python and locations should be the same.
371372
If you need stubs for grpc internal code we suggest using this package https://github.com/shabbyrobe/grpc-stubs
372373

373-
### `_ClearFieldNamesType` and `_HasFieldNamesType` aliases
374+
### `_ClearFieldArgType` and `_HasFieldArgType` aliases
374375

375-
Where applicable, type aliases are generated for the arguments to `ClearField` and `HasField`. These can be used to create typed functions for field manipulation:
376+
Where applicable, type aliases are generated for the arguments to `ClearField`, `WhichOneof` and `HasField`. These can be used to create typed functions for field manipulation:
376377

377378
```python
378379
from testproto.edition2024_pb2 import Editions2024Test
379380

380-
def test_hasfield_alias(msg: Editions2024Test, field: "Editions2024Test._HasFieldNamesType") -> bool:
381+
def test_hasfield_alias(msg: Editions2024Test, field: "Editions2024Test._HasFieldArgType") -> bool:
381382
return msg.HasField(field)
382383

383384
test_hasfield_alias(Editions2024Test(), "legacy")
385+
386+
def test_whichoneof_alias(
387+
msg: SimpleProto3,
388+
oneof: "SimpleProto3._WhichOneofArgType_a_oneof",
389+
) -> "SimpleProto3._WhichOneofReturnType_a_oneof | None":
390+
return msg.WhichOneof(oneof)
391+
392+
test_whichoneof_alias(SimpleProto3(), "a_oneof")
384393
```
385394

386-
Note the deferred evaluation (string reference, or `from __future__ import annotations`. This bypasses the fact that the alias does not exist on the stub)
395+
Note the deferred evaluation (string reference, or `from __future__ import annotations`. This bypasses the fact that the alias does not exist on the runtime class)
387396

388397
### Targeting python2 support
389398

mypy_protobuf/extensions_pb2.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class FieldOptions(google.protobuf.message.Message):
3838
keytype: builtins.str = ...,
3939
valuetype: builtins.str = ...,
4040
) -> None: ...
41-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"]
42-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
41+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"]
42+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
4343

4444
Global___FieldOptions: typing_extensions.TypeAlias = FieldOptions
4545

mypy_protobuf/main.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -578,29 +578,43 @@ def write_stringly_typed_fields(self, desc: d.DescriptorProto) -> None:
578578
return
579579

580580
if hf_fields:
581-
wl("_HasFieldNamesType: {} = {}[{}]", self._import("typing_extensions", "TypeAlias"), self._import("typing", "Literal"), hf_fields_text)
581+
wl("_HasFieldArgType: {} = {}[{}]", self._import("typing_extensions", "TypeAlias"), self._import("typing", "Literal"), hf_fields_text)
582582
wl(
583-
"def HasField(self, field_name: _HasFieldNamesType) -> {}: ...",
583+
"def HasField(self, field_name: _HasFieldArgType) -> {}: ...",
584584
self._builtin("bool"),
585585
)
586586
if cf_fields:
587-
wl("_ClearFieldNamesType: {} = {}[{}]", self._import("typing_extensions", "TypeAlias"), self._import("typing", "Literal"), cf_fields_text)
587+
wl("_ClearFieldArgType: {} = {}[{}]", self._import("typing_extensions", "TypeAlias"), self._import("typing", "Literal"), cf_fields_text)
588588
wl(
589-
"def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...",
589+
"def ClearField(self, field_name: _ClearFieldArgType) -> None: ...",
590590
)
591591

592+
# Write type aliases first so overloads are not interrupted
592593
for wo_field, members in sorted(wo_fields.items()):
593-
if len(wo_fields) > 1:
594-
wl("@{}", self._import("typing", "overload"))
595594
wl(
596-
"def WhichOneof(self, oneof_group: {}[{}]) -> {}[{}] | None: ...",
597-
self._import("typing", "Literal"),
598-
# Accepts both str and bytes
599-
f'"{wo_field}", b"{wo_field}"',
595+
"_WhichOneofReturnType_{}: {} = {}[{}]",
596+
wo_field,
597+
self._import("typing_extensions", "TypeAlias"),
600598
self._import("typing", "Literal"),
601599
# Returns `str`
602600
", ".join(f'"{m}"' for m in members),
603601
)
602+
wl(
603+
"_WhichOneofArgType_{}: {} = {}[{}]",
604+
wo_field,
605+
self._import("typing_extensions", "TypeAlias"),
606+
self._import("typing", "Literal"),
607+
# Accepts both str and bytes
608+
f'"{wo_field}", b"{wo_field}"',
609+
)
610+
for wo_field, _ in sorted(wo_fields.items()):
611+
if len(wo_fields) > 1:
612+
wl("@{}", self._import("typing", "overload"))
613+
wl(
614+
"def WhichOneof(self, oneof_group: {}) -> {} | None: ...",
615+
f"_WhichOneofArgType_{wo_field}",
616+
f"_WhichOneofReturnType_{wo_field}",
617+
)
604618

605619
def write_extensions(
606620
self,

stubtest_allowlist.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,5 +242,7 @@ testproto.test_pb2.Extensions1.ext
242242

243243

244244
# Generated type aliases for HasField and ClearField. These do not exist on a message, but are also just type aliases
245-
.*_HasFieldNamesType
246-
.*_ClearFieldNamesType
245+
.*_HasFieldArgType
246+
.*_ClearFieldArgType
247+
.*_WhichOneofReturnType.*
248+
.*_WhichOneofArgType.*

test/generated/google/protobuf/duration_pb2.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class Duration(google.protobuf.message.Message, google.protobuf.internal.well_kn
131131
seconds: builtins.int = ...,
132132
nanos: builtins.int = ...,
133133
) -> None: ...
134-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["nanos", b"nanos", "seconds", b"seconds"]
135-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
134+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["nanos", b"nanos", "seconds", b"seconds"]
135+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
136136

137137
Global___Duration: typing_extensions.TypeAlias = Duration

test/generated/mypy_protobuf/extensions_pb2.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ class FieldOptions(google.protobuf.message.Message):
3838
keytype: builtins.str = ...,
3939
valuetype: builtins.str = ...,
4040
) -> None: ...
41-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"]
42-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
41+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"]
42+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
4343

4444
Global___FieldOptions: typing_extensions.TypeAlias = FieldOptions
4545

test/generated/testproto/Capitalized/Capitalized_pb2.pyi

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ class lower(google.protobuf.message.Message):
2727
*,
2828
a: builtins.int = ...,
2929
) -> None: ...
30-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["a", b"a"]
31-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
30+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["a", b"a"]
31+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
3232

3333
Global___lower: typing_extensions.TypeAlias = lower
3434

@@ -44,10 +44,10 @@ class Upper(google.protobuf.message.Message):
4444
*,
4545
Lower: Global___lower | None = ...,
4646
) -> None: ...
47-
_HasFieldNamesType: typing_extensions.TypeAlias = typing.Literal["Lower", b"Lower"]
48-
def HasField(self, field_name: _HasFieldNamesType) -> builtins.bool: ...
49-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["Lower", b"Lower"]
50-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
47+
_HasFieldArgType: typing_extensions.TypeAlias = typing.Literal["Lower", b"Lower"]
48+
def HasField(self, field_name: _HasFieldArgType) -> builtins.bool: ...
49+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["Lower", b"Lower"]
50+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
5151

5252
Global___Upper: typing_extensions.TypeAlias = Upper
5353

@@ -63,9 +63,9 @@ class lower2(google.protobuf.message.Message):
6363
*,
6464
upper: Global___Upper | None = ...,
6565
) -> None: ...
66-
_HasFieldNamesType: typing_extensions.TypeAlias = typing.Literal["upper", b"upper"]
67-
def HasField(self, field_name: _HasFieldNamesType) -> builtins.bool: ...
68-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["upper", b"upper"]
69-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
66+
_HasFieldArgType: typing_extensions.TypeAlias = typing.Literal["upper", b"upper"]
67+
def HasField(self, field_name: _HasFieldArgType) -> builtins.bool: ...
68+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["upper", b"upper"]
69+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
7070

7171
Global___lower2: typing_extensions.TypeAlias = lower2

test/generated/testproto/comment_special_chars_pb2.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class Test(google.protobuf.message.Message):
7777
j: builtins.str = ...,
7878
k: builtins.str = ...,
7979
) -> None: ...
80-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["a", b"a", "b", b"b", "c", b"c", "d", b"d", "e", b"e", "f", b"f", "g", b"g", "h", b"h", "i", b"i", "j", b"j", "k", b"k"]
81-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
80+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["a", b"a", "b", b"b", "c", b"c", "d", b"d", "e", b"e", "f", b"f", "g", b"g", "h", b"h", "i", b"i", "j", b"j", "k", b"k"]
81+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
8282

8383
Global___Test: typing_extensions.TypeAlias = Test

test/generated/testproto/dot/com/test_pb2.pyi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class TestMessage(google.protobuf.message.Message):
2727
*,
2828
foo: builtins.str = ...,
2929
) -> None: ...
30-
_ClearFieldNamesType: typing_extensions.TypeAlias = typing.Literal["foo", b"foo"]
31-
def ClearField(self, field_name: _ClearFieldNamesType) -> None: ...
30+
_ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["foo", b"foo"]
31+
def ClearField(self, field_name: _ClearFieldArgType) -> None: ...
3232

3333
Global___TestMessage: typing_extensions.TypeAlias = TestMessage

0 commit comments

Comments
 (0)