Skip to content
This repository was archived by the owner on Jun 9, 2025. It is now read-only.

Commit 482b3cf

Browse files
committed
Use Python 3.10 unions
1 parent b96e38a commit 482b3cf

File tree

11 files changed

+39
-48
lines changed

11 files changed

+39
-48
lines changed

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ select = [
5252
"SIM102", # Simplify return or yield statements
5353
"SIM103", # Simplify list/set/dict comprehensions
5454

55+
"UP007", # Use Python 3.10 unions
56+
5557
"I",
5658
]
5759

src/betterproto2_compiler/enum.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
TYPE_CHECKING,
1010
Any,
1111
Dict,
12-
Optional,
1312
Tuple,
1413
)
1514

@@ -111,12 +110,12 @@ class Enum(IntEnum if TYPE_CHECKING else int, metaclass=EnumType):
111110
inherit from this. Emulates `enum.IntEnum`.
112111
"""
113112

114-
name: Optional[str]
113+
name: str | None
115114
value: int
116115

117116
if not TYPE_CHECKING:
118117

119-
def __new__(cls, *, name: Optional[str], value: int) -> Self:
118+
def __new__(cls, *, name: str | None, value: int) -> Self:
120119
self = super().__new__(cls, value)
121120
super().__setattr__(self, "name", name)
122121
super().__setattr__(self, "value", value)

src/betterproto2_compiler/grpc/grpclib_client.py

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
Optional,
1111
Tuple,
1212
Type,
13-
Union,
1413
)
1514

1615
import grpclib.const
@@ -25,9 +24,9 @@
2524
)
2625

2726

28-
Value = Union[str, bytes]
29-
MetadataLike = Union[Mapping[str, Value], Collection[Tuple[str, Value]]]
30-
MessageSource = Union[Iterable["IProtoMessage"], AsyncIterable["IProtoMessage"]]
27+
Value = str | bytes
28+
MetadataLike = Mapping[str, Value] | Collection[Tuple[str, Value]]
29+
MessageSource = Iterable["IProtoMessage"] | AsyncIterable["IProtoMessage"]
3130

3231

3332
class ServiceStub(ABC):
@@ -39,9 +38,9 @@ def __init__(
3938
self,
4039
channel: "Channel",
4140
*,
42-
timeout: Optional[float] = None,
41+
timeout: float | None = None,
4342
deadline: Optional["Deadline"] = None,
44-
metadata: Optional[MetadataLike] = None,
43+
metadata: MetadataLike | None = None,
4544
) -> None:
4645
self.channel = channel
4746
self.timeout = timeout
@@ -50,9 +49,9 @@ def __init__(
5049

5150
def __resolve_request_kwargs(
5251
self,
53-
timeout: Optional[float],
52+
timeout: float | None,
5453
deadline: Optional["Deadline"],
55-
metadata: Optional[MetadataLike],
54+
metadata: MetadataLike | None,
5655
):
5756
return {
5857
"timeout": self.timeout if timeout is None else timeout,
@@ -66,9 +65,9 @@ async def _unary_unary(
6665
request: "IProtoMessage",
6766
response_type: Type["T"],
6867
*,
69-
timeout: Optional[float] = None,
68+
timeout: float | None = None,
7069
deadline: Optional["Deadline"] = None,
71-
metadata: Optional[MetadataLike] = None,
70+
metadata: MetadataLike | None = None,
7271
) -> "T":
7372
"""Make a unary request and return the response."""
7473
async with self.channel.request(
@@ -89,9 +88,9 @@ async def _unary_stream(
8988
request: "IProtoMessage",
9089
response_type: Type["T"],
9190
*,
92-
timeout: Optional[float] = None,
91+
timeout: float | None = None,
9392
deadline: Optional["Deadline"] = None,
94-
metadata: Optional[MetadataLike] = None,
93+
metadata: MetadataLike | None = None,
9594
) -> AsyncIterator["T"]:
9695
"""Make a unary request and return the stream response iterator."""
9796
async with self.channel.request(
@@ -112,9 +111,9 @@ async def _stream_unary(
112111
request_type: Type["IProtoMessage"],
113112
response_type: Type["T"],
114113
*,
115-
timeout: Optional[float] = None,
114+
timeout: float | None = None,
116115
deadline: Optional["Deadline"] = None,
117-
metadata: Optional[MetadataLike] = None,
116+
metadata: MetadataLike | None = None,
118117
) -> "T":
119118
"""Make a stream request and return the response."""
120119
async with self.channel.request(
@@ -137,9 +136,9 @@ async def _stream_stream(
137136
request_type: Type["IProtoMessage"],
138137
response_type: Type["T"],
139138
*,
140-
timeout: Optional[float] = None,
139+
timeout: float | None = None,
141140
deadline: Optional["Deadline"] = None,
142-
metadata: Optional[MetadataLike] = None,
141+
metadata: MetadataLike | None = None,
143142
) -> AsyncIterator["T"]:
144143
"""
145144
Make a stream request and return an AsyncIterator to iterate over response

src/betterproto2_compiler/grpc/util/async_channel.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
AsyncIterable,
44
AsyncIterator,
55
Iterable,
6-
Optional,
76
TypeVar,
8-
Union,
97
)
108

119
T = TypeVar("T")
@@ -117,7 +115,7 @@ def done(self) -> bool:
117115
# receiver per enqueued item.
118116
return self._closed and self._queue.qsize() <= self._waiting_receivers
119117

