Skip to content

Commit 6247451

Browse files
Merge pull request #129 from r1chardj0n3s/ruff
Switch from isort and flake8 to ruff
2 parents 94061f2 + eeca5bf commit 6247451

File tree

12 files changed

+154
-133
lines changed

12 files changed

+154
-133
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ jobs:
5555
5656
- name: "Lint"
5757
run: |
58-
flake8 *.py pip_check_reqs tests
5958
mypy .
60-
isort --check-only .
59+
ruff .
6160
black --check .
6261
pylint pip_check_reqs tests
6362
pip-extra-reqs pip_check_reqs

pip_check_reqs/common.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Common functions."""
22

3+
from __future__ import annotations
4+
35
import ast
46
import fnmatch
57
import imp
@@ -11,14 +13,8 @@
1113
from pathlib import Path
1214
from typing import (
1315
Callable,
14-
Dict,
1516
Generator,
1617
Iterable,
17-
List,
18-
Optional,
19-
Set,
20-
Tuple,
21-
Union,
2218
)
2319

2420
from packaging.markers import Marker
@@ -38,7 +34,7 @@ class FoundModule:
3834

3935
modname: str
4036
filename: str
41-
locations: List[Tuple[str, int]] = field(default_factory=list)
37+
locations: list[tuple[str, int]] = field(default_factory=list)
4238

4339
def __post_init__(self) -> None:
4440
self.filename = os.path.realpath(self.filename)
@@ -48,22 +44,22 @@ class _ImportVisitor(ast.NodeVisitor):
4844
def __init__(self, ignore_modules_function: Callable[[str], bool]) -> None:
4945
super().__init__()
5046
self._ignore_modules_function = ignore_modules_function
51-
self._modules: Dict[str, FoundModule] = {}
52-
self._location: Optional[str] = None
47+
self._modules: dict[str, FoundModule] = {}
48+
self._location: str | None = None
5349

5450
def set_location(self, location: str) -> None:
5551
self._location = location
5652

5753
# Ignore the name error as we are overriding the method.
58-
def visit_Import( # pylint: disable=invalid-name
54+
def visit_Import( # noqa: N802, pylint: disable=invalid-name
5955
self,
6056
node: ast.Import,
6157
) -> None:
6258
for alias in node.names:
6359
self._add_module(alias.name, node.lineno)
6460

6561
# Ignore the name error as we are overriding the method.
66-
def visit_ImportFrom( # pylint: disable=invalid-name
62+
def visit_ImportFrom( # noqa: N802, pylint: disable=invalid-name
6763
self,
6864
node: ast.ImportFrom,
6965
) -> None:
@@ -103,7 +99,7 @@ def _add_module(self, modname: str, lineno: int) -> None:
10399
break
104100

105101
# ... though it might not be a file, so not interesting to us
106-
if not os.path.isdir(modpath):
102+
if not Path(modpath).is_dir():
107103
break
108104

109105
path = [modpath]
@@ -119,17 +115,17 @@ def _add_module(self, modname: str, lineno: int) -> None:
119115
assert isinstance(self._location, str)
120116
self._modules[modname].locations.append((self._location, lineno))
121117

122-
def finalise(self) -> Dict[str, FoundModule]:
123-
result = self._modules
124-
return result
118+
def finalise(self) -> dict[str, FoundModule]:
119+
return self._modules
125120

126121

127122
def pyfiles(root: Path) -> Generator[Path, None, None]:
128123
if root.is_file():
129124
if root.suffix == ".py":
130125
yield root.absolute()
131126
else:
132-
raise ValueError(f"{root} is not a python file or directory")
127+
msg = f"{root} is not a python file or directory"
128+
raise ValueError(msg)
133129
elif root.is_dir():
134130
for item in root.rglob("*.py"):
135131
yield item.absolute()
@@ -139,31 +135,33 @@ def find_imported_modules(
139135
paths: Iterable[Path],
140136
ignore_files_function: Callable[[str], bool],
141137
ignore_modules_function: Callable[[str], bool],
142-
) -> Dict[str, FoundModule]:
138+
) -> dict[str, FoundModule]:
143139
vis = _ImportVisitor(ignore_modules_function=ignore_modules_function)
144140
for path in paths:
145141
for filename in pyfiles(path):
146142
if ignore_files_function(str(filename)):
147143
log.info("ignoring: %s", os.path.relpath(filename))
148144
continue
149145
log.debug("scanning: %s", os.path.relpath(filename))
150-
with open(filename, encoding="utf-8") as file_obj:
151-
content = file_obj.read()
146+
content = filename.read_text(encoding="utf-8")
152147
vis.set_location(str(filename))
153148
vis.visit(ast.parse(content, str(filename)))
154149
return vis.finalise()
155150

156151

157152
def find_required_modules(
153+
*,
158154
ignore_requirements_function: Callable[
159-
[Union[str, ParsedRequirement]], bool
155+
[str | ParsedRequirement],
156+
bool,
160157
],
161158
skip_incompatible: bool,
162159
requirements_filename: Path,
163-
) -> Set[NormalizedName]:
160+
) -> set[NormalizedName]:
164161
explicit = set()
165162
for requirement in parse_requirements(
166-
str(requirements_filename), session=PipSession()
163+
str(requirements_filename),
164+
session=PipSession(),
167165
):
168166
requirement_name = install_req_from_line(
169167
requirement.requirement,
@@ -202,22 +200,23 @@ def has_compatible_markers(full_requirement: str) -> bool:
202200

203201

204202
def is_package_file(path: str) -> str:
205-
"""Determines whether the path points to a Python package sentinel
206-
file - the __init__.py or its compiled variants.
203+
"""Determine whether the path points to a Python package sentinel file.
204+
205+
A sentinel file is the __init__.py or its compiled variants.
207206
"""
208207
search_result = re.search(r"(.+)/__init__\.py[co]?$", path)
209208
if search_result is not None:
210209
return search_result.group(1)
211210
return ""
212211

