Skip to content

Add pre-commit check for stale cudf_polars version-compat flags - #23133

Open
nethum529 wants to merge 4 commits into
rapidsai:mainfrom
nethum529:fix/issue-16736-version-compat-check
Open

Add pre-commit check for stale cudf_polars version-compat flags#23133
nethum529 wants to merge 4 commits into
rapidsai:mainfrom
nethum529:fix/issue-16736-version-compat-check

Conversation

@nethum529

Copy link
Copy Markdown
Contributor

cudf_polars/utils/versions.py defines POLARS_VERSION_LT_* flags that gate behavior on the installed polars version. Once the minimum polars version pinned in cudf_polars/pyproject.toml passes one of these thresholds, the flag can never evaluate true again and the code path it guards is dead, but nothing currently reminds maintainers to clean it up when bumping the pin.

Add ci/checks/versions_compat.py, a standalone script (no cudf import) that parses the pinned minimum polars version from pyproject.toml and flags any POLARS_VERSION_LT_* threshold that has fallen at or below it. It fails loudly (rather than silently skipping) if it finds a version-compat flag assignment in a form it doesn't recognize, since a missed match would otherwise make the check falsely report "clean".

Wire it into .pre-commit-config.yaml as a local script hook, triggered when cudf_polars/pyproject.toml or utils/versions.py change, following the existing cudf-polars-ir-signatures hook as a style precedent.

Ships with a standalone unit-test module for the checker's own logic.

Fixes #16736

cudf_polars/utils/versions.py defines POLARS_VERSION_LT_* flags that
gate behavior on the installed polars version. Once the minimum polars
version pinned in cudf_polars/pyproject.toml passes one of these
thresholds, the flag can never evaluate true again and the code path
it guards is dead, but nothing currently reminds maintainers to clean
it up when bumping the pin.

Add ci/checks/versions_compat.py, a standalone script (no cudf import)
that parses the pinned minimum polars version from pyproject.toml and
flags any POLARS_VERSION_LT_* threshold that has fallen at or below it.
It fails loudly (rather than silently skipping) if it finds a
version-compat flag assignment in a form it doesn't recognize, since a
missed match would otherwise make the check falsely report "clean".

Wire it into .pre-commit-config.yaml as a local script hook, triggered
when cudf_polars/pyproject.toml or utils/versions.py change, following
the existing cudf-polars-ir-signatures hook as a style precedent.

Fixes rapidsai#16736

Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
@nethum529
nethum529 requested review from a team as code owners July 6, 2026 21:26
@nethum529
nethum529 requested a review from bdice July 6, 2026 21:26
@copy-pr-bot

copy-pr-bot Bot commented Jul 6, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3ca24b98-1462-4472-af35-29c85101da87

📥 Commits

Reviewing files that changed from the base of the PR and between bbe8ccd and 60ce016.

📒 Files selected for processing (1)
  • .pre-commit-config.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .pre-commit-config.yaml

📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Added an automated compatibility check to detect unreachable Polars version guard flags before merging.
    • Expanded test coverage for version compatibility validation, including parsing rules, edge cases, and CLI behavior (exit codes and messages).

Walkthrough

This PR adds a version-compatibility checker for stale POLARS_VERSION_LT_* flags, registers it as a scoped pre-commit hook, and adds pytest coverage for parsing, stale-flag detection, CLI behavior, and repository regressions.

Changes

Version Compat Checker

Layer / File(s) Summary
Core parsing helpers and data types
ci/checks/versions_compat.py
Adds compiled patterns for flag assignments and version extraction, the StaleFlag tuple type, and UnparseableFlagError.
Minimum version and stale-flag detection logic
ci/checks/versions_compat.py
Parses the minimum Polars dependency version and reports unreachable compatibility flags with line numbers.
CLI entrypoint and pre-commit wiring
ci/checks/versions_compat.py, .pre-commit-config.yaml
Adds CLI options, reporting and exit codes, the script entrypoint, and the cudf-polars-version-compat pre-commit hook.
Test suite for version compat checker
ci/checks/test_versions_compat.py
Tests version extraction, stale and unparseable flags, CLI paths, default repository files, regex coverage, and the current repository state.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested labels: Python

