Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/tools/lint/python/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 6 kB image not shown  

Quelle  ruff.py

  Sprache: Python
 

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

import json
import os
import re
import signal
import subprocess
from pathlib import Path

import toml
from mozlint import result

here = os.path.abspath(os.path.dirname(__file__))


def get_pyproject_excludes(pyproject_toml: Path):
    if not pyproject_toml.exists():
        return []

    with pyproject_toml.open() as f:
        data = toml.load(f)

    return data.get("tool", {}).get("ruff", {}).get("exclude", [])


def get_ruff_version(binary):
    """
    Returns found binary's version
    """
    try:
        output = subprocess.check_output(
            [binary, "--version"],
            stderr=subprocess.STDOUT,
            text=True,
        )
    except subprocess.CalledProcessError as e:
        output = e.output

    matches = re.match(r"ruff ([0-9\.]+)", output)
    if matches:
        return matches[1]
    print(f"Error: Could not parse the version '{output}'")


def run_process(cmd, log):
    orig = signal.signal(signal.SIGINT, signal.SIG_IGN)
    proc = subprocess.Popen(
        cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
    )
    signal.signal(signal.SIGINT, orig)
    try:
        stdout, stderr = proc.communicate()
        proc.wait()
        for line in stderr.splitlines():
            if line:
                log.debug(line)
    except KeyboardInterrupt:
        proc.kill()
        return "", -1

    return stdout, proc.returncode


def lint(paths, config, log, **lintargs):
    fixed = 0
    results = []

    if not paths:
        return {"results": results, "fixed": fixed}

    args = ["ruff""check""--force-exclude"] + paths

    if config.get("exclude"):
        args.append(f"--extend-exclude={','.join(config['exclude'])}")

    if lintargs.get("extra_args"):
        args.extend(lintargs["extra_args"])

    warning_rules = set(config.get("warning-rules", []))
    if lintargs.get("fix"):
        # Do a first pass with --fix-only as the json format doesn't return the
        # number of fixed issues.
        fix_args = args + ["--fix-only"]
        if not lintargs.get("warning"):
            # Don't fix warnings to limit unrelated changes sneaking into patches.
            # except when  --fix -W  is passed
            fix_args.append(f"--extend-ignore={','.join(warning_rules)}")

        log.debug(f"Running --fix: {fix_args}")
        output, returncode = run_process(fix_args, log)
        if returncode == 2:
            log.error(
                f"ruff terminated abnormally (invalid config, CLI options, or internal error): {output}"
            )
            return {"results": [], "fixed"0}
        matches = re.match(r"Fixed (\d+) errors?.", output)
        if matches:
            fixed = int(matches[1])
    args += ["--output-format=json"]
    log.debug(f"Running with args: {args}")

    output, returncode = run_process(args, log)
    if returncode == 2:
        log.error(
            f"ruff terminated abnormally (invalid config, CLI options, or internal error): {output}"
        )
        return {"results": [], "fixed": fixed}
    if not output:
        return {"results": [], "fixed": fixed}

    try:
        issues = json.loads(output)
    except json.JSONDecodeError:
        log.error(f"could not parse output: {output}")
        return []

    for issue in issues:
        res = {
            "path": issue["filename"],
            "lineno": issue["location"]["row"],
            "column": issue["location"]["column"],
            "lineoffset": issue["end_location"]["row"] - issue["location"]["row"],
            "message": issue["message"],
            "rule": issue["code"],
            "level""error",
        }
        if issue["code"is not None and any(
            issue["code"].startswith(w) for w in warning_rules
        ):
            res["level"] = "warning"

        if issue["fix"]:
            res["hint"] = issue["fix"]["message"]

        results.append(result.from_config(config, **res))

    return {"results": results, "fixed": fixed}


def format(paths, config, log, **lintargs):
    """Run ruff format to check/fix Python formatting."""
    fixed = 0
    results = []

    if not paths:
        return {"results": results, "fixed": fixed}

    args = ["ruff""format""--force-exclude"] + paths

    log.debug(f"Ruff version {get_ruff_version('ruff')}")

    topsrcdir = Path(lintargs["root"])
    pyproject_toml = topsrcdir / "pyproject.toml"
    exclude_patterns = get_pyproject_excludes(pyproject_toml)

    # Merge pyproject.toml excludes with config excludes.
    # This is needed because ruff format's --exclude replaces rather than extends
    # the pyproject.toml excludes (unlike ruff check which has --extend-exclude).
    if config.get("exclude"):
        exclude_patterns.extend(config["exclude"])

    for exclude in exclude_patterns:
        args.append(f"--exclude={exclude}")

    if lintargs.get("fix"):
        # Do a first pass to fix, as JSON output doesn't include fix counts
        log.debug(f"Running --fix: {args}")
        output, returncode = run_process(args, log)
        if returncode == 2:
            log.error(
                f"ruff terminated abnormally (invalid config, CLI options, or internal error): {output}"
            )
            return {"results": [], "fixed"0}
        match = re.search(r"(\d+) files? reformatted", output)
        if match:
            fixed = int(match.group(1))

    args += ["--check""--output-format=json"]
    log.debug(f"Running with args: {args}")

    output, returncode = run_process(args, log)
    if returncode == 2 and not output:
        log.error(
            "ruff format terminated abnormally (invalid config, CLI options, or internal error)"
        )
        return {"results": [], "fixed": fixed}
    if not output:
        return {"results": [], "fixed": fixed}

    try:
        issues = json.loads(output)
    except json.JSONDecodeError:
        log.error(f"could not parse output: {output}")
        return {"results": [], "fixed": fixed}

    for issue in issues:
        res = {
            "path": issue["filename"],
            "lineno": issue["location"]["row"],
            "column": issue["location"]["column"],
            "message": issue["message"],
            "level""error",
        }
        results.append(result.from_config(config, **res))

    return {"results": results, "fixed": fixed}

Messung V0.5 in Prozent
C=95 H=89 G=91

¤ Dauer der Verarbeitung: 0.20 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.