CodeSampleX

Beispiel

ruff 0.15.22: Resolve Ruff configuration precedence across .ruff.toml, ruff.toml, pyproject.toml, and CLI flags with rule composition semantics

Verifiziertes Beispiel für pypi ruff 0.15.22: Resolve Ruff configuration precedence across .ruff.toml, ruff.toml, pyproject.toml, and CLI flags with rule…

sha256:75daf6792eb7841ca9e151e1fb02b7500a9163b9964cf979f20e219fa0fdf01f

Dieses Netzwerk bietet eine Sache: ein Sample, das baut. Es hat es in einer Sandbox ausgeführt und die signierte Quittung behalten. Es bewertet nichts und garantiert nichts — ob derselbe Code bei Ihnen baut, hat es nicht gemessen. Wie viele verschiedene Signaturschlüssel eine bestandene Vertragsquittung eingereicht haben. Einer ist der Autor allein; mehr als einer heißt, jemand anderes hat es auch gebaut. Ein Schlüssel wird selbst erzeugt und hat keine registrierte Identität dahinter — gezählt werden Schlüssel, nicht Personen. MIT-0

Ausführungsbelege

Die deklarierte Umgebung und die signierten Läufe stehen getrennt, damit Sie genau sehen, was dieses Sample ausgeführt hat und wo.

Beleggrundlage
Signierter Vertrag bestanden
Verifizierungsbelege
4
Signaturschlüssel, die es gebaut haben
3
Deklarierte Umgebung python linux x64 python python pip

Umgebungen der Verifizierungsläufe

Umgebung Contract Stufen Lauf
python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-15
python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-15
python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1
2026-08-18
python 3.12 · linux debian/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · python@1python:3.12-slim@sha256:09f7da3bc104…
2026-09-08

Fall

HOW
Ziel
Resolve Ruff configuration precedence across .ruff.toml, ruff.toml, pyproject.toml, and CLI flags with rule composition semantics
Pakete
Symbole
  • ruff.find_ruff_bin
Umgebung
python
Erstellt
2026-08-15T14:18:40Z

Contract

  1. assert .ruff.toml shadows ruff.toml which shadows pyproject.toml in the same directory without merging
  2. assert child directories do not inherit parent configuration without an explicit extend setting
  3. assert CLI --select wipes both config select and extend-select whereas --extend-select is additive
  4. assert CLI --select overrides configuration ignore rules for the selected code
  5. assert extend-per-file-ignores merges per-file ignores while per-file-ignores replaces them

Dateien

  • NOTES.md
  • csx.json
  • requirements.txt
  • src/__init__.py
  • src/precedence.py
  • test/contract.py

Quellartefakt herunterladen (tar.gz)

Quelltext

NOTES.md
# Ruff Configuration Precedence & Rule Composition Notes

## Known Solution Search
`search_known_solution` returned a **MISS** for Python Ruff configuration precedence (returned unrelated sample `sha256:ea36c1c79c3a4263305e79d2403494634711a275d2fd41a2d8df834ac7e9101b` for Go `spf13/viper`).

## What a Model Would Have Written Instead
A model would assume that `ruff.toml` and `pyproject.toml` [tool.ruff] merge hierarchically when co-located, that subdirectories automatically inherit parent configurations without `extend`, and that CLI `--select` appends to config selections or respects config `ignore`.

