Skip to content

Commit d91d1df

Browse files
authored
Mark mangled globals as TypeAlias (#607)
* Mark mangled globals as `TypeAlias` * Use `Global___` for mangling prefix
1 parent e44c1bc commit d91d1df

20 files changed

+193
-115
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## Upcoming
22

3+
- Mark top-level mangled identifiers as `TypeAlias`.
4+
- Change the top-level mangling prefix from `global___` to `Global___` to respect
5+
[Y042](https://github.com/PyCQA/flake8-pyi/blob/main/ERRORCODES.md#list-of-warnings) naming convention.
6+
37
## 3.6.0
48

59
- Remove 3.7 compatibility for typing_extensions.final/Literal

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ black .
302302
- [@Alphadelta14](https://github.com/Alphadelta14)
303303
- [@fergyfresh](https://github.com/fergyfresh)
304304
- [@AlexWaygood](https://github.com/AlexWaygood)
305+
- [@Avasam](https://github.com/Avasam)
305306

306307
## Licence etc.
307308

mypy_protobuf/extensions_pb2.pyi

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ import google.protobuf.descriptor
88
import google.protobuf.descriptor_pb2
99
import google.protobuf.internal.extension_dict
1010
import google.protobuf.message
11+
import sys
1112
import typing
1213

14+
if sys.version_info >= (3, 10):
15+
import typing as typing_extensions
16+
else:
17+
import typing_extensions
18+
1319
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1420

1521
@typing.final
@@ -34,13 +40,13 @@ class FieldOptions(google.protobuf.message.Message):
3440
) -> None: ...
3541
def ClearField(self, field_name: typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"]) -> None: ...
3642

37-
global___FieldOptions = FieldOptions
43+
Global___FieldOptions: typing_extensions.TypeAlias = FieldOptions
3844

3945
OPTIONS_FIELD_NUMBER: builtins.int
4046
CASTTYPE_FIELD_NUMBER: builtins.int
4147
KEYTYPE_FIELD_NUMBER: builtins.int
4248
VALUETYPE_FIELD_NUMBER: builtins.int
43-
options: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, global___FieldOptions]
49+
options: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, Global___FieldOptions]
4450
"""Custom field options from mypy-protobuf"""
4551
casttype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, builtins.str]
4652
"""Legacy fields. Prefer to use ones within `options` instead."""

mypy_protobuf/main.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,10 @@ def _mangle_global_identifier(name: str) -> str:
9292
9393
Eg:
9494
Enum variant `Name` or message field `Name` might conflict with a top level
95-
message or enum named `Name`, so mangle it with a global___ prefix for
95+
message or enum named `Name`, so mangle it with a `Global___` prefix for
9696
internal references. Note that this doesn't affect inner enums/messages
97-
because they get fuly qualified when referenced within a file"""
98-
return f"global___{name}"
97+
because they get fully qualified when referenced within a file"""
98+
return f"Global___{name}"
9999

100100

101101
class Descriptors(object):
@@ -376,7 +376,7 @@ def write_enums(
376376
scl + [d.EnumDescriptorProto.VALUE_FIELD_NUMBER],
377377
)
378378
if prefix == "" and not self.readable_stubs:
379-
wl(f"{_mangle_global_identifier(class_name)} = {class_name}")
379+
wl(f"{_mangle_global_identifier(class_name)}: {self._import('typing_extensions', 'TypeAlias')} = {class_name}")
380380
wl("")
381381

382382
def write_messages(
@@ -483,7 +483,7 @@ def write_messages(
483483

484484
if prefix == "" and not self.readable_stubs:
485485
wl("")
486-
wl(f"{_mangle_global_identifier(class_name)} = {class_name}")
486+
wl(f"{_mangle_global_identifier(class_name)}: {self._import('typing_extensions', 'TypeAlias')} = {class_name}")
487487
wl("")
488488

489489
def write_stringly_typed_fields(self, desc: d.DescriptorProto) -> None:

stubtest_allowlist.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ testproto.grpc.dummy_pb2_grpc.DummyService
5757
testproto.grpc.import_pb2_grpc.SimpleService
5858

5959
# global prefix globals are generated, but aren't used at runtime
60-
.*_pb2\.global___.*
60+
# using `__` would be preferable, but Y047 will detect unused names.
61+
.*_pb2\.Global___.*
6162

6263
# All readonly generated @property fields seem to trip up
6364
# stubtest. It claims they aren't available at runtime, when practically,

test/generated/google/protobuf/duration_pb2.pyi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,14 @@ import builtins
3636
import google.protobuf.descriptor
3737
import google.protobuf.internal.well_known_types
3838
import google.protobuf.message
39+
import sys
3940
import typing
4041

42+
if sys.version_info >= (3, 10):
43+
import typing as typing_extensions
44+
else:
45+
import typing_extensions
46+
4147
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
4248

4349
@typing.final
@@ -127,4 +133,4 @@ class Duration(google.protobuf.message.Message, google.protobuf.internal.well_kn
127133
) -> None: ...
128134
def ClearField(self, field_name: typing.Literal["nanos", b"nanos", "seconds", b"seconds"]) -> None: ...
129135

130-
global___Duration = Duration
136+
Global___Duration: typing_extensions.TypeAlias = Duration

test/generated/mypy_protobuf/extensions_pb2.pyi

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ import google.protobuf.descriptor
88
import google.protobuf.descriptor_pb2
99
import google.protobuf.internal.extension_dict
1010
import google.protobuf.message
11+
import sys
1112
import typing
1213

14+
if sys.version_info >= (3, 10):
15+
import typing as typing_extensions
16+
else:
17+
import typing_extensions
18+
1319
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1420

1521
@typing.final
@@ -34,13 +40,13 @@ class FieldOptions(google.protobuf.message.Message):
3440
) -> None: ...
3541
def ClearField(self, field_name: typing.Literal["casttype", b"casttype", "keytype", b"keytype", "valuetype", b"valuetype"]) -> None: ...
3642

37-
global___FieldOptions = FieldOptions
43+
Global___FieldOptions: typing_extensions.TypeAlias = FieldOptions
3844

3945
OPTIONS_FIELD_NUMBER: builtins.int
4046
CASTTYPE_FIELD_NUMBER: builtins.int
4147
KEYTYPE_FIELD_NUMBER: builtins.int
4248
VALUETYPE_FIELD_NUMBER: builtins.int
43-
options: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, global___FieldOptions]
49+
options: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, Global___FieldOptions]
4450
"""Custom field options from mypy-protobuf"""
4551
casttype: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, builtins.str]
4652
"""Legacy fields. Prefer to use ones within `options` instead."""

test/generated/testproto/Capitalized/Capitalized_pb2.pyi

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ isort:skip_file
66
import builtins
77
import google.protobuf.descriptor
88
import google.protobuf.message
9+
import sys
910
import typing
1011

12+
if sys.version_info >= (3, 10):
13+
import typing as typing_extensions
14+
else:
15+
import typing_extensions
16+
1117
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1218

1319
@typing.final
@@ -23,38 +29,38 @@ class lower(google.protobuf.message.Message):
2329
) -> None: ...
2430
def ClearField(self, field_name: typing.Literal["a", b"a"]) -> None: ...
2531

