Skip to content

Commit ffe13bb

Browse files
Fix Python linting errors (#147)
* Resolve Python linting errors * Add missing docstrings to Python files Adds Google-style docstrings to public modules, classes, and functions in the 'scripts/' and 'test/python/' directories to resolve CI errors. * Resolve mypy type-checking errors Resolves mypy errors in Python scripts by adding missing type annotations, handling potential `None` values, and correcting import statements. * Fix minor `ruff check` regression from `mypy` fixes --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
1 parent d6e913e commit ffe13bb

File tree

10 files changed

+299
-35
lines changed

10 files changed

+299
-35
lines changed

scripts/check_codeql_alerts.py

Lines changed: 182 additions & 25 deletions
Large diffs are not rendered by default.

scripts/codeql_reset_dismissed_alerts.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import urllib.parse
2323
import urllib.request
2424
from dataclasses import dataclass
25-
from typing import Iterator, List, Optional
25+
from typing import Any, Iterator, List, Optional
2626

2727
API_ROOT = "https://api.github.com"
2828
API_VERSION = "2022-11-28"
@@ -45,7 +45,7 @@ def _request(
4545
*,
4646
params: Optional[dict] = None,
4747
payload: Optional[dict] = None,
48-
) -> dict:
48+
) -> Any:
4949
url = urllib.parse.urljoin(API_ROOT, path)
5050
if params:
5151
query = urllib.parse.urlencode(params)
@@ -99,6 +99,8 @@ def _paginate_alerts(owner: str, repo: str) -> Iterator[dict]:
9999

100100
@dataclass
101101
class Alert:
102+
"""Represents a dismissed CodeQL alert."""
103+
102104
number: int
103105
html_url: str
104106
rule_id: str
@@ -123,6 +125,14 @@ def _to_alert(raw: dict) -> Alert:
123125

124126

125127
def reopen_alert(owner: str, repo: str, alert: Alert, *, dry_run: bool) -> None:
128+
"""Reopens a dismissed CodeQL alert.
129+
130+
Args:
131+
owner: The GitHub organization or user.
132+
repo: The repository name.
133+
alert: The alert to reopen.
134+
dry_run: If True, print the action without executing it.
135+
"""
126136
if dry_run:
127137
print(f"DRY RUN: would reopen alert #{alert.number} ({alert.rule_id})")
128138
return
@@ -135,6 +145,14 @@ def reopen_alert(owner: str, repo: str, alert: Alert, *, dry_run: bool) -> None:
135145

136146

137147
def parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
148+
"""Parses command-line arguments.
149+
150+
Args:
151+
argv: The command-line arguments to parse.
152+
153+
Returns:
154+
The parsed arguments.
155+
"""
138156
parser = argparse.ArgumentParser(description=__doc__)
139157
parser.add_argument("--owner", required=True, help="GitHub organization or user")
140158
parser.add_argument("--repo", required=True, help="Repository name")
@@ -147,6 +165,14 @@ def parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
147165

148166

149167
def main(argv: Optional[List[str]] = None) -> int:
168+
"""The main entry point of the script.
169+
170+
Args:
171+
argv: The command-line arguments.
172+
173+
Returns:
174+
The exit code.
175+
"""
150176
args = parse_args(argv)
151177
try:
152178
alerts = [_to_alert(raw) for raw in _paginate_alerts(args.owner, args.repo)]

scripts/create_coverage_symlinks.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,14 @@
3434

3535

3636
def should_link(path: pathlib.Path) -> bool:
37+
"""Checks if a file should be symlinked for coverage analysis.
38+
39+
Args:
40+
path: The path to the file.
41+
42+
Returns:
43+
True if the file should be symlinked, False otherwise.
44+
"""
3745
if not path.is_file():
3846
return False
3947
suffix = path.suffix
@@ -49,6 +57,14 @@ def should_link(path: pathlib.Path) -> bool:
4957

5058

5159
def iter_source_files(build_root: pathlib.Path) -> Iterable[pathlib.Path]:
60+
"""Iterates over all source files in a directory.
61+
62+
Args:
63+
build_root: The root directory to search.
64+
65+
Yields:
66+
Paths to the source files.
67+
"""
5268
for root, _dirs, files in os.walk(build_root):
5369
root_path = pathlib.Path(root)
5470
for filename in files:
@@ -58,6 +74,12 @@ def iter_source_files(build_root: pathlib.Path) -> Iterable[pathlib.Path]:
5874

5975

6076
def create_symlinks(build_root: pathlib.Path, output_root: pathlib.Path) -> None:
77+
"""Creates symlinks for all source files in a directory.
78+
79+
Args:
80+
build_root: The root directory containing the source files.
81+
output_root: The directory where the symlinks will be created.
82+
"""
6183
if output_root.exists():
6284
shutil.rmtree(output_root)
6385
output_root.mkdir(parents=True, exist_ok=True)
@@ -79,13 +101,29 @@ def create_symlinks(build_root: pathlib.Path, output_root: pathlib.Path) -> None
79101