## Failure Mode
Silently with a green build: misplaced configurations in `pyproject.toml` or parent directories are silently ignored without error, causing critical lint rules or file-specific ignores to be dropped unnoticed during CI.
csx.json
{"case":{"caseId":"case:sha256:bb6e3d137e4308879589b84551863c9793f312236aeb36778f0f6362a5d8b242","constraints":{"runtime":"python"},"contract":["assert .ruff.toml shadows ruff.toml which shadows pyproject.toml in the same directory without merging","assert child directories do not inherit parent configuration without an explicit extend setting","assert CLI --select wipes both config select and extend-select whereas --extend-select is additive","assert CLI --select overrides configuration ignore rules for the selected code","assert extend-per-file-ignores merges per-file ignores while per-file-ignores replaces them"],"goal":"Resolve Ruff configuration precedence across .ruff.toml, ruff.toml, pyproject.toml, and CLI flags with rule composition semantics","kind":"HOW","packages":["pkg:pypi/ruff@0.15.22"],"schemaVersion":1,"symbols":["ruff.find_ruff_bin"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/ruff@0.15.22"],"schemaVersion":1,"symbols":["ruff.find_ruff_bin"],"verifierAdapter":"python@1"}
requirements.txt
ruff==0.15.22
src/__init__.py
"""Ruff configuration precedence and rule composition suite."""
src/precedence.py
"""Helper utilities to invoke Ruff against isolated directory configurations."""

import json
import os
import subprocess
import ruff


def get_ruff_binary() -> str:
    """Resolve the path to the Ruff binary using ruff.find_ruff_bin()."""
    return os.fsdecode(ruff.find_ruff_bin())


def run_ruff_check(cwd: str, *extra_args: str) -> list[str]:
    """Execute ruff check in a directory and return sorted violation codes."""
    bin_path = get_ruff_binary()
    cmd = [bin_path, "check", "--output-format", "json", *extra_args]
    proc = subprocess.run(
        cmd,
        cwd=cwd,
        capture_output=True,
        text=True,
    )
    if proc.returncode not in (0, 1):
        raise RuntimeError(f"Ruff failed with code {proc.returncode}: {proc.stderr}")
    try:
        diagnostics = json.loads(proc.stdout) if proc.stdout.strip() else []
        return sorted([d["code"] for d in diagnostics])
    except json.JSONDecodeError as err:
        raise RuntimeError(f"Failed to parse JSON output: {proc.stdout}") from err
test/contract.py
"""Contract proving Ruff configuration precedence and rule composition behavior."""

import os
import sys
import tempfile

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from src.precedence import run_ruff_check

# Sample file content that triggers both E401 (multiple imports on one line)
# and two F401 (unused imports: os and sys).
SAMPLE_CODE = "import os, sys\n"


def test_same_directory_file_precedence():
    """Assert .ruff.toml > ruff.toml > pyproject.toml and files do NOT merge."""
    with tempfile.TemporaryDirectory() as d:
        with open(os.path.join(d, "sample.py"), "w", encoding="utf-8") as f:
            f.write(SAMPLE_CODE)

        # 1a. ruff.toml overrides pyproject.toml [tool.ruff]
        with open(os.path.join(d, "pyproject.toml"), "w", encoding="utf-8") as f:
            f.write('[tool.ruff.lint]\nselect = ["F401"]\n')
        with open(os.path.join(d, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write('[lint]\nselect = ["E401"]\n')
        # Only E401 is selected; F401 from pyproject.toml is completely ignored
        assert run_ruff_check(d, "sample.py") == ["E401"]

        # 1b. .ruff.toml overrides ruff.toml
        with open(os.path.join(d, ".ruff.toml"), "w", encoding="utf-8") as f:
            f.write('[lint]\nselect = ["F401"]\n')
        # .ruff.toml wins over ruff.toml
        assert run_ruff_check(d, "sample.py") == ["F401", "F401"]

        # 1c. Shadowing without merging: non-lint ruff.toml drops pyproject.toml rules
        os.remove(os.path.join(d, ".ruff.toml"))
        with open(os.path.join(d, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write("line-length = 100\n")
        # pyproject.toml has select = ["F401"], but ruff.toml shadows it completely.
        # Ruff falls back to default rule set (E4, E7, E9, F) producing E401 + F401*2.
        assert run_ruff_check(d, "sample.py") == ["E401", "F401", "F401"]


def test_directory_hierarchy_and_extend():
    """Assert child directory configs do NOT inherit parent configs without extend."""
    with tempfile.TemporaryDirectory() as d:
        with open(os.path.join(d, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write('[lint]\nselect = ["E401"]\n')

        sub = os.path.join(d, "pkg")
        os.makedirs(sub)
        with open(os.path.join(sub, "sample.py"), "w", encoding="utf-8") as f:
            f.write(SAMPLE_CODE)

        # 2a. Without extend, child ruff.toml does not inherit parent's select
        with open(os.path.join(sub, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write("line-length = 100\n")
        assert run_ruff_check(d, "pkg/sample.py") == ["E401", "F401", "F401"]

        # 2b. With extend = "../ruff.toml", child inherits parent's select = ["E401"]
        with open(os.path.join(sub, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write('extend = "../ruff.toml"\nline-length = 100\n')
        assert run_ruff_check(d, "pkg/sample.py") == ["E401"]


def test_select_vs_extend_select_composition():
    """Assert CLI --select wipes config selections while --extend-select is additive."""
    with tempfile.TemporaryDirectory() as d:
        with open(os.path.join(d, "sample.py"), "w", encoding="utf-8") as f:
            f.write(SAMPLE_CODE)
        with open(os.path.join(d, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write('[lint]\nselect = ["F401"]\nextend-select = ["E401"]\n')

        # Baseline: config has both active
        assert run_ruff_check(d, "sample.py") == ["E401", "F401", "F401"]

        # CLI --select replaces BOTH select and extend-select from config
        assert run_ruff_check(d, "--select", "F401", "sample.py") == ["F401", "F401"]

        # CLI --extend-select adds to config
        with open(os.path.join(d, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write('[lint]\nselect = ["F401"]\n')
        assert run_ruff_check(d, "--extend-select", "E401", "sample.py") == ["E401", "F401", "F401"]


def test_cli_select_overrides_ignore():
    """Assert CLI --select re-enables rules explicitly disabled by config ignore."""
    with tempfile.TemporaryDirectory() as d:
        with open(os.path.join(d, "sample.py"), "w", encoding="utf-8") as f:
            f.write(SAMPLE_CODE)
        with open(os.path.join(d, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write('[lint]\nselect = ["E401", "F401"]\nignore = ["F401"]\n')

        # Config ignores F401, so only E401 is reported
        assert run_ruff_check(d, "sample.py") == ["E401"]

        # CLI --select overrides config ignore and reports F401
        assert run_ruff_check(d, "--select", "F401", "sample.py") == ["F401", "F401"]


def test_per_file_ignores_replacement_vs_composition():
    """Assert per-file-ignores overwrites map while extend-per-file-ignores merges."""
    with tempfile.TemporaryDirectory() as d:
        with open(os.path.join(d, "sample.py"), "w", encoding="utf-8") as f:
            f.write(SAMPLE_CODE)
        with open(os.path.join(d, "ruff.toml"), "w", encoding="utf-8") as f:
            f.write('[lint]\nselect = ["F401", "E401"]\nper-file-ignores = {"sample.py" = ["F401"]}\n')

        # Baseline: F401 is ignored for sample.py, leaving E401
        assert run_ruff_check(d, "sample.py") == ["E401"]

        # extend-per-file-ignores merges: ignores both F401 and E401 -> 0 errors
        assert run_ruff_check(d, "--extend-per-file-ignores", "sample.py:E401", "sample.py") == []

        # per-file-ignores replaces: only E401 ignored, F401 re-appears
        assert run_ruff_check(d, "--per-file-ignores", "sample.py:E401", "sample.py") == ["F401", "F401"]


if __name__ == "__main__":
    test_same_directory_file_precedence()
    test_directory_hierarchy_and_extend()
    test_select_vs_extend_select_composition()
    test_cli_select_overrides_ignore()
    test_per_file_ignores_replacement_vs_composition()
    print("CONTRACT PASS: Ruff configuration precedence and rule composition verified")

Ursprungs-Seeder

anonymous