Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,73 @@ markers = [
version_file = "src/mini_trainer/_version.py"
# do not include +gREV local version, required for Test PyPI upload
local_scheme = "no-local-version"

[tool.ruff]
line-length = 120
target-version = "py311"
exclude = [
".venv",
"venv",
"__pycache__",
".git",
"build",
"dist",
"*.egg-info",
"checkpoints",
"outputs",
"wandb",
"mlruns",
]

[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"RUF", # ruff-specific rules
]
ignore = [
"E501", # line too long (handled by formatter)
"E402", # module level import not at top (common in ML scripts for path setup)
"E741", # ambiguous variable name (l, O, I) - common in ML for loss, lambda
"B007", # unused loop variable (often intentional: for _ in range)
"B008", # function call in default argument (common in typer/fastapi)
"B905", # zip without strict= (often intentional in ML)
"UP007", # Use X | Y for type union (compatibility)
"RUF001", # ambiguous unicode (intentional for i18n test strings)
"RUF002", # ambiguous unicode in docstrings
"RUF012", # mutable class attrs (common in dataclasses)
"RUF013", # implicit Optional (stylistic preference)
"RUF015", # prefer next() over [0] slice (stylistic)
"RUF022", # __all__ not sorted (stylistic)
"RUF059", # unused parameters (often intentional in callbacks/hooks)
"C401", # unnecessary generator - set comprehension (stylistic)
"C408", # unnecessary dict/list/tuple call (stylistic)
"C416", # unnecessary dict comprehension (stylistic)
"C419", # unnecessary comprehension in any/all (stylistic)
"B012", # return in finally (sometimes intentional for early exit)
"UP042", # use StrEnum instead of str, Enum (compatibility with older Python)
]

[tool.ruff.lint.isort]
known-first-party = ["mini_trainer"]
combine-as-imports = true

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101", "F841"] # allow assert and unused vars in tests
"__init__.py" = ["F401"] # allow unused imports in __init__
"regression_tests/*" = ["F401", "F811", "F841"] # allow unused and redefinitions in benchmark scripts
"research_scratch/*" = ["F401", "F841"] # allow unused in research scripts
"tutorials/*" = ["F401", "F841"] # allow unused in tutorials
"scripts/*" = ["E722"] # allow bare except in scripts
"test-*.py" = ["F841"] # allow unused vars in standalone test files
Comment on lines +160 to +167
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check for nested Python files in target directories
for d in tests regression_tests research_scratch tutorials scripts; do
  if [ -d "$d" ]; then
    echo "== $d =="
    fd -t f '\.py$' "$d" | head -20
  fi
done

Repository: Red-Hat-AI-Innovation-Team/mini_trainer

Length of output: 1202


🌐 Web query:

Ruff per-file-ignores glob pattern matching semantics "tests/*" vs "tests/**"

💡 Result:

Ruff’s per-file-ignores patterns use Rust’s globset syntax, matched against paths relative to the project root. (docs.astral.sh)

tests/*

  • * matches within a single path component (it won’t cross /). (docs.rs)
  • So tests/* matches files directly inside tests/, e.g.:
    • tests/test_api.py
    • tests/unit/test_api.py ❌ (because of the extra /unit/)

tests/**

  • In globset, a pattern ending in /** matches all sub-entries under that directory, recursively (e.g., foo/** matches foo/a and foo/a/b, but not foo itself). (docs.rs)
  • So tests/** matches:
    • tests/test_api.py
    • tests/unit/test_api.py
    • but not the directory path tests itself (Ruff is matching files anyway). (docs.rs)

Citations:


Update per-file-ignores to use recursive globs for nested test files.

Nested test files under tests/gpu_tests/ are not covered by the current tests/* pattern, which only matches one directory level. Ruff's globset syntax requires tests/** for recursive matching. Update all per-file-ignore patterns to use recursive globs:

Required fix
[tool.ruff.lint.per-file-ignores]
-"tests/*" = ["S101", "F841"]  # allow assert and unused vars in tests
-"regression_tests/*" = ["F401", "F811", "F841"]  # allow unused and redefinitions in benchmark scripts
-"research_scratch/*" = ["F401", "F841"]  # allow unused in research scripts
-"tutorials/*" = ["F401", "F841"]  # allow unused in tutorials
-"scripts/*" = ["E722"]  # allow bare except in scripts
+"tests/**" = ["S101", "F841"]  # allow assert and unused vars in tests
+"regression_tests/**" = ["F401", "F811", "F841"]  # allow unused and redefinitions in benchmark scripts
+"research_scratch/**" = ["F401", "F841"]  # allow unused in research scripts
+"tutorials/**" = ["F401", "F841"]  # allow unused in tutorials
+"scripts/**" = ["E722"]  # allow bare except in scripts
🤖 Prompt for AI Agents
In `@pyproject.toml` around lines 160 - 167, The per-file-ignore globs under the
tool.ruff.lint.per-file-ignores table are not recursive; update each
directory-level pattern to use recursive globs so nested files are matched
(e.g., change "tests/*" to "tests/**"); apply the same update for other
directory patterns such as "regression_tests/*" -> "regression_tests/**",
"research_scratch/*" -> "research_scratch/**", "tutorials/*" -> "tutorials/**"
and "scripts/*" -> "scripts/**" while leaving single-file patterns (like
"__init__.py" and "test-*.py") unchanged so the existing ignore lists (S101,
F841, F401, F811, E722, etc.) continue to apply.


[tool.ruff.format]
quote-style = "double"
indent-style = "space"
docstring-code-format = true
skip-magic-trailing-comma = false
Loading
Loading