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

Commit f7d9e30

Browse files
committed
Add more rules
1 parent e2e4038 commit f7d9e30

File tree

10 files changed

+63
-102
lines changed

10 files changed

+63
-102
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ protobuf = "^4"
3737
protoc-gen-python_betterproto2 = "betterproto2_compiler.plugin:main"
3838

3939
[tool.ruff]
40-
extend-exclude = ["tests/output_*"]
40+
extend-exclude = ["tests/output_*", "src/betterproto2_compiler/lib"]
4141
target-version = "py310"
4242
line-length = 120
4343

@@ -52,7 +52,7 @@ select = [
5252
"SIM102", # Simplify return or yield statements
5353
"SIM103", # Simplify list/set/dict comprehensions
5454

55-
"UP007", # Use Python 3.10 unions
55+
"UP",
5656

5757
"I",
5858
]

src/betterproto2_compiler/compile/importing.py

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33
import os
44
from typing import (
55
TYPE_CHECKING,
6-
Dict,
7-
List,
8-
Set,
9-
Tuple,
10-
Type,
116
)
127

138
from ..casing import safe_snake_case
@@ -18,7 +13,7 @@
1813
from ..plugin.models import PluginRequestCompiler
1914
from ..plugin.typing_compiler import TypingCompiler
2015

