Skip to content

Commit 4280ef1

Browse files
manage-repositories-app[bot]renovate[bot]myakove
authored
ci(deps): lock file maintenance (main) (#2702) (#2716)
* ci(deps): lock file maintenance * Update Python compatibility markers and modernize code Update resolution markers to support Python 3.12 as primary version with 3.11 as fallback. Modernize Python 3.10+ syntax by replacing typing constructs with built-in generics (Optional → None union, List → list, Tuple → tuple). Update imports to use traceback at module level and refactor error handling from assert to raise AssertionError. Simplify failure summary output by removing truncation logic. Replace uv.lock with updated dependencies reflecting Python version changes. * chore: update pre-commit dependencies Update ruff to v0.15.12, gitleaks to v8.30.1, and mypy to v1.20.2. Also remove unnecessary space in string join operation in test fixture. * Fix CLI tool invocations with missing configuration flags Update pytest, prek, and ruff commands to include their required configuration flags. Add `--group tests` to pytest invocation, add `-c .pre-commit-config.yaml` to prek invocation, and add `--config pyproject.toml` to ruff invocation. Also remove extra space in string join operation for consistency. * test: Update pytest invocation with test dependency group The pytest command in the CLI test now includes the `--group tests` flag to ensure the test dependencies are available when running pytest through the uv package manager. * Refactor imports in class_generator_template.j2 Reorganize imports to improve readability and add conditional import for MissingRequiredArgumentError. The exception import is now only included when there are required arguments that will actually use it, reducing unnecessary dependencies in generated classes with no required arguments. * Remove extra blank line in class_generator_template.j2 * Improve file formatting with prek and ruff fallback Add ruff as a fallback formatter when prek fails. Extract project root path calculation to module level and pass configuration paths explicitly to prek. Introduce _run_ruff_fallback() helper that runs ruff check and ruff format sequentially. Update logging to clarify fallback behavior and fix typo in prek stdout log message. --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Meni Yakove <myakove@gmail.com>
1 parent 4556648 commit 4280ef1

8 files changed

Lines changed: 68 additions & 34 deletions

File tree

.pre-commit-config.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,18 @@ repos:
4545
]
4646

4747
- repo: https://github.com/astral-sh/ruff-pre-commit
48-
rev: v0.15.0
48+
rev: v0.15.12
4949
hooks:
5050
- id: ruff
5151
- id: ruff-format
5252

5353
- repo: https://github.com/gitleaks/gitleaks
54-
rev: v8.30.0
54+
rev: v8.30.1
5555
hooks:
5656
- id: gitleaks
5757

5858
- repo: https://github.com/pre-commit/mirrors-mypy
59-
rev: v1.19.1
59+
rev: v1.20.2
6060
hooks:
6161
- id: mypy
6262
exclude: ^(tests/|examples/|docs/)

class_generator/cli.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ def handle_test_generation(add_tests: bool) -> None:
489489
# Run the generated test file
490490
LOGGER.info("Running generated tests...")
491491
test_file = "class_generator/tests/test_class_generator.py"
492-
exit_code = os.system(f"uv run pytest {test_file}")
492+
exit_code = os.system(f"uv run --group tests pytest {test_file}")
493493

494494
# os.system returns the exit status shifted left by 8 bits
495495
if exit_code != 0:
Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
"""File writing utilities for generated code."""
22

3+
from pathlib import Path
4+
35
from pyhelper_utils.shell import run_command
46
from simple_logger.logger import get_logger
57

68
LOGGER = get_logger(name=__name__)
79

10+
# Project root directory (contains pyproject.toml and .pre-commit-config.yaml)
11+
_PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
12+
813