80102

81103
def parse_args(argv: Iterable[str]) -> argparse.Namespace:
104+
"""Parses command-line arguments.
105+
106+
Args:
107+
argv: The command-line arguments to parse.
108+
109+
Returns:
110+
The parsed arguments.
111+
"""
82112
parser = argparse.ArgumentParser(description="Create coverage symlink tree")
83113
parser.add_argument("--build-root", required=True)
84114
parser.add_argument("--output-root", required=True)
85115
return parser.parse_args(list(argv)[1:])
86116

87117

88118
def main(argv: Iterable[str]) -> int:
119+
"""The main entry point of the script.
120+
121+
Args:
122+
argv: The command-line arguments.
123+
124+
Returns:
125+
The exit code.
126+
"""
89127
args = parse_args(argv)
90128
build_root = pathlib.Path(args.build_root).resolve()
91129
output_root = pathlib.Path(args.output_root).resolve()

scripts/export_llvm_lcov.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@
1111

1212

1313
def build_parser() -> argparse.ArgumentParser:
14+
"""Builds the command-line argument parser.
15+
16+
Returns:
17+
The argument parser.
18+
"""
1419
parser = argparse.ArgumentParser(
1520
description="Run llvm-cov export and write the LCOV data to a file."
1621
)
@@ -28,6 +33,14 @@ def build_parser() -> argparse.ArgumentParser:
2833

2934

3035
def main(argv: list[str] | None = None) -> int:
36+
"""The main entry point of the script.
37+
38+
Args:
39+
argv: The command-line arguments.
40+
41+
Returns:
42+
The exit code.
43+
"""
3144
parser = build_parser()
3245
args = parser.parse_args(argv)
3346

scripts/normalize_coverage_xml.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,17 @@ def _usable_prefix(prefix: Path | None) -> Path | None:
208208

209209
absolute_candidate = (repo_root_resolved / relative).resolve()
210210

211-
cls.set("filename", relative.as_posix())
211+
if relative is not None:
212+
cls.set("filename", relative.as_posix())
212213

213-
candidate = repo_root / relative
214-
candidate_resolved = absolute_candidate
215-
if not candidate.exists() and not candidate_resolved.exists():
216-
missing.append(relative.as_posix())
214+
candidate = repo_root / relative
215+
if absolute_candidate is not None:
216+
candidate_resolved = absolute_candidate
217+
else:
218+
candidate_resolved = candidate.resolve()
219+
220+
if not candidate.exists() and not candidate_resolved.exists():
221+
missing.append(relative.as_posix())
217222

218223
tree.write(report_path)
219224
return missing, external

scripts/sarif-alerts.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""A simple tool to print SARIF results from one or more SARIF files."""
12
import argparse
23
import json
34
from pathlib import Path
@@ -26,6 +27,14 @@ def _process_sarif(path: Path) -> Iterable[str]:
2627

2728

2829
def main(argv=None) -> int:
30+
"""The main entry point of the script.
31+
32+
Args:
33+
argv: The command-line arguments.
34+
35+
Returns:
36+
The exit code.
37+
"""
2938
parser = argparse.ArgumentParser(
3039
description="Print SARIF results from one or more SARIF files"
3140
)

test/python/adder.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""This module defines a simple C++ function using cppyy."""
12
import cppyy
23

34
cppyy.cppdef("""\

test/python/pyphlex.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
# `with` is a keyword in Python, so can not be the name of a method; fix this
2929
# by renaming it to `with_` for all phlex classes
3030
def fixwith(klass, name):
31+
"""A cppyy pythonization to rename the 'with' method to 'with_'.
32+
33+
Args:
34+
klass: The class to pythonize.
35+
name: The name of the class.
36+
"""
3137
try:
3238
klass.with_ = getattr(klass, "with")
3339
except AttributeError:

test/python/registry.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
"""This module provides a function to register Python algorithms with the Phlex framework."""
2+
import types
3+
14
import cppyy
25
import pyphlex # noqa: F401
36

@@ -7,7 +10,7 @@
710

811
cppyy.include("Python.h")
912

10-
_registered_modules = dict()
13+
_registered_modules: dict[str, types.ModuleType] = {}
1114

1215

1316
def register(m, config):

test/python/test_phlex.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
"""This module contains tests for the pyphlex module."""
2+
3+
14
class TestPYPHLEX:
5+
"""Tests for the pyphlex module."""
6+
27
@classmethod
38
def setup_class(cls):
9+
"""Set up the test class."""
410
import pyphlex # noqa: F401
511

6-
__all__ = ["pyphlex"] # For CodeQL
12+
__all__ = ["pyphlex"] # noqa: F841 # For CodeQL
713

814
def test01_phlex_existence(self):
9-
"""Test existence of the phlex namespace"""
15+
"""Test existence of the phlex namespace."""
1016
import cppyy
1117

1218
assert cppyy.gbl.phlex

0 commit comments

Comments
 (0)