From c728f765ce33bb6064d9a1ee9fa5b086340ab598 Mon Sep 17 00:00:00 2001 From: Glenn Jocher Date: Fri, 24 Jul 2026 01:00:46 +0200 Subject: [PATCH] Ignore intentional broad exception handling in Ruff (#832) Co-authored-by: UltralyticsAssistant --- AGENTS.md | 4 ++-- action.yml | 6 +++--- actions/__init__.py | 2 +- actions/format_code.py | 4 ++-- actions/format_python_docstrings.py | 15 ++++++++------- actions/github_report.py | 6 ++++-- actions/update_markdown_code_blocks.py | 4 ++-- actions/utils/openai_utils.py | 4 ++-- pyproject.toml | 1 + tests/test_dispatch_actions.py | 7 +++---- tests/test_first_interaction.py | 17 +---------------- tests/test_github_report.py | 2 +- tests/test_openai_utils.py | 17 ++++++++--------- 13 files changed, 38 insertions(+), 51 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b44fd11..b5b2053 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -41,8 +41,8 @@ pytest tests/test_github_utils.py::test_name -v # run one test pytest tests -v --cov=actions --cov-report=xml:coverage.xml # tests with coverage (CI command) # Lint/format — mirrors the "Run Python" step in action.yml (source of truth if these drift) -ruff check --fix --unsafe-fixes --extend-select F,I,D,UP,RUF,FA --target-version py39 \ - --ignore D100,D104,D203,D205,D212,D213,D401,D406,D407,D413,RUF001,RUF002,RUF012 . +ruff check --fix --unsafe-fixes --extend-select F,I,D,UP,RUF,FA --target-version py38 \ + --ignore BLE001,D100,D104,D203,D205,D212,D213,D401,D406,D407,D413,RUF001,RUF002,RUF012,S110 . ruff format --line-length 120 . ``` diff --git a/action.yml b/action.yml index 212829a..009a760 100644 --- a/action.yml +++ b/action.yml @@ -172,7 +172,7 @@ runs: # D406: Section name should end with a newline # D407: Missing dashed underline after section # D413: Missing blank line after last section - # --target-version is Python 3.9 for --extend-select UP (pyupgrade) + # --target-version is Python 3.8 for --extend-select UP (pyupgrade) - name: Run Python if: (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && inputs.python == 'true' && (github.event.action == 'opened' || github.event.action == 'synchronize') run: | @@ -182,8 +182,8 @@ runs: --fix \ --unsafe-fixes \ --extend-select F,I,D,UP,RUF,FA \ - --target-version py39 \ - --ignore D100,D104,D203,D205,D212,D213,D401,D406,D407,D413,RUF001,RUF002,RUF012 \ + --target-version py38 \ + --ignore BLE001,D100,D104,D203,D205,D212,D213,D401,D406,D407,D413,RUF001,RUF002,RUF012,S110 \ . || true ruff format \ --line-length 120 \ diff --git a/actions/__init__.py b/actions/__init__.py index ad91142..a4278a3 100644 --- a/actions/__init__.py +++ b/actions/__init__.py @@ -28,4 +28,4 @@ # ├── test_summarize_pr.py # └── ... -__version__ = "0.2.33" +__version__ = "0.2.34" diff --git a/actions/format_code.py b/actions/format_code.py index 2f77dea..ca42770 100644 --- a/actions/format_code.py +++ b/actions/format_code.py @@ -12,8 +12,8 @@ RUFF_CHECK = [ "--fix", "--unsafe-fixes", "--extend-select=F,I,D,UP,RUF,FA", - "--target-version=py39", - "--ignore=D100,D104,D203,D205,D212,D213,D401,D406,D407,D413,RUF001,RUF002,RUF012", + "--target-version=py38", + "--ignore=BLE001,D100,D104,D203,D205,D212,D213,D401,D406,D407,D413,RUF001,RUF002,RUF012,S110", ".", ] RUFF_FORMAT = ["ruff", "format", "--line-length=120", "."] diff --git a/actions/format_python_docstrings.py b/actions/format_python_docstrings.py index 96f8071..627a088 100644 --- a/actions/format_python_docstrings.py +++ b/actions/format_python_docstrings.py @@ -42,11 +42,13 @@ TABLE_RULE_RX = re.compile(r"^\s*[:\-\|\s]{3,}$") TREE_CHARS = ("└", "├", "│", "─") # Antipatterns for non-Google docstring styles -RST_FIELD_RX = re.compile(r"^\s*:(param|type|return|rtype|raises)\b", re.M) -EPYDOC_RX = re.compile(r"^\s*@(?:param|type|return|rtype|raise)\b", re.M) -NUMPY_UNDERLINE_SECTION_RX = re.compile(r"^\s*(Parameters|Returns|Yields|Raises|Notes|Examples)\n[-]{3,}\s*$", re.M) +RST_FIELD_RX = re.compile(r"^\s*:(param|type|return|rtype|raises)\b", re.MULTILINE) +EPYDOC_RX = re.compile(r"^\s*@(?:param|type|return|rtype|raise)\b", re.MULTILINE) +NUMPY_UNDERLINE_SECTION_RX = re.compile( + r"^\s*(Parameters|Returns|Yields|Raises|Notes|Examples)\n[-]{3,}\s*$", re.MULTILINE +) GOOGLE_SECTION_RX = re.compile( - r"^\s*(Args|Attributes|Methods|Returns|Yields|Raises|Example|Examples|Notes|References):\s*$", re.M + r"^\s*(Args|Attributes|Methods|Returns|Yields|Raises|Example|Examples|Notes|References):\s*$", re.MULTILINE ) NON_GOOGLE = {"numpy", "rest", "epydoc"} @@ -283,9 +285,8 @@ def format_structured_block(lines: list[str], width: int, base: int) -> list[str desc = " ".join(parts) head = " " * cont + (f"{name}: " if (desc or had_colon) else name) out.extend(wrap_hanging(head, desc, width, cont + 4)) - if tail: - if body := emit_paragraphs(tail, width, cont + 4, lst, orphan_min=2): - out.extend(body) + if tail and (body := emit_paragraphs(tail, width, cont + 4, lst, orphan_min=2)): + out.extend(body) return out diff --git a/actions/github_report.py b/actions/github_report.py index f05ea38..7627f4a 100644 --- a/actions/github_report.py +++ b/actions/github_report.py @@ -113,8 +113,10 @@ def format_pr_report(prs, repos, visibility, org="ultralytics"): lines.extend( [ f"**Total:** {len(prs)} open PRs across {repo_count}/{len(repos)} {visibility} repos", - f"**By Phase:** 🆕 {phase_counts['new']} New | 🟢 {phase_counts['green']} ≤7d | " - f"🟡 {phase_counts['yellow']} ≤30d | 🔴 {phase_counts['red']} >30d", + ( + f"**By Phase:** 🆕 {phase_counts['new']} New | 🟢 {phase_counts['green']} ≤7d | " + f"🟡 {phase_counts['yellow']} ≤30d | 🔴 {phase_counts['red']} >30d" + ), "", ] ) diff --git a/actions/update_markdown_code_blocks.py b/actions/update_markdown_code_blocks.py index cd0a35a..a40277a 100644 --- a/actions/update_markdown_code_blocks.py +++ b/actions/update_markdown_code_blocks.py @@ -72,8 +72,8 @@ def format_code_with_ruff(temp_dir): "--fix", "--unsafe-fixes", "--extend-select=F,I,D,UP,RUF", - "--target-version=py39", - "--ignore=D100,D101,D103,D104,D203,D205,D212,D213,D401,D406,D407,D413,F821,F841,RUF001,RUF002,RUF012", + "--target-version=py38", + "--ignore=BLE001,D100,D101,D103,D104,D203,D205,D212,D213,D401,D406,D407,D413,F821,F841,RUF001,RUF002,RUF012,S110", str(temp_dir), ], check=True, diff --git a/actions/utils/openai_utils.py b/actions/utils/openai_utils.py index 154de43..978953a 100644 --- a/actions/utils/openai_utils.py +++ b/actions/utils/openai_utils.py @@ -89,7 +89,7 @@ def filter_labels(available_labels: dict, current_labels: list | None = None, is current_labels = current_labels or [] filtered = available_labels.copy() - for label in { + for label in ( "help wanted", "TODO", "research", @@ -99,7 +99,7 @@ def filter_labels(available_labels: dict, current_labels: list | None = None, is "Stale", "wontfix", "duplicate", - }: + ): filtered.pop(label, None) if "bug" in current_labels: diff --git a/pyproject.toml b/pyproject.toml index cee0bf8..eb959a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -125,6 +125,7 @@ omit = [ [tool.ruff] line-length = 120 +target-version = "py38" [tool.ruff.format] docstring-code-format = true diff --git a/tests/test_dispatch_actions.py b/tests/test_dispatch_actions.py index a371f1f..911bb10 100644 --- a/tests/test_dispatch_actions.py +++ b/tests/test_dispatch_actions.py @@ -40,10 +40,9 @@ def test_get_pr_branch_fork(): "base": {"repo": {"id": 1}}, } - with patch("time.time", return_value=1234567.890): - with patch("subprocess.run") as mock_run: - with patch("os.environ.get", return_value="test-token"): - branch, temp_branch = get_pr_branch(mock_event) + with patch("time.time", return_value=1234567.890), patch("subprocess.run") as mock_run: + with patch("os.environ.get", return_value="test-token"): + branch, temp_branch = get_pr_branch(mock_event) assert branch == "temp-ci-456-1234567890" assert temp_branch == "temp-ci-456-1234567890" diff --git a/tests/test_first_interaction.py b/tests/test_first_interaction.py index 6503f77..a090125 100644 --- a/tests/test_first_interaction.py +++ b/tests/test_first_interaction.py @@ -364,22 +364,7 @@ def test_get_repo_guidelines_fetches_pr_head(mock_fetch): def test_review_agent_tools_can_list_and_read_changed_file_diffs(): """Test PR diff tools let the agent inspect every changed file on demand.""" - diff = "\n".join( - [ - "diff --git a/early.py b/early.py", - "--- a/early.py", - "+++ b/early.py", - "@@ -1 +1 @@", - "-old = True", - "+old = False", - "diff --git a/nested/late.py b/nested/late.py", - "--- a/nested/late.py", - "+++ b/nested/late.py", - "@@ -10 +10 @@", - "-value = 1", - "+value = 2", - ] - ) + diff = "diff --git a/early.py b/early.py\n--- a/early.py\n+++ b/early.py\n@@ -1 +1 @@\n-old = True\n+old = False\ndiff --git a/nested/late.py b/nested/late.py\n--- a/nested/late.py\n+++ b/nested/late.py\n@@ -10 +10 @@\n-value = 1\n+value = 2" diff_files, augmented_diff = review_pr.parse_diff_files(diff) _, handlers = review_pr.build_review_agent_tools(diff_files, augmented_diff) diff --git a/tests/test_github_report.py b/tests/test_github_report.py index e4a5f34..b5ba871 100644 --- a/tests/test_github_report.py +++ b/tests/test_github_report.py @@ -11,7 +11,7 @@ def test_paginate_only_skips_http_errors_when_allowed(monkeypatch): def fake_get(path, params=None, token=None, allow_skip=False): if allow_skip: - return None + return raise PermissionError(path) monkeypatch.setattr(failed_scheduled_actions, "github_get", fake_get) diff --git a/tests/test_openai_utils.py b/tests/test_openai_utils.py index 1641205..4d954fd 100644 --- a/tests/test_openai_utils.py +++ b/tests/test_openai_utils.py @@ -257,15 +257,14 @@ def test_get_agent_response_calls_function_tools(mock_post): } ] - with patch("actions.utils.openai_utils.OPENAI_API_KEY", "test-key"): - with patch("builtins.print") as mock_print: - result = get_agent_response( - [{"role": "user", "content": "review"}], - tools=tools, - tool_handlers={"lookup_value": lambda value: {"found": value}}, - text_format={"format": {"type": "json_schema", "name": "review", "strict": True, "schema": schema}}, - retries=0, - ) + with patch("actions.utils.openai_utils.OPENAI_API_KEY", "test-key"), patch("builtins.print") as mock_print: + result = get_agent_response( + [{"role": "user", "content": "review"}], + tools=tools, + tool_handlers={"lookup_value": lambda value: {"found": value}}, + text_format={"format": {"type": "json_schema", "name": "review", "strict": True, "schema": schema}}, + retries=0, + ) assert result == {"comments": [], "summary": "done"} assert mock_post.call_count == 2