213212

214-
def ignorer(ignore_cfg: List[str]) -> Callable[..., bool]:
213+
def ignorer(ignore_cfg: list[str]) -> Callable[..., bool]:
215214
if not ignore_cfg:
216-
return lambda candidate: False
215+
return lambda _: False
217216

218217
def ignorer_function(
219-
candidate: Union[str, ParsedRequirement],
220-
ignore_cfg: List[str] = ignore_cfg,
218+
candidate: str | ParsedRequirement,
219+
ignore_cfg: list[str] = ignore_cfg,
221220
) -> bool:
222221
for ignore in ignore_cfg:
223222
if isinstance(candidate, str):

pip_check_reqs/find_extra_reqs.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,41 @@
11
"""Find extra requirements."""
22

3+
from __future__ import annotations
4+
35
import argparse
46
import collections
57
import importlib.metadata
68
import logging
79
import os
810
import sys
911
from pathlib import Path
10-
from typing import Callable, Iterable, List, Optional, Union
12+
from typing import TYPE_CHECKING, Callable, Iterable
1113
from unittest import mock
1214

1315
from packaging.utils import canonicalize_name
1416
from pip._internal.commands.show import search_packages_info
15-
from pip._internal.req.req_file import ParsedRequirement
1617

1718
from pip_check_reqs import common
1819
from pip_check_reqs.common import version_info
1920

21+
if TYPE_CHECKING:
22+
from pip._internal.req.req_file import ParsedRequirement
23+
2024
log = logging.getLogger(__name__)
2125

2226