Suggested reviewers: bdice

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR addresses the Polars compatibility-check objective, but the reviewer reported that the hook does not run and the fix is not included. Fix the pre-commit hook so it runs correctly, then verify the hook detects stale and unparseable version-compatibility flags.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding a pre-commit check for stale cudf_polars version-compatibility flags.
Description check ✅ Passed The description explains the new checker, its pre-commit integration, failure behavior, tests, and linked issue.
Out of Scope Changes check ✅ Passed The script, tests, and pre-commit configuration changes directly support the requested version-compatibility reminder.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
ci/checks/test_versions_compat.py (1)

14-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Note: dynamic module loading assumes spec_from_file_location succeeds.

importlib.util.spec_from_file_location can return None if the target file can't be located, which would cause a confusing AttributeError on _SPEC.loader rather than a clear failure message. Given this only runs against a known sibling file in the same directory, this is a low-risk edge case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ci/checks/test_versions_compat.py` around lines 14 - 19, The dynamic import
setup in test_versions_compat.py assumes importlib.util.spec_from_file_location
always returns a valid spec, but _SPEC can be None and make _SPEC.loader fail
with an unclear AttributeError. Update the module-loading block around _SPEC,
versions_compat, and _SPEC.loader.exec_module to explicitly handle a missing
spec (or missing loader) with a clear failure before module execution.
ci/checks/versions_compat.py (1)

130-135: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Blind except Exception flagged by Ruff (BLE001).

The catch-all is intentional here (fail loudly with a message rather than a raw traceback), but Ruff's static analysis flagged it. Since this repo's pre-commit runs Ruff on Python files, this could trip CI lint if BLE rules are selected in the project's ruff config.

🔧 Suggested fix: silence with explicit rationale
     try:
         minimum = minimum_polars_version(args.pyproject)
         stale = find_stale_flags(args.versions_file, minimum)
-    except Exception as e:
+    except Exception as e:  # noqa: BLE001 - CLI: report any failure, don't crash with a traceback
         print(f"Error: {e}", file=sys.stderr)
         return 1
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ci/checks/versions_compat.py` around lines 130 - 135, The try/except in
versions_compat.py is intentionally catching all exceptions, but Ruff flags the
blind Exception handler in the versions_compat main flow. Update the exception
handling around minimum_polars_version and find_stale_flags to explicitly
document that this broad catch is intentional, and add the appropriate Ruff
suppression on the except block in a localized way so CI lint does not fail
while still preserving the user-friendly stderr message and exit code.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@ci/checks/test_versions_compat.py`:
- Around line 14-19: The dynamic import setup in test_versions_compat.py assumes
importlib.util.spec_from_file_location always returns a valid spec, but _SPEC
can be None and make _SPEC.loader fail with an unclear AttributeError. Update
the module-loading block around _SPEC, versions_compat, and
_SPEC.loader.exec_module to explicitly handle a missing spec (or missing loader)
with a clear failure before module execution.

In `@ci/checks/versions_compat.py`:
- Around line 130-135: The try/except in versions_compat.py is intentionally
catching all exceptions, but Ruff flags the blind Exception handler in the
versions_compat main flow. Update the exception handling around
minimum_polars_version and find_stale_flags to explicitly document that this
broad catch is intentional, and add the appropriate Ruff suppression on the
except block in a localized way so CI lint does not fail while still preserving
the user-friendly stderr message and exit code.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: b7ce619c-f514-4893-9a75-1e636fe68dca

📥 Commits

Reviewing files that changed from the base of the PR and between 35e7cd6 and 80def2a.

📒 Files selected for processing (3)
  • .pre-commit-config.yaml
  • ci/checks/test_versions_compat.py
  • ci/checks/versions_compat.py

@vyasr

vyasr commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

@nethum529 it looks like your new hook is failing to run. Can you please fix it?

@vyasr vyasr added improvement Improvement / enhancement to an existing function non-breaking Non-breaking change labels Jul 20, 2026
@nethum529

Copy link
Copy Markdown
Contributor Author

@nethum529 it looks like your new hook is failing to run. Can you please fix it?

Will do, currently at work. Will have to fix it after 5:00 PM today.

Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
Signed-off-by: nethum529 <nethumweerasinghe.nw@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

improvement Improvement / enhancement to an existing function non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEA]: pre-commit reminders when pandas/polars dependencies get out of sync with "version" compat flags

2 participants