914
def write_and_format_rendered(filepath: str, output: str) -> None:
1015
"""
11-
Write rendered content to file and format it with prek.
16+
Write rendered content to file and format with prek, falling back to ruff.
1217
1318
Args:
1419
filepath: Path to write the file to
@@ -17,20 +22,50 @@ def write_and_format_rendered(filepath: str, output: str) -> None:
1722
with open(filepath, "w", encoding="utf-8") as fd:
1823
fd.write(output)
1924

20-
# Run prek on the file
25+
pre_commit_config = str(_PROJECT_ROOT / ".pre-commit-config.yaml")
26+
pyproject_toml = str(_PROJECT_ROOT / "pyproject.toml")
27+
28+
# Try prek first (runs all pre-commit hooks including ruff)
29+
prek_success = False
2130
try:
2231
rc, stdout, stderr = run_command(
23-
command=["uvx", "prek", "run", "--files", filepath],
32+
command=["uvx", "prek", "-c", pre_commit_config, "run", "--files", filepath],
2433
verify_stderr=False,
2534
check=False,
2635
log_errors=False,
2736
)
2837
if not rc:
2938
if stderr:
30-
LOGGER.warning(f"Prek hooks failed for {filepath}. This is non-fatal and generation will continue.")
39+
LOGGER.warning(f"Prek hooks failed for {filepath}, falling back to ruff.")
3140
LOGGER.debug(f"prek stderr: {stderr}")
41+
else:
42+
prek_success = True
43+
3244
if stdout:
3345
LOGGER.info(f"{filepath} fixed by prek")
34-
LOGGER.debug(f"rek stdout: {stdout}")
46+
LOGGER.debug(f"prek stdout: {stdout}")
3547
except Exception as e:
36-
LOGGER.error(f"Failed to run prek hooks for {filepath}: {e}. This is non-fatal and generation will continue.")
48+
LOGGER.warning(f"Failed to run prek for {filepath}, falling back to ruff: {e}")
49+
50+
if not prek_success:
51+
_run_ruff_fallback(filepath=filepath, pyproject_toml=pyproject_toml)
52+
53+
54+
def _run_ruff_fallback(filepath: str, pyproject_toml: str) -> None:
55+
"""Run ruff check --fix and ruff format as fallback when prek fails."""
56+
for ruff_cmd in (
57+
["uvx", "ruff", "check", "--fix", "--config", pyproject_toml, filepath],
58+
["uvx", "ruff", "format", "--config", pyproject_toml, filepath],
59+
):
60+
try:
61+
_, stdout, _ = run_command(
62+
command=ruff_cmd,
63+
verify_stderr=False,
64+
check=False,
65+
log_errors=False,
66+
)
67+
if stdout:
68+
LOGGER.info(f"{filepath} fixed by ruff")
69+
LOGGER.debug(f"ruff stdout: {stdout}")
70+
except Exception as e:
71+
LOGGER.error(f"Ruff fallback failed for {filepath}: {e}")

class_generator/manifests/class_generator_template.j2

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@
1414
{% endfor %}
1515

1616
from typing import Any
17-
from ocp_resources.resource import {{ base_class }}
17+
18+
{% if all_required_args %}
1819
from ocp_resources.exceptions import MissingRequiredArgumentError
20+
{% endif %}
21+
from ocp_resources.resource import {{ base_class }}
22+
1923

2024
class {{ kind }}({{ base_class }}):
2125
"""

class_generator/tests/manifests/test_parse_explain.j2

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
# Generated using https://github.com/RedHatQE/openshift-python-wrapper/blob/main/scripts/resource/README.md#adding-tests
22

33
import filecmp
4+
import traceback
45
from pathlib import Path
5-
import pytest
6-
from typing import List, Tuple, Optional
76

87
from class_generator.constants import TESTS_MANIFESTS_DIR
98
from class_generator.core.generator import class_generator
109
from class_generator.utils import execute_parallel_tasks
1110

1211

