Ctrl K
ComunidadGuías…

scripts/p5_wave2_fix_core_ops.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python3
"""P5 wave2b: minimal mypy strict fixes for butler/core/*_ops.py."""

from __future__ import annotations

import re
import subprocess
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]


def ensure_import(src: str, name: str) -> str:
    if re.search(rf"\b{name}\b", src.split("def ", 1)[0]) is None and name not in src:
        return src
    if name == "cast" and "cast(" in src:
        if re.search(r"from typing import[^\n]*\bcast\b", src):
            return src
        if "from typing import" in src:
            return re.sub(
                r"(from typing import [^\n]+)",
                lambda m: m.group(1) + (", cast" if "cast" not in m.group(1) else ""),
                src,
                count=1,
            )
        return "from typing import cast\n" + src
    if name == "Any":
        if re.search(r"from typing import[^\n]*\bAny\b", src):
            return src
        if "from typing import" in src:
            return re.sub(
                r"(from typing import [^\n]+)",
                lambda m: m.group(1) + (", Any" if "Any" not in m.group(1) else ""),
                src,
                count=1,
            )
        return "from typing import Any\n" + src
    return src


def fix_file(path: Path) -> bool:
    src = path.read_text(encoding="utf-8")
    orig = src

    src = re.sub(r": dict\)(?!])", ": dict[str, Any])", src)
    src = re.sub(r": dict \|", ": dict[str, Any] |", src)
    src = re.sub(r": dict,", ": dict[str, Any],", src)
    src = re.sub(r": dict$", ": dict[str, Any]", src, flags=re.MULTILINE)
    src = re.sub(r"list\[dict\]", "list[dict[str, Any]]", src)
    src = re.sub(r": list\)(?!])", ": list[Any])", src)
    src = re.sub(r"-> list:", "-> list[Any]:", src)
    src = re.sub(r"\bdict\[\]", "dict[str, Any]", src)
    src = re.sub(r"\blist\[\]", "list[Any]", src)

    # remove stale unused ignores on imports (strict may not need them)
    src = re.sub(
        r"  # type: ignore\[import-untyped\]\n",
        "\n",
        src,
    )

    if "dict[str, Any]" in src or ": dict[str, Any]" in src:
        src = ensure_import(src, "Any")
    if "list[Any]" in src:
        src = ensure_import(src, "Any")

    if src != orig:
        path.write_text(src, encoding="utf-8")
        return True
    return False


def main() -> int:
    changed = 0
    for p in sorted((ROOT / "butler/core").glob("*_ops.py")):
        if fix_file(p):
            changed += 1
            print("auto", p.relative_to(ROOT))
    return 0


if __name__ == "__main__":
    raise SystemExit(main())