21-
WRAPPER_TYPES: Dict[str, Type] = {
16+
WRAPPER_TYPES: dict[str, type] = {
2217
".google.protobuf.DoubleValue": google_protobuf.DoubleValue,
2318
".google.protobuf.FloatValue": google_protobuf.FloatValue,
2419
".google.protobuf.Int32Value": google_protobuf.Int32Value,
@@ -31,7 +26,7 @@
3126
}
3227

3328

34-
def parse_source_type_name(field_type_name: str, request: "PluginRequestCompiler") -> Tuple[str, str]:
29+
def parse_source_type_name(field_type_name: str, request: PluginRequestCompiler) -> tuple[str, str]:
3530
"""
3631
Split full source type name into package and type name.
3732
E.g. 'root.package.Message' -> ('root.package', 'Message')
@@ -77,7 +72,7 @@ def get_type_reference(
7772
imports: set,
7873
source_type: str,
7974
typing_compiler: TypingCompiler,
80-
request: "PluginRequestCompiler",
75+
request: PluginRequestCompiler,
8176
unwrap: bool = True,
8277
pydantic: bool = False,
8378
) -> str:
@@ -98,8 +93,8 @@ def get_type_reference(
9893

9994
source_package, source_type = parse_source_type_name(source_type, request)
10095

101-
current_package: List[str] = package.split(".") if package else []
102-
py_package: List[str] = source_package.split(".") if source_package else []
96+
current_package: list[str] = package.split(".") if package else []
97+
py_package: list[str] = source_package.split(".") if source_package else []
10398
py_type: str = pythonize_class_name(source_type)
10499

105100
compiling_google_protobuf = current_package == ["google", "protobuf"]
@@ -122,7 +117,7 @@ def get_type_reference(
122117
return reference_cousin(current_package, imports, py_package, py_type)
123118

124119

125-
def reference_absolute(imports: Set[str], py_package: List[str], py_type: str) -> str:
120+
def reference_absolute(imports: set[str], py_package: list[str], py_type: str) -> str:
126121
"""
127122
Returns a reference to a python type located in the root, i.e. sys.path.
128123
"""
@@ -139,7 +134,7 @@ def reference_sibling(py_type: str) -> str:
139134
return f"{py_type}"
140135

141136

142-
def reference_descendent(current_package: List[str], imports: Set[str], py_package: List[str], py_type: str) -> str:
137+
def reference_descendent(current_package: list[str], imports: set[str], py_package: list[str], py_type: str) -> str:
143138
"""
144139
Returns a reference to a python type in a package that is a descendent of the
145140
current package, and adds the required import that is aliased to avoid name
@@ -157,7 +152,7 @@ def reference_descendent(current_package: List[str], imports: Set[str], py_packa
157152
return f"{string_import}.{py_type}"
158153

159154

160-
def reference_ancestor(current_package: List[str], imports: Set[str], py_package: List[str], py_type: str) -> str:
155+
def reference_ancestor(current_package: list[str], imports: set[str], py_package: list[str], py_type: str) -> str:
161156
"""
162157
Returns a reference to a python type in a package which is an ancestor to the
163158
current package, and adds the required import that is aliased (if possible) to avoid
@@ -178,7 +173,7 @@ def reference_ancestor(current_package: List[str], imports: Set[str], py_package
178173
return string_alias
179174

180175

181-
def reference_cousin(current_package: List[str], imports: Set[str], py_package: List[str], py_type: str) -> str:
176+
def reference_cousin(current_package: list[str], imports: set[str], py_package: list[str], py_type: str) -> str:
182177
"""
183178
Returns a reference to a python type in a package that is not descendent, ancestor
184179
or sibling, and adds the required import that is aliased to avoid name conflicts.

src/betterproto2_compiler/enum.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88
from typing import (
99
TYPE_CHECKING,
1010
Any,
11-
Dict,
12-
Tuple,
1311
)
1412

1513
if TYPE_CHECKING:
@@ -32,7 +30,7 @@ class EnumType(EnumMeta if TYPE_CHECKING else type):
3230
_value_map_: Mapping[int, Enum]
3331
_member_map_: Mapping[str, Enum]
3432

35-
def __new__(mcs, name: str, bases: Tuple[type, ...], namespace: Dict[str, Any]) -> Self:
33+
def __new__(mcs, name: str, bases: tuple[type, ...], namespace: dict[str, Any]) -> Self:
3634
value_map = {}
3735
member_map = {}
3836

src/betterproto2_compiler/plugin/models.py

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,12 @@
3131

3232
import builtins
3333
import re
34+
from collections.abc import Iterable, Iterator
3435
from dataclasses import (
3536
dataclass,
3637
field,
3738
)
3839
from typing import (
39-
Dict,
40-
Iterable,
41-
Iterator,
42-
List,
43-
Set,
44-
Type,
4540
Union,
4641
)
4742

@@ -145,7 +140,7 @@
145140

146141
def get_comment(
147142
proto_file: "FileDescriptorProto",
148-
path: List[int],
143+
path: list[int],
149144
) -> str:
150145
for sci_loc in proto_file.source_code_info.location:
151146
if list(sci_loc.path) == path:
@@ -181,10 +176,10 @@ class ProtoContentBase:
181176

182177
source_file: FileDescriptorProto
183178
typing_compiler: TypingCompiler
184-
path: List[int]
179+
path: list[int]
185180
parent: Union["betterproto2.Message", "OutputTemplate"]
186181

187-
__dataclass_fields__: Dict[str, object]
182+
__dataclass_fields__: dict[str, object]
188183

189184
def __post_init__(self) -> None:
190185
"""Checks that no fake default fields were left as placeholders."""
@@ -224,10 +219,10 @@ def deprecated(self) -> bool:
224219
@dataclass
225220
class PluginRequestCompiler:
226221
plugin_request_obj: CodeGeneratorRequest
227-
output_packages: Dict[str, "OutputTemplate"] = field(default_factory=dict)
222+
output_packages: dict[str, "OutputTemplate"] = field(default_factory=dict)
228223

229224
@property
230-
def all_messages(self) -> List["MessageCompiler"]:
225+
def all_messages(self) -> list["MessageCompiler"]:
231226
"""All of the messages in this request.
232227
233228
Returns
@@ -249,11 +244,11 @@ class OutputTemplate:
249244

250245
parent_request: PluginRequestCompiler
251246
package_proto_obj: FileDescriptorProto
252-
input_files: List[str] = field(default_factory=list)
253-
imports_end: Set[str] = field(default_factory=set)
254-
messages: Dict[str, "MessageCompiler"] = field(default_factory=dict)
255-
enums: Dict[str, "EnumDefinitionCompiler"] = field(default_factory=dict)
256-
services: Dict[str, "ServiceCompiler"] = field(default_factory=dict)
247+
input_files: list[str] = field(default_factory=list)
248+
imports_end: set[str] = field(default_factory=set)
249+
messages: dict[str, "MessageCompiler"] = field(default_factory=dict)
250+
enums: dict[str, "EnumDefinitionCompiler"] = field(default_factory=dict)
251+
services: dict[str, "ServiceCompiler"] = field(default_factory=dict)
257252
pydantic_dataclasses: bool = False
258253
output: bool = True
259254
typing_compiler: TypingCompiler = field(default_factory=DirectImportTypingCompiler)
@@ -289,9 +284,9 @@ class MessageCompiler(ProtoContentBase):
289284
typing_compiler: TypingCompiler
290285
parent: Union["MessageCompiler", OutputTemplate] = PLACEHOLDER
291286
proto_obj: DescriptorProto = PLACEHOLDER
292-
path: List[int] = PLACEHOLDER
293-
fields: List[Union["FieldCompiler", "MessageCompiler"]] = field(default_factory=list)
294-
builtins_types: Set[str] = field(default_factory=set)
287+
path: list[int] = PLACEHOLDER
288+
fields: list[Union["FieldCompiler", "MessageCompiler"]] = field(default_factory=list)
289+
builtins_types: set[str] = field(default_factory=set)
295290

296291
def __post_init__(self) -> None:
297292
# Add message to output file
@@ -327,11 +322,9 @@ def has_oneof_fields(self) -> bool:
327322
@property
328323
def has_message_field(self) -> bool:
329324
return any(
330-
(
331-
field.proto_obj.type in PROTO_MESSAGE_TYPES
332-
for field in self.fields
333-
if isinstance(field.proto_obj, FieldDescriptorProto)
334-
)
325+
field.proto_obj.type in PROTO_MESSAGE_TYPES
326+
for field in self.fields
327+
if isinstance(field.proto_obj, FieldDescriptorProto)
335328
)
336329

337330

@@ -373,8 +366,8 @@ def is_oneof(proto_field_obj: FieldDescriptorProto) -> bool:
373366
class FieldCompiler(ProtoContentBase):
374367
source_file: FileDescriptorProto
375368
typing_compiler: TypingCompiler
376-
path: List[int] = PLACEHOLDER
377-
builtins_types: Set[str] = field(default_factory=set)
369+
path: list[int] = PLACEHOLDER
370+
builtins_types: set[str] = field(default_factory=set)
378371

379372
parent: MessageCompiler = PLACEHOLDER
380373
proto_obj: FieldDescriptorProto = PLACEHOLDER
@@ -395,7 +388,7 @@ def get_field_string(self) -> str:
395388
return f'{name}: "{self.annotation}" = {betterproto_field_type}'
396389

397390
@property
398-
def betterproto_field_args(self) -> List[str]:
391+
def betterproto_field_args(self) -> list[str]:
399392
args = []
400393
if self.field_wraps:
401394
args.append(f"wraps={self.field_wraps}")
@@ -499,7 +492,7 @@ def optional(self) -> bool:
499492
return True
500493

501494
@property
502-
def betterproto_field_args(self) -> List[str]:
495+
def betterproto_field_args(self) -> list[str]:
503496
args = super().betterproto_field_args
504497
group = self.parent.proto_obj.oneof_decl[self.proto_obj.oneof_index].name
505498
args.append(f'group="{group}"')
@@ -508,8 +501,8 @@ def betterproto_field_args(self) -> List[str]:
508501

509502
@dataclass
510503
class MapEntryCompiler(FieldCompiler):
511-
py_k_type: Type | None = None
512-
py_v_type: Type | None = None
504+
py_k_type: type | None = None
505+
py_v_type: type | None = None
513506
proto_k_type: str = ""
514507
proto_v_type: str = ""
515508

@@ -547,7 +540,7 @@ def ready(self) -> None:
547540
raise ValueError("can't find enum")
548541

549542
@property
550-
def betterproto_field_args(self) -> List[str]:
543+
def betterproto_field_args(self) -> list[str]:
551544
return [f"betterproto2.{self.proto_k_type}", f"betterproto2.{self.proto_v_type}"]
552545

553546
@property
@@ -568,7 +561,7 @@ class EnumDefinitionCompiler(MessageCompiler):
568561
"""Representation of a proto Enum definition."""
569562

570563
proto_obj: EnumDescriptorProto = PLACEHOLDER
571-
entries: List["EnumDefinitionCompiler.EnumEntry"] = PLACEHOLDER
564+
entries: list["EnumDefinitionCompiler.EnumEntry"] = PLACEHOLDER
572565

573566
@dataclass(unsafe_hash=True)
574567
class EnumEntry:
@@ -596,8 +589,8 @@ class ServiceCompiler(ProtoContentBase):
596589
source_file: FileDescriptorProto
597590
parent: OutputTemplate = PLACEHOLDER
598591
proto_obj: DescriptorProto = PLACEHOLDER
599-
path: List[int] = PLACEHOLDER
600-
methods: List["ServiceMethodCompiler"] = field(default_factory=list)
592+
path: list[int] = PLACEHOLDER
593+
methods: list["ServiceMethodCompiler"] = field(default_factory=list)
601594

602595
def __post_init__(self) -> None:
603596
# Add service to output file
@@ -618,7 +611,7 @@ class ServiceMethodCompiler(ProtoContentBase):
618611
source_file: FileDescriptorProto
619612
parent: ServiceCompiler
620613
proto_obj: MethodDescriptorProto
621-
path: List[int] = PLACEHOLDER
614+
path: list[int] = PLACEHOLDER
622615

623616
def __post_init__(self) -> None:
624617
# Add method to service

src/betterproto2_compiler/plugin/module_validation.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
11
import re
22
from collections import defaultdict
3+
from collections.abc import Iterator
34
from dataclasses import (
45
dataclass,
56
field,
67
)
7-
from typing import (
8-
Dict,
9-
Iterator,
10-
List,
11-
Tuple,
12-
)
138

149

1510
@dataclass
1611
class ModuleValidator:
1712
line_iterator: Iterator[str]
1813
line_number: int = field(init=False, default=0)
1914

20-
collisions: Dict[str, List[Tuple[int, str]]] = field(init=False, default_factory=lambda: defaultdict(list))
15+
collisions: dict[str, list[tuple[int, str]]] = field(init=False, default_factory=lambda: defaultdict(list))
2116

2217
def add_import(self, imp: str, number: int, full_line: str):
2318
"""

src/betterproto2_compiler/plugin/parser.py

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import pathlib
22
import sys
3-
from typing import (
4-
Generator,
5-
List,
6-
Set,
7-
Tuple,
8-
)
3+
from collections.abc import Generator
94

105
from betterproto2_compiler.lib.google.protobuf import (
116
DescriptorProto,
@@ -44,13 +39,13 @@
4439

4540
def traverse(
4641
proto_file: FileDescriptorProto,
47-
) -> Generator[Tuple[EnumDescriptorProto | DescriptorProto, List[int]], None, None]:
42+
) -> Generator[tuple[EnumDescriptorProto | DescriptorProto, list[int]], None, None]:
4843
# Todo: Keep information about nested hierarchy
4944
def _traverse(
50-
path: List[int],
51-
items: List[EnumDescriptorProto] | List[DescriptorProto],
45+
path: list[int],
46+
items: list[EnumDescriptorProto] | list[DescriptorProto],
5247
prefix: str = "",
53-
) -> Generator[Tuple[EnumDescriptorProto | DescriptorProto, List[int]], None, None]:
48+
) -> Generator[tuple[EnumDescriptorProto | DescriptorProto, list[int]], None, None]:
5449
for i, item in enumerate(items):
5550
# Adjust the name since we flatten the hierarchy.
5651
# Todo: don't change the name, but include full name in returned tuple
@@ -143,7 +138,7 @@ def generate_code(request: CodeGeneratorRequest) -> CodeGeneratorResponse:
143138
service.ready()
144139

145140
# Generate output files
146-
output_paths: Set[pathlib.Path] = set()
141+
output_paths: set[pathlib.Path] = set()
147142
for output_package_name, output_package in request_data.output_packages.items():
148143
if not output_package.output:
149144
continue
@@ -182,7 +177,7 @@ def _make_one_of_field_compiler(
182177
source_file: "FileDescriptorProto",
183178
parent: MessageCompiler,
184179
proto_obj: "FieldDescriptorProto",
185-
path: List[int],
180+
path: list[int],
186181
) -> FieldCompiler:
187182
return OneOfFieldCompiler(
188183
source_file=source_file,
@@ -195,7 +190,7 @@ def _make_one_of_field_compiler(
195190

196191
def read_protobuf_type(
197192
item: DescriptorProto,
198-
path: List[int],
193+
path: list[int],
199194
source_file: "FileDescriptorProto",
200195
output_package: OutputTemplate,
201196
) -> None:

0 commit comments

Comments
 (0)