26-
global___lower = lower
32+
Global___lower: typing_extensions.TypeAlias = lower
2733

2834
@typing.final
2935
class Upper(google.protobuf.message.Message):
3036
DESCRIPTOR: google.protobuf.descriptor.Descriptor
3137

3238
LOWER_FIELD_NUMBER: builtins.int
3339
@property
34-
def Lower(self) -> global___lower: ...
40+
def Lower(self) -> Global___lower: ...
3541
def __init__(
3642
self,
3743
*,
38-
Lower: global___lower | None = ...,
44+
Lower: Global___lower | None = ...,
3945
) -> None: ...
4046
def HasField(self, field_name: typing.Literal["Lower", b"Lower"]) -> builtins.bool: ...
4147
def ClearField(self, field_name: typing.Literal["Lower", b"Lower"]) -> None: ...
4248

43-
global___Upper = Upper
49+
Global___Upper: typing_extensions.TypeAlias = Upper
4450

4551
@typing.final
4652
class lower2(google.protobuf.message.Message):
4753
DESCRIPTOR: google.protobuf.descriptor.Descriptor
4854

4955
UPPER_FIELD_NUMBER: builtins.int
5056
@property
51-
def upper(self) -> global___Upper: ...
57+
def upper(self) -> Global___Upper: ...
5258
def __init__(
5359
self,
5460
*,
55-
upper: global___Upper | None = ...,
61+
upper: Global___Upper | None = ...,
5662
) -> None: ...
5763
def HasField(self, field_name: typing.Literal["upper", b"upper"]) -> builtins.bool: ...
5864
def ClearField(self, field_name: typing.Literal["upper", b"upper"]) -> None: ...
5965