2327
def find_extra_reqs(
28+
*,
2429
requirements_filename: Path,
2530
paths: Iterable[Path],
2631
ignore_files_function: Callable[[str], bool],
2732
ignore_modules_function: Callable[[str], bool],
2833
ignore_requirements_function: Callable[
29-
[Union[str, ParsedRequirement]], bool
34+
[str | ParsedRequirement],
35+
bool,
3036
],
3137
skip_incompatible: bool,
32-
) -> List[str]:
38+
) -> list[str]:
3339
# 1. find files used by imports in the code (as best we can without
3440
# executing)
3541
used_modules = common.find_imported_modules(
@@ -55,7 +61,7 @@ def find_extra_reqs(
5561
package_location = package.location
5662
package_files = []
5763
for item in package.files or []:
58-
here = Path(".").resolve()
64+
here = Path().resolve()
5965
item_location_rel = Path(package_location) / item
6066
item_location = item_location_rel.resolve()
6167
try:
@@ -68,11 +74,13 @@ def find_extra_reqs(
6874
package_files.append(str(relative_item_location))
6975

7076
log.debug(
71-
"installed package: %s (at %s)", package_name, package_location
77+
"installed package: %s (at %s)",
78+
package_name,
79+
package_location,
7280
)
7381
for package_file in package_files:
7482
path = os.path.realpath(
75-
os.path.join(package_location, package_file),
83+
Path(package_location) / package_file,
7684
)
7785
installed_files[path] = package_name
7886
package_path = common.is_package_file(path)
@@ -112,8 +120,8 @@ def find_extra_reqs(
112120
return [name for name in explicit if name not in used]
113121

114122

115-
def main(arguments: Optional[List[str]] = None) -> None:
116-
"""Main entry point."""
123+
def main(arguments: list[str] | None = None) -> None:
124+
"""pip-extra-reqs entry point."""
117125
usage = "usage: %prog [options] files or directories"
118126
parser = argparse.ArgumentParser(usage)
119127
parser.add_argument("paths", type=Path, nargs="*")
@@ -156,7 +164,7 @@ def main(arguments: Optional[List[str]] = None) -> None:
156164
dest="skip_incompatible",
157165
action="store_true",
158166
default=False,
159-
help="skip requirements that have incompatible " "environment markers",
167+
help="skip requirements that have incompatible environment markers",
160168
)
161169
parser.add_argument(
162170
"-v",
@@ -186,7 +194,7 @@ def main(arguments: Optional[List[str]] = None) -> None:
186194
parse_result = parser.parse_args(arguments)
187195

188196
if parse_result.version:
189-
print(version_info())
197+
sys.stdout.write(version_info() + "\n")
190198
sys.exit(0)
191199

192200
if not parse_result.paths:

pip_check_reqs/find_missing_reqs.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
"""Find missing requirements."""
22

3+
from __future__ import annotations
4+
35
import argparse
46
import collections
57
import importlib.metadata
68
import logging
79
import os
810
import sys
911
from pathlib import Path
10-
from typing import Callable, Iterable, List, Optional, Tuple
12+
from typing import Callable, Iterable
1113
from unittest import mock
1214

1315
from packaging.utils import NormalizedName, canonicalize_name
@@ -27,7 +29,7 @@ def find_missing_reqs(
2729
paths: Iterable[Path],
2830
ignore_files_function: Callable[[str], bool],
2931
ignore_modules_function: Callable[[str], bool],
30-
) -> List[Tuple[NormalizedName, List[FoundModule]]]:
32+
) -> list[tuple[NormalizedName, list[FoundModule]]]:
3133
# 1. find files used by imports in the code (as best we can without
3234
# executing)
3335
used_modules = common.find_imported_modules(
@@ -53,7 +55,7 @@ def find_missing_reqs(
5355
package_location = package.location
5456
package_files = []
5557
for item in package.files or []:
56-
here = Path(".").resolve()
58+
here = Path().resolve()
5759
item_location_rel = Path(package_location) / item
5860
item_location = item_location_rel.resolve()
5961
try:
@@ -66,11 +68,13 @@ def find_missing_reqs(
6668
package_files.append(str(relative_item_location))
6769

6870
log.debug(
69-
"installed package: %s (at %s)", package_name, package_location
71+
"installed package: %s (at %s)",
72+
package_name,
73+
package_location,
7074
)
7175
for package_file in package_files:
7276
path = os.path.realpath(
73-
os.path.join(package_location, package_file),
77+
str(Path(package_location) / package_file),
7478
)
7579
installed_files[path] = package_name
7680
package_path = common.is_package_file(path)
@@ -113,11 +117,10 @@ def find_missing_reqs(
113117
log.debug("found requirement: %s", requirement_name)
114118
explicit.add(canonicalize_name(requirement_name))
115119

116-
result = [(name, used[name]) for name in used if name not in explicit]
117-
return result
120+
return [(name, used[name]) for name in used if name not in explicit]
118121

119122

120-
def main(arguments: Optional[List[str]] = None) -> None:
123+
def main(arguments: list[str] | None = None) -> None:
121124
usage = "usage: %prog [options] files or directories"
122125
parser = argparse.ArgumentParser(usage)
123126
parser.add_argument("paths", type=Path, nargs="*")
@@ -174,7 +177,7 @@ def main(arguments: Optional[List[str]] = None) -> None:
174177
parse_result = parser.parse_args(arguments)
175178

176179
if parse_result.version:
177-
print(version_info())
180+
sys.stdout.write(version_info() + "\n")
178181
sys.exit(0)
179182

180183
if not parse_result.paths:

0 commit comments

Comments
 (0)