13-
def _test_single_resource(kind: str, tmp_path: Path) -> Optional[Tuple[str, str]]:
12+
def _test_single_resource(kind: str, tmp_path: Path) -> tuple[str, str] | None:
1413
"""
1514
Test a single resource kind and return failure info if test fails.
1615

@@ -45,9 +44,9 @@ def _test_single_resource(kind: str, tmp_path: Path) -> Optional[Tuple[str, str]
4544
if not filecmp.cmp(output_file, expected_file):
4645
try:
4746
# Read both files to show diff details
48-
with open(output_file, "r") as f:
47+
with open(output_file) as f:
4948
generated_content = f.read()
50-
with open(expected_file, "r") as f:
49+
with open(expected_file) as f:
5150
expected_content = f.read()
5251

5352
# Find first difference for debugging
@@ -60,7 +59,7 @@ def _test_single_resource(kind: str, tmp_path: Path) -> Optional[Tuple[str, str]
6059
diff_info += f"\nGenerated lines: {len(generated_lines)}, Expected lines: {len(expected_lines)}"
6160

6261
# Find first differing line
63-
for i, (gen_line, exp_line) in enumerate(zip(generated_lines, expected_lines)):
62+
for i, (gen_line, exp_line) in enumerate(zip(generated_lines, expected_lines, strict=True)):
6463
if gen_line != exp_line:
6564
diff_info += f"\nFirst difference at line {i + 1}:"
6665
diff_info += f"\nGenerated: {repr(gen_line[:100])}..."
@@ -81,8 +80,6 @@ def _test_single_resource(kind: str, tmp_path: Path) -> Optional[Tuple[str, str]
8180
return None
8281

8382
except Exception as e:
84-
import traceback
85-
8683
error_details = f"Exception during generation: {str(e)}\n"
8784
error_details += f"Traceback:\n{traceback.format_exc()}"
8885
return (kind, error_details)
@@ -97,17 +94,17 @@ def test_parse_explain(tmp_path: Path) -> None:
9794
{% endfor %}
9895
]
9996

100-
failures: List[Tuple[str, str]] = []
97+
failures: list[tuple[str, str]] = []
10198

10299
# Process test results and collect failures
103-
def process_test_result(kind: str, result: Optional[Tuple[str, str]]) -> None:
100+
def process_test_result(kind: str, result: tuple[str, str] | None) -> None:
104101
if result is not None:
105102
failures.append(result)
106103

107104
def handle_test_error(kind: str, exc: Exception) -> None:
108105
failures.append((kind, f"Task execution failed: {str(exc)}"))
109106

110-
def create_test_task(kind: str) -> Optional[Tuple[str, str]]:
107+
def create_test_task(kind: str) -> tuple[str, str] | None:
111108
return _test_single_resource(kind, tmp_path / f"test-{kind}")
112109

113110
# Run tests in parallel
@@ -136,12 +133,10 @@ def test_parse_explain(tmp_path: Path) -> None:
136133

137134
# Create a concise failure message for pytest
138135
failed_kinds = [kind for kind, _ in failures]
139-
failure_summary = f"{len(failures)} resource(s) failed: {', '.join(failed_kinds[:5])}"
140-
if len(failed_kinds) > 5:
141-
failure_summary += f" and {len(failed_kinds) - 5} more"
136+
failure_summary = f"{len(failures)} resource(s) failed: {','.join(failed_kinds)}"
142137

143138
# Fail the test with summary - detailed output is already printed above
144-
assert False, failure_summary
139+
raise AssertionError(failure_summary)
145140

146141
# If we get here, all tests passed
147142
print(f"\nAll {len(resource_kinds)} resource generation tests passed successfully!")

class_generator/tests/test_class_generator.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ def test_parse_explain(tmp_path: Path) -> None:
9696
"Deployment",
9797
"ImageContentSourcePolicy",
9898
"Machine",
99+
"NMState",
99100
"Pod",
100101
"Secret",
101-
"NMState",
102102
"ServiceMeshMember",
103-
"ServingRuntime",
103+
"Ingress",
104104
"OAuth",
105105
"Pipeline",
106-
"Ingress",
107106
"RouteAdvertisements",
107+
"ServingRuntime",
108108
]
109109

110110
failures: list[tuple[str, str]] = []
@@ -146,9 +146,7 @@ def create_test_task(kind: str) -> tuple[str, str] | None:
146146

147147
# Create a concise failure message for pytest
148148
failed_kinds = [kind for kind, _ in failures]
149-
failure_summary = f"{len(failures)} resource(s) failed: {', '.join(failed_kinds[:5])}"
150-
if len(failed_kinds) > 5:
151-
failure_summary += f" and {len(failed_kinds) - 5} more"
149+
failure_summary = f"{len(failures)} resource(s) failed: {','.join(failed_kinds)}"
152150

153151
# Fail the test with summary - detailed output is already printed above
154152
raise AssertionError(failure_summary)

class_generator/tests/test_cli.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,9 @@ def test_add_tests(self):
170170

171171
assert result.exit_code == 0
172172
mock_test_gen.assert_called_once()
173-
mock_os_system.assert_called_once_with("uv run pytest class_generator/tests/test_class_generator.py")
173+
mock_os_system.assert_called_once_with(
174+
"uv run --group tests pytest class_generator/tests/test_class_generator.py"
175+
)
174176

175177
def test_add_tests_requires_kind(self):
176178
"""Test that --add-tests cannot be used alone."""

tests/scripts/generate_pytest_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ def run_ruff_on_files(filepaths: list[str]) -> bool:
517517

518518
# Run ruff format and check on all files
519519
for op in ("format", "check"):
520-
cmd_str = f"uvx ruff {op} {' '.join(filepaths)}"
520+
cmd_str = f"uvx ruff --config pyproject.toml {op} {' '.join(filepaths)}"
521521
rc, _, _ = run_command(
522522
command=shlex.split(cmd_str),
523523
verify_stderr=False,

0 commit comments

Comments
 (0)