Skip to content

Commit 448dd7d

Browse files
authored
refactor: improve codebase using ruff (#305)
1 parent 5fa396c commit 448dd7d

10 files changed

Lines changed: 190 additions & 103 deletions

File tree

pep517backend/backend.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
from typing import Any
4+
from typing import TYPE_CHECKING
45

56
import itertools
67
import logging
@@ -10,6 +11,9 @@
1011

1112
import setuptools.build_meta as _orig
1213

14+
if TYPE_CHECKING:
15+
from _typeshed import StrPath
16+
1317
logging.basicConfig(level="INFO", format="%(levelname)s: %(message)s")
1418
log = logging.getLogger()
1519

@@ -93,12 +97,14 @@ def _install_stubs(stub_config: list[LibVersion]) -> None:
9397
new_stub_path.write_text(f"from ._{lib} import *")
9498

9599

96-
def get_requires_for_build_editable(config_settings: Any | None = None) -> list[str]:
100+
def get_requires_for_build_editable(
101+
config_settings: _orig._ConfigSettings | None = None,
102+
) -> list[str]:
97103
return _orig.get_requires_for_build_editable(config_settings)
98104

99105

100106
def prepare_metadata_for_build_editable(
101-
metadata_directory: Any, config_settings: Any | None = None
107+
metadata_directory: StrPath, config_settings: _orig._ConfigSettings | None = None
102108
) -> str:
103109
return _orig.prepare_metadata_for_build_editable(
104110
metadata_directory, config_settings
@@ -113,19 +119,19 @@ def build_editable(
113119
return _orig.build_editable(wheel_directory, config_settings, metadata_directory)
114120

115121

116-
def get_requires_for_build_sdist(*args: Any, **kwargs: Any) -> str:
122+
def get_requires_for_build_sdist(*args: Any, **kwargs: Any) -> str: # noqa: ANN401
117123
return _orig.get_requires_for_build_sdist(*args, **kwargs)
118124

119125

120-
def build_sdist(*args: Any, **kwargs: Any) -> str:
126+
def build_sdist(*args: Any, **kwargs: Any) -> str: # noqa: ANN401
121127
return _orig.build_sdist(*args, **kwargs)
122128

123129

124-
def get_requires_for_build_wheel(*args: Any, **kwargs: Any) -> str:
130+
def get_requires_for_build_wheel(*args: Any, **kwargs: Any) -> str: # noqa: ANN401
125131
return _orig.get_requires_for_build_wheel(*args, **kwargs)
126132

127133

128-
def prepare_metadata_for_build_wheel(*args: Any, **kwargs: Any) -> str:
134+
def prepare_metadata_for_build_wheel(*args: Any, **kwargs: Any) -> str: # noqa: ANN401
129135
return _orig.prepare_metadata_for_build_wheel(*args, **kwargs)
130136

131137

@@ -141,10 +147,8 @@ def build_wheel(
141147
_check_config(stub_config)
142148
_install_stubs(stub_config)
143149

144-
basename = _orig.build_wheel(
150+
return _orig.build_wheel(
145151
wheel_directory,
146152
config_settings=config_settings,
147153
metadata_directory=metadata_directory,
148154
)
149-
150-
return basename

pyproject.toml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,27 @@ exclude = [
6161

6262
[tool.ruff.lint]
6363
select = [
64-
"PYI", # flake8-pyi
65-
"UP",
66-
"I001", # isort
67-
"F401", # unused imports
64+
"ANN", # flake8-annotations
65+
"B", # flake8-bugbear
66+
"C4", # flake8-comprehensions
67+
"E", # pycodestyle errors
68+
"EXE", # flake8-executable
69+
"F", # pyflakes
70+
"I", # isort
71+
"INP", # flake8-no-pep420
72+
"ISC", # flake8-implicit-str-concat
73+
"PIE", # flake8-pie
74+
"PTH", # flake8-use-pathlib
75+
"PYI", # flake8-pyi
76+
"Q", # flake8-quotes
77+
"RET", # flake8-return
78+
"RSE", # flake8-raise
79+
"SIM", # flake8-simplify
80+
"T10", # flake8-debugger
81+
"TC", # flake8-type-checking
82+
"UP", # pyupgrade
83+
"W", # pycodestyle warnings
84+
"RUF", # ruff-specific rules
6885
]
6986
ignore = [
7087
"PYI001", # Name of private `TypeVar` must start with `_`
@@ -78,13 +95,15 @@ ignore = [
7895
]
7996

8097
[tool.ruff.lint.per-file-ignores]
81-
"src/pygobject_stub_generator/**/*.py" = ["PYI"]
98+
"src/gi-stubs/*.pyi" = ["ANN", "E501", "E701", "E741", "F403", "F405", "F811", "F821", "I002", "PTH", "TC", "T10", "RUF002"]
99+
"src/pygobject_stub_generator/*.py" = ["PYI"]
82100

83101
[tool.ruff.lint.isort]
84102
case-sensitive = false
85103
order-by-type = false
86104
force-single-line = true
87105
section-order = ["future", "typing", "standard-library", "third-party", "first-party", "local-folder"]
106+
required-imports = ["from __future__ import annotations"]
88107

89108
[tool.ruff.lint.isort.sections]
90109
typing = ["_typeshed", "typing", "typing_extensions"]

src/pygobject_stub_generator/class_info.py

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def _find_attributes(obj: type[Any]) -> list[str]:
5151
if "__info__" in base.__dict__:
5252
obj_attrs.update(base.__dict__.keys())
5353

54-
return sorted(list(obj_attrs))
54+
return sorted(obj_attrs)
5555

5656

5757
@dataclass(slots=True)
@@ -144,17 +144,26 @@ def __get_bases_and_gi_info(
144144
object_info: GI.RegisteredTypeInfo | None = self.cls.__dict__.get("__info__")
145145
bases = list(get_original_bases(self.cls))
146146

147-
# Because we're generating types for gi.repository, we have to generate stubs for
148-
# override classes that come from gi.repository and inherit from gi.repository classes.
149-
# Effectively, we want to write the stubs as if the override class and repository class
150-
# are one class in the MRO. What this means is that the following transformations need to
151-
# happen:
147+
# Because we're generating types for gi.repository, we have to generate stubs
148+
# for override classes that come from gi.repository and inherit from
149+
# gi.repository classes. Effectively, we want to write the stubs as if the
150+
# override class and repository class are one class in the MRO. What this means
151+
# is that the following transformations need to happen:
152152
# 1. For the following:
153153
# gi.repository.X.One(<One repository bases>)
154-
# gi.overrides.X.One(<One prefix override bases>, gi.repository.X.One, <One suffix override bases>) ->
155-
# gi.repository.X.One(<One prefix override bases>, <One repository bases>, <One override bases>)
154+
# gi.overrides.X.One(
155+
# <One prefix override bases>,
156+
# gi.repository.X.One,
157+
# <One suffix override bases>
158+
# ) -> gi.repository.X.One(
159+
# <One prefix override bases>,
160+
# <One repository bases>,
161+
# <One override bases>
162+
# )
156163
# 2. gi.overrides.X.Two(float) -> gi.repository.X.Two(float)
157-
# 3. gi.overrides.X.Three(gi.overrides.X.Four, ...) -> gi.repository.X.Three(gi.repository.X.Four, ...)
164+
# 3. gi.overrides.X.Three(gi.overrides.X.Four, ...) -> gi.repository.X.Three(
165+
# gi.repository.X.Four, ...
166+
# )
158167
if full_module_name.startswith("gi.overrides.") and any(
159168
base.__module__.startswith("gi.repository.") for base in bases
160169
):
@@ -290,8 +299,7 @@ def __build_docstring(self) -> str | None:
290299
).strip()
291300

292301
if docs:
293-
docs = '"""\n' + docs.strip() + '\n"""'
294-
return docs
302+
return '"""\n' + docs.strip() + '\n"""'
295303

296304
return None
297305

@@ -324,7 +332,9 @@ def __build_props_class(self) -> str | None:
324332
parent := self.gi_info.get_parent()
325333
):
326334
parent_name = f"{parent.get_name()}"
327-
parents_string = f"({self.stub.get_namespace_member(parent.get_namespace(), parent_name)}.Props)"
335+
parents_string = f"({
336+
self.stub.get_namespace_member(parent.get_namespace(), parent_name)
337+
}.Props)"
328338

329339
return f"""@{self.stub.get_import("typing", "type_check_only")}
330340
class Props{parents_string}:
@@ -353,7 +363,7 @@ def __build_props(self) -> str | None:
353363
def __build_fields(self) -> str:
354364
lines: list[str] = []
355365

356-
for field in self.fields:
366+
for field in self.fields: # noqa: F402
357367
name = f"{field.get_name()}"
358368

359369
if override := self.stub.check_override(self.full_name, name):

src/pygobject_stub_generator/main.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,9 @@ def main() -> None:
8484
parser.add_argument(
8585
"--init",
8686
type=str,
87-
help='Initialization code that must be evaluated first e.g. \'gi.require_version("Gst", "1.0"); from gi.repository import Gst; Gst.init(None)\'',
87+
help="Initialization code that must be evaluated first e.g. "
88+
'\'gi.require_version("Gst", "1.0"); from gi.repository import Gst; '
89+
"Gst.init(None)'",
8890
)
8991
parser.add_argument(
9092
"--format",

src/pygobject_stub_generator/parse.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ def _search_overridden_symbols(input: str) -> list[str]:
6464
) / INDENTATION_SPACES
6565
if indentation_level != int(indentation_level):
6666
raise ParseError(
67-
f"Wrong indentation at line: {i}, {indentation_level} != {int(indentation_level)}"
67+
f"Wrong indentation at line: {i}, {indentation_level} != {
68+
int(indentation_level)
69+
}"
6870
)
6971
indentation_level = int(indentation_level)
7072

@@ -75,12 +77,10 @@ def _search_overridden_symbols(input: str) -> list[str]:
7577
else:
7678
if index != CONSTANT_INDEX:
7779
raise ParseError(f"Wrong indentation at line: {i}")
78-
else:
79-
# Regex for constant trigger also on functions arguments
80-
print(
81-
f"Wrong indentation for constant at line {i}, skipping"
82-
)
83-
continue
80+
81+
# Regex for constant trigger also on functions arguments
82+
print(f"Wrong indentation for constant at line {i}, skipping")
83+
continue
8484
elif indentation_level < last_indentation_level:
8585
while indentation_level < last_indentation_level:
8686
parents.pop()
@@ -93,7 +93,8 @@ def _search_overridden_symbols(input: str) -> list[str]:
9393
symbols.append(".".join(full_list))
9494

9595
break
96-
elif res:
96+
97+
if res:
9798
raise ParseError(f"Unable to parse line {i}: '{line}'")
9899

99100
class_res = re.match(CLASS_PATTERN, line)
@@ -166,15 +167,16 @@ def _generate_result_node(
166167
return
167168

168169
if isinstance(node, ast.Assign):
169-
if typevars is not None:
170-
if isinstance(node.value, ast.Call) and isinstance(
171-
node.value.func, ast.Name
172-
):
173-
if node.value.func.id == "TypeVar":
174-
typevars.append(TypeVarInfo.from_call(node.value))
175-
176-
if node.value.func.id == "TypeVarTuple":
177-
typevars.append(TypeVarTupleInfo.from_call(node.value))
170+
if (
171+
typevars is not None
172+
and isinstance(node.value, ast.Call)
173+
and isinstance(node.value.func, ast.Name)
174+
):
175+
if node.value.func.id == "TypeVar":
176+
typevars.append(TypeVarInfo.from_call(node.value))
177+
178+
if node.value.func.id == "TypeVarTuple":
179+
typevars.append(TypeVarTupleInfo.from_call(node.value))
178180

179181
if not hasattr(node.targets[0], "id"):
180182
print(f"Skipping {'.'.join(parents)} {node} no id attribute")

0 commit comments

Comments
 (0)