60-
global___lower2 = lower2
66+
Global___lower2: typing_extensions.TypeAlias = lower2

test/generated/testproto/comment_special_chars_pb2.pyi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ isort:skip_file
66
import builtins
77
import google.protobuf.descriptor
88
import google.protobuf.message
9+
import sys
910
import typing
1011

12+
if sys.version_info >= (3, 10):
13+
import typing as typing_extensions
14+
else:
15+
import typing_extensions
16+
1117
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1218

1319
@typing.final
@@ -73,4 +79,4 @@ class Test(google.protobuf.message.Message):
7379
) -> None: ...
7480
def ClearField(self, field_name: 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"]) -> None: ...
7581

76-
global___Test = Test
82+
Global___Test: typing_extensions.TypeAlias = Test

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ isort:skip_file
66
import builtins
77
import google.protobuf.descriptor
88
import google.protobuf.message
9+
import sys
910
import typing
1011

12+
if sys.version_info >= (3, 10):
13+
import typing as typing_extensions
14+
else:
15+
import typing_extensions
16+
1117
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1218

1319
@typing.final
@@ -23,4 +29,4 @@ class TestMessage(google.protobuf.message.Message):
2329
) -> None: ...
2430
def ClearField(self, field_name: typing.Literal["foo", b"foo"]) -> None: ...
2531

26-
global___TestMessage = TestMessage
32+
Global___TestMessage: typing_extensions.TypeAlias = TestMessage

test/generated/testproto/grpc/dummy_pb2.pyi

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ https://github.com/vmagamedov/grpclib/blob/master/tests/dummy.proto"""
66
import builtins
77
import google.protobuf.descriptor
88
import google.protobuf.message
9+
import sys
910
import typing
1011

12+
if sys.version_info >= (3, 10):
13+
import typing as typing_extensions
14+
else:
15+
import typing_extensions
16+
1117
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1218

1319
@typing.final
@@ -23,7 +29,7 @@ class DummyRequest(google.protobuf.message.Message):
2329
) -> None: ...
2430
def ClearField(self, field_name: typing.Literal["value", b"value"]) -> None: ...
2531

26-
global___DummyRequest = DummyRequest
32+
Global___DummyRequest: typing_extensions.TypeAlias = DummyRequest
2733

2834
@typing.final
2935
class DummyReply(google.protobuf.message.Message):
@@ -38,4 +44,4 @@ class DummyReply(google.protobuf.message.Message):
3844
) -> None: ...
3945
def ClearField(self, field_name: typing.Literal["value", b"value"]) -> None: ...
4046

41-
global___DummyReply = DummyReply
47+
Global___DummyReply: typing_extensions.TypeAlias = DummyReply

test/generated/testproto/inner/inner_pb2.pyi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ isort:skip_file
66
import builtins
77
import google.protobuf.descriptor
88
import google.protobuf.message
9+
import sys
910
import testproto.test3_pb2
1011
import typing
1112

13+
if sys.version_info >= (3, 10):
14+
import typing as typing_extensions
15+
else:
16+
import typing_extensions
17+
1218
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1319

1420
@typing.final
@@ -24,4 +30,4 @@ class Inner(google.protobuf.message.Message):
2430
) -> None: ...
2531
def ClearField(self, field_name: typing.Literal["a", b"a"]) -> None: ...
2632

27-
global___Inner = Inner
33+
Global___Inner: typing_extensions.TypeAlias = Inner

