Skip to content

Conversation

@junhaoliao
Copy link
Member

@junhaoliao junhaoliao commented Nov 18, 2025

Description

This PR fixes #97 by updating the ruff per-file-ignores pattern to support extending the shared configuration across projects.

Changes

  1. Updated ruff.toml pattern: Changed "tests/**" to "/**/tests/**" to match test directories at any level when extended
  2. Added extend documentation: Updated README with instructions on using the extend directive for ruff
  3. Refactored ystdlib-py: Consolidated configuration by extending the shared ruff config instead of duplicating 36 lines

Context

When projects extend the ruff config using extend = "path/to/ruff.toml", the old pattern "tests/**" was resolved relative to the config file location, not the extending project's root. This prevented the per-file-ignores from working correctly in extending projects.

The new pattern "/**/tests/**" matches test directories anywhere in the project hierarchy, making it work correctly for both standalone use and when extended by other projects.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

  • In clp's integration-tests, verified the new pattern correctly ignores S101 and TC003 rules in test directories at any level
  • Tested with extend directive to confirm it works in extending projects
  • Confirmed all lint checks pass with the new configuration
  • Validated ystdlib-py successfully uses the extended config

Summary by CodeRabbit

Release Notes

  • Documentation

    • Updated Python linting integration guidance with Ruff setup instructions.
  • Chores

    • Expanded test directory ignore pattern for Python linting across all project depths.
    • Consolidated Python linting configuration through external configuration reference, reducing duplication.

