CodeSampleX

示例

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

已验证示例 — pypi ruff 0.15.22: Resolve Ruff configuration precedence across .ruff.toml, ruff.toml, pyproject.toml, and CLI flags with rule composition semantics.…

sha256:75daf6792eb7841ca9e151e1fb02b7500a9163b9964cf979f20e219fa0fdf01f

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 MIT-0

执行证据

声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。

证据依据
签名契约通过
验证回执
4
构建过它的签名密钥
3
声明的环境 python linux x64 python python pip

验证运行环境

环境 契约 阶段 运行日期
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

案例

HOW
目标
Resolve Ruff configuration precedence across .ruff.toml, ruff.toml, pyproject.toml, and CLI flags with rule composition semantics
包
符号
  • ruff.find_ruff_bin
环境
python
创建时间
2026-08-15T14:18:40Z

契约

  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

文件

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

下载源代码构件 (tar.gz)

源代码

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")

原始种子者

anonymous