test/generated/testproto/nested/nested_pb2.pyi

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ class Nested(google.protobuf.message.Message):
3131
) -> None: ...
3232
def ClearField(self, field_name: typing.Literal["a", b"a"]) -> None: ...
3333

34-
global___Nested = Nested
34+
Global___Nested: typing_extensions.TypeAlias = Nested
3535

3636
@typing.final
3737
class AnotherNested(google.protobuf.message.Message):
@@ -77,20 +77,20 @@ class AnotherNested(google.protobuf.message.Message):
7777
NE2_FIELD_NUMBER: builtins.int
7878
s: builtins.str
7979
b: builtins.bool
80-
ne: global___AnotherNested.NestedEnum.ValueType
81-
ne2: global___AnotherNested.NestedMessage.NestedEnum2.ValueType
80+
ne: Global___AnotherNested.NestedEnum.ValueType
81+
ne2: Global___AnotherNested.NestedMessage.NestedEnum2.ValueType
8282
def __init__(
8383
self,
8484
*,
8585
s: builtins.str = ...,
8686
b: builtins.bool = ...,
87-
ne: global___AnotherNested.NestedEnum.ValueType = ...,
88-
ne2: global___AnotherNested.NestedMessage.NestedEnum2.ValueType = ...,
87+
ne: Global___AnotherNested.NestedEnum.ValueType = ...,
88+
ne2: Global___AnotherNested.NestedMessage.NestedEnum2.ValueType = ...,
8989
) -> None: ...
9090
def ClearField(self, field_name: typing.Literal["b", b"b", "ne", b"ne", "ne2", b"ne2", "s", b"s"]) -> None: ...
9191

9292
def __init__(
9393
self,
9494
) -> None: ...
9595

96-
global___AnotherNested = AnotherNested
96+
Global___AnotherNested: typing_extensions.TypeAlias = AnotherNested

test/generated/testproto/nopackage_pb2.pyi

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ import collections.abc
88
import google.protobuf.descriptor
99
import google.protobuf.internal.containers
1010
import google.protobuf.message
11+
import sys
1112
import typing
1213

14+
if sys.version_info >= (3, 10):
15+
import typing as typing_extensions
16+
else:
17+
import typing_extensions
18+
1319
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
1420

1521
@typing.final
@@ -22,7 +28,7 @@ class NoPackage(google.protobuf.message.Message):
2228
self,
2329
) -> None: ...
2430

25-
global___NoPackage = NoPackage
31+
Global___NoPackage: typing_extensions.TypeAlias = NoPackage
2632

2733
@typing.final
2834
class NoPackage2(google.protobuf.message.Message):
@@ -31,16 +37,16 @@ class NoPackage2(google.protobuf.message.Message):
3137
NP_FIELD_NUMBER: builtins.int
3238
NP_REP_FIELD_NUMBER: builtins.int
3339
@property
34-
def np(self) -> global___NoPackage: ...
40+
def np(self) -> Global___NoPackage: ...
3541
@property
36-
def np_rep(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NoPackage]: ...
42+
def np_rep(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[Global___NoPackage]: ...
3743
def __init__(
3844
self,
3945
*,
40-
np: global___NoPackage | None = ...,
41-
np_rep: collections.abc.Iterable[global___NoPackage] | None = ...,
46+
np: Global___NoPackage | None = ...,
47+
np_rep: collections.abc.Iterable[Global___NoPackage] | None = ...,
4248
) -> None: ...
4349
def HasField(self, field_name: typing.Literal["np", b"np"]) -> builtins.bool: ...
4450
def ClearField(self, field_name: typing.Literal["np", b"np", "np_rep", b"np_rep"]) -> None: ...
4551

46-
global___NoPackage2 = NoPackage2
52+
Global___NoPackage2: typing_extensions.TypeAlias = NoPackage2

test/generated/testproto/readme_enum_pb2.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ class MyEnum(_MyEnum, metaclass=_MyEnumEnumTypeWrapper): ...
2929

3030
HELLO: MyEnum.ValueType # 0
3131
WORLD: MyEnum.ValueType # 1
32-
global___MyEnum = MyEnum
32+
Global___MyEnum: typing_extensions.TypeAlias = MyEnum

0 commit comments

Comments
 (0)