… to allow it to be extended (fixes y-scope#97); Consolidate ruff configuration by extending the shared config.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

Updates Python linting configuration to support extended configs across projects. Modifies the Ruff per-file-ignores pattern to match test directories at any depth, documents integration methods in README, and consolidates ystdlib-py's Ruff config to extend the shared configuration file.

Changes

Cohort / File(s) Summary
Documentation
exports/lint-configs/python/README.md
Added "Integration Methods" section with Ruff extend directive example for pyproject.toml and Mypy configuration guidance.
Ruff Configuration
exports/lint-configs/python/ruff.toml
Updated per-file-ignores glob pattern from "tests/**" to "/**/tests/**" to match test directories at any depth in extending projects.
Project Configuration
exports/ystdlib-py/pyproject.toml
Replaced inline Ruff configuration (line-length, lint/ignores, per-file-ignores, format settings) with extend directive pointing to ../lint-configs/python/ruff.toml.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

  • Pattern change rationale: Confirm that "/**/tests/**" correctly addresses the relative path resolution issue when configs are extended from external locations.
  • Configuration migration: Verify that the extend directive in pyproject.toml properly inherits all settings from the shared Ruff config without unintended overrides.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating the Ruff per-file-ignores pattern and consolidating configuration via extension.
Linked Issues check ✅ Passed The pull request fully addresses issue #97 by updating the per-file-ignores pattern to '//tests/' and documenting the extend directive usage.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #97: the Ruff pattern update, README documentation, and ystdlib-py refactoring to use the extended config.
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
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@junhaoliao junhaoliao marked this pull request as ready for review November 18, 2025 02:29
@junhaoliao junhaoliao requested a review from a team as a code owner November 18, 2025 02:29
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b5c3f54 and a7bd16d.

📒 Files selected for processing (3)
  • exports/lint-configs/python/README.md (1 hunks)
  • exports/lint-configs/python/ruff.toml (1 hunks)
  • exports/ystdlib-py/pyproject.toml (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-06-08T16:54:50.714Z
Learnt from: davidlion
Repo: y-scope/yscope-dev-utils PR: 60
File: exports/lint-configs/python/ruff.toml:23-23
Timestamp: 2025-06-08T16:54:50.714Z
Learning: Ruff uses hyphens (not underscores) for isort configuration keys. For example, `isort.order-by-type` is correct, not `isort.order_by_type`. Always verify against the official Ruff documentation at https://docs.astral.sh/ruff/settings/

Applied to files:

  • exports/lint-configs/python/ruff.toml
  • exports/ystdlib-py/pyproject.toml
📚 Learning: 2025-06-08T16:54:50.714Z
Learnt from: davidlion
Repo: y-scope/yscope-dev-utils PR: 60
File: exports/lint-configs/python/ruff.toml:23-23
Timestamp: 2025-06-08T16:54:50.714Z
Learning: Ruff configuration uses hyphens for isort settings keys (e.g., `isort.order-by-type`), not underscores (e.g., `isort.order_by_type`). Always verify against the official Ruff documentation at https://docs.astral.sh/ruff/settings/

Applied to files:

  • exports/lint-configs/python/ruff.toml
  • exports/ystdlib-py/pyproject.toml
📚 Learning: 2025-06-08T17:04:50.095Z
Learnt from: davidlion
Repo: y-scope/yscope-dev-utils PR: 60
File: taskfiles/lint/python.yaml:15-20
Timestamp: 2025-06-08T17:04:50.095Z
Learning: In Ruff, the `--fix` flag is used specifically with `ruff check` to automatically fix linting violations. The `ruff format` command formats code by default and does not require a `--fix` flag. When configuring taskfiles, `RUFF_CHECK_FLAGS: "--fix"` is the correct way to enable auto-fixing for linting issues.

Applied to files:

  • exports/ystdlib-py/pyproject.toml
📚 Learning: 2025-06-08T17:04:50.095Z
Learnt from: davidlion
Repo: y-scope/yscope-dev-utils PR: 60
File: taskfiles/lint/python.yaml:15-20
Timestamp: 2025-06-08T17:04:50.095Z
Learning: The `--fix` flag is used with `ruff check` to automatically fix linting issues, while `ruff format` formats files by default without needing a `--fix` flag. In the context of taskfiles, `RUFF_CHECK_FLAGS: "--fix"` is the correct way to enable auto-fixing for the `ruff check` command.

Applied to files:

  • exports/ystdlib-py/pyproject.toml
🔇 Additional comments (2)
exports/lint-configs/python/README.md (2)

6-17: Documentation is clear and well-structured.

The "Integration Methods" section properly documents the difference between Ruff (which supports extend) and Mypy (which requires copying). The example path is appropriately generic with a placeholder. The reference to ystdlib-py/pyproject.toml as a concrete example is helpful and the relative path ../../ystdlib-py/pyproject.toml should resolve correctly from the README location.


19-22: Mypy documentation accurately conveys the configuration requirement.

The note correctly explains that Mypy does not support extending external configurations and provides clear instructions for users. No concerns identified.


[lint.per-file-ignores]
"tests/**" = [
"/**/tests/**" = [
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify Ruff glob pattern syntax for per-file-ignores with leading /**/.

The pattern change from "tests/**" to "/**/tests/**" is intended to match test directories at any project depth when this config is extended. However, I need to confirm that Ruff supports glob patterns starting with /**/ and that this syntax produces the expected behaviour when used with the extend directive.


🌐 Web query:

Does Ruff support glob patterns starting with /**/ in per-file-ignores configuration?

💡 Result:

Short answer: No — use "/" not "//". Ruff's per-file-ignores use the Rust globset-style globs (which support patterns that start with "/"), but patterns with a leading slash ("//…") are not the supported form; write "**/path" (or project-relative paths) instead. [1][2][3]

Sources:

  • Ruff configuration (per-file-ignores) docs. [1]
  • globset glob syntax (explains "**/" behavior). [2]
  • Ruff issue noting pattern-syntax differences and glob behavior. [3]

Correct the glob pattern syntax in per-file-ignores; use "**/tests/**" instead of "/**/tests/**".

Ruff's per-file-ignores use Rust globset-style globs which support **/ patterns but not the leading-slash form /**/. The correct syntax is **/path or project-relative paths. Change line 29 from "/**/tests/**" to "**/tests/**" to match test directories at any depth when this config is extended.

🤖 Prompt for AI Agents
In exports/lint-configs/python/ruff.toml around line 29, the per-file-ignores
glob uses a leading-slash form "/**/tests/**" which Ruff's globset does not
accept; replace it with the correct Rust globset-style pattern "**/tests/**" so
test directories are matched at any depth (update the quoted string
accordingly).

Comment on lines 30 to +31
[tool.ruff]
line-length = 100

[tool.ruff.lint]
select = ["ALL"]
ignore = [
"ANN401", # Allow using Any type for function signatures
"COM812", # Redundant and conflicts with ruff format
"D203", # No blank line before docstrings (D211)
"D205", # Breaks if summary is larger than one line due to wrapping or if no summary exists
"D212", # Enforce docstring summary line on the next line after quotes (D213)
"D400", # First line of docstrings may not end in period
"D401", # Docstrings should be written in present tense (not imperative)
"D415", # First line of docstrings may not end in a period, question mark, or exclamation point
"FBT", # Allow bool positional parameters since other value positions are allowed
"FIX002", # Allow todo statements
"PERF401", # Allow for loops when creating lists
"PERF403", # Allow for loops when creating dicts
"S311", # Allow usage of `random` package
"S603", # Automatically trust inputs of subprocess execution
"SIM102", # Allow collapsible if statements for readability
"SIM300", # Skip Yoda-condition format fixes
"TD002", # Author unnecessary for todo statement
"TD003", # Issue link unnecessary for todo statement
"UP015", # Explicit open modes are helpful
]
isort.order-by-type = false

[tool.ruff.lint.per-file-ignores]
"tests/**" = [
"S101", # Allow usage of pytest `assert`
"TC003", # Ignore performance overhead of imports only used for type checking
]

[tool.ruff.format]
docstring-code-format = true
docstring-code-line-length = 100
extend = "../lint-configs/python/ruff.toml"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify that the extend path is correctly resolved by Ruff.

The relative path ../lint-configs/python/ruff.toml appears correct for reaching the shared config from exports/ystdlib-py/pyproject.toml. However, I should verify that Ruff correctly resolves this path relative to the pyproject.toml file location and that there are no other references to the previously inlined configuration that might break.


🏁 Script executed:

#!/bin/bash
# Description: Verify the relative path and check for any other references to ystdlib-py Ruff config

# Validate the path exists and is readable
if [ -f "exports/ystdlib-py/../lint-configs/python/ruff.toml" ]; then
  echo "✓ Path resolves correctly"
  echo "File: exports/lint-configs/python/ruff.toml exists"
else
  echo "✗ Path does not resolve to a valid file"
fi

# Search for any other pyproject.toml files that might reference ystdlib config
echo ""
echo "Searching for other pyproject.toml files that might reference ystdlib..."
rg -l "pyproject\.toml" --type=toml -g "pyproject.toml" | head -20

# Search for any documentation or comments referencing ystdlib Ruff config
echo ""
echo "Searching for documentation references to ystdlib Ruff config..."
rg -nC2 "ystdlib" --type=md exports/lint-configs/python/README.md 2>/dev/null || echo "No matches found in README"

Length of output: 327


Now let me verify the content of the shared ruff.toml to ensure it contains the appropriate configuration:

Now let me check the content of the shared ruff.toml to verify what configuration is being inherited:


🏁 Script executed:

#!/bin/bash
# View the content of the shared ruff.toml file
cat "exports/lint-configs/python/ruff.toml"

Length of output: 1544


Critical: Per-file-ignores patterns from the shared config will not resolve correctly when extended.

When per-file-ignores is set only in an extended ruff.toml file, Ruff calculates the path according to the extended configuration file location, not the project root. The pattern "/**/tests/**" in exports/lint-configs/python/ruff.toml will be resolved relative to exports/lint-configs/python/, not exports/ystdlib-py/. This means the per-file-ignores for test files will not work correctly for ystdlib-py.

Solution: Add extend-per-file-ignores in exports/ystdlib-py/pyproject.toml to override the test patterns:

[tool.ruff.lint.extend-per-file-ignores]
"/**/tests/**" = [
    "S101",
    "TC003",
]

This ensures the glob patterns are resolved relative to the ystdlib-py project root.

🤖 Prompt for AI Agents
In exports/ystdlib-py/pyproject.toml around lines 30-31, the project extends the
shared Ruff config but does not override per-file-ignores, so glob patterns in
the shared config are resolved relative to the shared config path and won’t
match this project’s test files; fix by adding a
[tool.ruff.lint.extend-per-file-ignores] section in this pyproject.toml that
re-declares the test-file globs (e.g. "/**/tests/**") with the same error codes
(S101, TC003) so the patterns are resolved relative to exports/ystdlib-py.

@junhaoliao junhaoliao merged commit 6eb62e9 into y-scope:main Nov 18, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update ruff per-file-ignores pattern to support extended configs

2 participants