120-
async def send_from(self, source: Union[Iterable[T], AsyncIterable[T]], close: bool = False) -> "AsyncChannel[T]":
118+
async def send_from(self, source: Iterable[T] | AsyncIterable[T], close: bool = False) -> "AsyncChannel[T]":
121119
"""
122120
Iterates the given [Async]Iterable and sends all the resulting items.
123121
If close is set to True then subsequent send calls will be rejected with a
@@ -150,7 +148,7 @@ async def send(self, item: T) -> "AsyncChannel[T]":
150148
await self._queue.put(item)
151149
return self
152150

153-
async def receive(self) -> Optional[T]:
151+
async def receive(self) -> T | None:
154152
"""
155153
Returns the next item from this channel when it becomes available,
156154
or None if the channel is closed before another item is sent.

src/betterproto2_compiler/lib/pydantic/google/protobuf/__init__.py

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/betterproto2_compiler/lib/std/google/protobuf/__init__.py

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/betterproto2_compiler/plugin/models.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
Iterable,
4141
Iterator,
4242
List,
43-
Optional,
4443
Set,
4544
Type,
4645
Union,
@@ -416,7 +415,7 @@ def use_builtins(self) -> bool:
416415
)
417416

418417
@property
419-
def field_wraps(self) -> Optional[str]:
418+
def field_wraps(self) -> str | None:
420419
"""Returns betterproto wrapped field type or None."""
421420
match_wrapper = re.match(r"\.google\.protobuf\.(.+)Value$", self.proto_obj.type_name)
422421
if match_wrapper:
@@ -509,8 +508,8 @@ def betterproto_field_args(self) -> List[str]:
509508

510509
@dataclass
511510
class MapEntryCompiler(FieldCompiler):
512-
py_k_type: Optional[Type] = None
513-
py_v_type: Optional[Type] = None
511+
py_k_type: Type | None = None
512+
py_v_type: Type | None = None
514513
proto_k_type: str = ""
515514
proto_v_type: str = ""
516515

src/betterproto2_compiler/plugin/parser.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
List,
66
Set,
77
Tuple,
8-
Union,
98
)
109

1110
from betterproto2_compiler.lib.google.protobuf import (
@@ -45,13 +44,13 @@
4544

4645
def traverse(
4746
proto_file: FileDescriptorProto,
48-
) -> Generator[Tuple[Union[EnumDescriptorProto, DescriptorProto], List[int]], None, None]:
47+
) -> Generator[Tuple[EnumDescriptorProto | DescriptorProto, List[int]], None, None]:
4948
# Todo: Keep information about nested hierarchy
5049
def _traverse(
5150
path: List[int],
52-
items: Union[List[EnumDescriptorProto], List[DescriptorProto]],
51+
items: List[EnumDescriptorProto] | List[DescriptorProto],
5352
prefix: str = "",
54-
) -> Generator[Tuple[Union[EnumDescriptorProto, DescriptorProto], List[int]], None, None]:
53+
) -> Generator[Tuple[EnumDescriptorProto | DescriptorProto, List[int]], None, None]:
5554
for i, item in enumerate(items):
5655
# Adjust the name since we flatten the hierarchy.
5756
# Todo: don't change the name, but include full name in returned tuple

src/betterproto2_compiler/plugin/typing_compiler.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from typing import (
88
Dict,
99
Iterator,
10-
Optional,
1110
Set,
1211
)
1312

@@ -42,7 +41,7 @@ def async_iterator(self, type_: str) -> str:
4241
raise NotImplementedError
4342

4443
@abc.abstractmethod
45-
def imports(self) -> Dict[str, Optional[Set[str]]]:
44+
def imports(self) -> Dict[str, Set[str] | None]:
4645
"""
4746
Returns either the direct import as a key with none as value, or a set of
4847
values to import from the key.
@@ -93,7 +92,7 @@ def async_iterator(self, type_: str) -> str:
9392
self._imports["typing"].add("AsyncIterator")
9493
return f"AsyncIterator[{type_}]"
9594

96-
def imports(self) -> Dict[str, Optional[Set[str]]]:
95+
def imports(self) -> Dict[str, Set[str] | None]:
9796
return {k: v if v else None for k, v in self._imports.items()}
9897

9998

@@ -129,7 +128,7 @@ def async_iterator(self, type_: str) -> str:
129128
self._imported = True
130129
return f"typing.AsyncIterator[{type_}]"
131130

132-
def imports(self) -> Dict[str, Optional[Set[str]]]:
131+
def imports(self) -> Dict[str, Set[str] | None]:
133132
if self._imported:
134133
return {"typing": None}
135134
return {}
@@ -163,5 +162,5 @@ def async_iterator(self, type_: str) -> str:
163162
self._imports["collections.abc"].add("AsyncIterator")
164163
return f"AsyncIterator[{type_}]"
165164

166-
def imports(self) -> Dict[str, Optional[Set[str]]]:
165+
def imports(self) -> Dict[str, Set[str] | None]:
167166
return {k: v if v else None for k, v in self._imports.items()}

tests/test_module_validation.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from typing import (
22
List,
3-
Optional,
43
Set,
54
)
65

@@ -99,7 +98,7 @@
9998
),
10099
],
101100
)
102-
def test_module_validator(text: List[str], expected_collisions: Optional[Set[str]]):
101+
def test_module_validator(text: List[str], expected_collisions: Set[str] | None):
103102
line_iterator = iter(text)
104103
validator = ModuleValidator(line_iterator)
105104
valid = validator.validate()

0 commit comments

Comments
 (0)