Enable Ruff flake8-use-pathlib (PTH) (#13795)

Port existing code to pathlib
This commit is contained in:
Avasam
2025-05-05 12:59:43 -04:00
committed by GitHub
parent 0eb44e574c
commit 4265ee7c72
11 changed files with 101 additions and 113 deletions
+22 -22
View File
@@ -12,19 +12,20 @@ from __future__ import annotations
import argparse
import asyncio
import glob
import os.path
import re
import subprocess
import sys
import urllib.parse
from http import HTTPStatus
from importlib.metadata import distribution
from pathlib import Path
import aiohttp
import termcolor
PYRIGHT_CONFIG = "pyrightconfig.stricter.json"
from ts_utils.paths import STDLIB_PATH, STUBS_PATH
PYRIGHT_CONFIG = Path("pyrightconfig.stricter.json")
def search_pip_freeze_output(project: str, output: str) -> tuple[str, str] | None:
@@ -52,22 +53,22 @@ def get_installed_package_info(project: str) -> tuple[str, str] | None:
return search_pip_freeze_output(project, r.stdout)
def run_stubgen(package: str, output: str) -> None:
def run_stubgen(package: str, output: Path) -> None:
print(f"Running stubgen: stubgen -o {output} -p {package}")
subprocess.run(["stubgen", "-o", output, "-p", package, "--export-less"], check=True)
def run_stubdefaulter(stub_dir: str) -> None:
def run_stubdefaulter(stub_dir: Path) -> None:
print(f"Running stubdefaulter: stubdefaulter --packages {stub_dir}")
subprocess.run(["stubdefaulter", "--packages", stub_dir], check=False)
def run_black(stub_dir: str) -> None:
def run_black(stub_dir: Path) -> None:
print(f"Running Black: black {stub_dir}")
subprocess.run(["pre-commit", "run", "black", "--files", *glob.iglob(f"{stub_dir}/**/*.pyi")], check=False)
subprocess.run(["pre-commit", "run", "black", "--files", *stub_dir.rglob("*.pyi")], check=False)
def run_ruff(stub_dir: str) -> None:
def run_ruff(stub_dir: Path) -> None:
print(f"Running Ruff: ruff check {stub_dir} --fix-only")
subprocess.run([sys.executable, "-m", "ruff", "check", stub_dir, "--fix-only"], check=False)
@@ -115,14 +116,14 @@ async def get_upstream_repo_url(project: str) -> str | None:
return None
def create_metadata(project: str, stub_dir: str, version: str) -> None:
def create_metadata(project: str, stub_dir: Path, version: str) -> None:
"""Create a METADATA.toml file."""
match = re.match(r"[0-9]+.[0-9]+", version)
if match is None:
sys.exit(f"Error: Cannot parse version number: {version}")
filename = os.path.join(stub_dir, "METADATA.toml")
filename = stub_dir / "METADATA.toml"
version = match.group(0)
if os.path.exists(filename):
if filename.exists():
return
metadata = f'version = "{version}.*"\n'
upstream_repo_url = asyncio.run(get_upstream_repo_url(project))
@@ -135,13 +136,12 @@ def create_metadata(project: str, stub_dir: str, version: str) -> None:
else:
metadata += f'upstream_repository = "{upstream_repo_url}"\n'
print(f"Writing {filename}")
with open(filename, "w", encoding="UTF-8") as file:
file.write(metadata)
filename.write_text(metadata, encoding="UTF-8")
def add_pyright_exclusion(stub_dir: str) -> None:
def add_pyright_exclusion(stub_dir: Path) -> None:
"""Exclude stub_dir from strict pyright checks."""
with open(PYRIGHT_CONFIG, encoding="UTF-8") as f:
with PYRIGHT_CONFIG.open(encoding="UTF-8") as f:
lines = f.readlines()
i = 0
while i < len(lines) and not lines[i].strip().startswith('"exclude": ['):
@@ -167,7 +167,7 @@ def add_pyright_exclusion(stub_dir: str) -> None:
third_party_excludes[-1] = last_line + "\n"
# Must use forward slash in the .json file
line_to_add = f' "{stub_dir}",\n'.replace("\\", "/")
line_to_add = f' "{stub_dir.as_posix()}",\n'
if line_to_add in third_party_excludes:
print(f"{PYRIGHT_CONFIG} already up-to-date")
@@ -177,7 +177,7 @@ def add_pyright_exclusion(stub_dir: str) -> None:
third_party_excludes.sort(key=str.lower)
print(f"Updating {PYRIGHT_CONFIG}")
with open(PYRIGHT_CONFIG, "w", encoding="UTF-8") as f:
with PYRIGHT_CONFIG.open("w", encoding="UTF-8") as f:
f.writelines(before_third_party_excludes)
f.writelines(third_party_excludes)
f.writelines(after_third_party_excludes)
@@ -194,7 +194,7 @@ def main() -> None:
parser.add_argument("--package", help="generate stubs for this Python package (default is autodetected)")
args = parser.parse_args()
project = args.project
package = args.package
package: str = args.package
if not re.match(r"[a-zA-Z0-9-_.]+$", project):
sys.exit(f"Invalid character in project name: {project!r}")
@@ -214,7 +214,7 @@ def main() -> None:
print(f'Using detected package "{package}" for project "{project}"', file=sys.stderr)
print("Suggestion: Try again with --package argument if that's not what you wanted", file=sys.stderr)
if not os.path.isdir("stubs") or not os.path.isdir("stdlib"):
if not STUBS_PATH.is_dir() or not STDLIB_PATH.is_dir():
sys.exit("Error: Current working directory must be the root of typeshed repository")
# Get normalized project name and version of installed package.
@@ -226,9 +226,9 @@ def main() -> None:
sys.exit(1)
project, version = info
stub_dir = os.path.join("stubs", project)
package_dir = os.path.join(stub_dir, package)
if os.path.exists(package_dir):
stub_dir = STUBS_PATH / project
package_dir = stub_dir / package
if package_dir.exists():
sys.exit(f"Error: {package_dir} already exists (delete it first)")
run_stubgen(package, stub_dir)
+4 -3
View File
@@ -4,6 +4,7 @@ import subprocess
import sys
from collections.abc import Iterable
from http.client import HTTPResponse
from pathlib import Path
from typing import TYPE_CHECKING
from urllib.request import urlopen
from zipfile import ZipFile
@@ -18,11 +19,11 @@ if TYPE_CHECKING:
MYPY_PROTOBUF_VERSION = mypy_protobuf__version__
def download_file(url: str, destination: StrPath) -> None:
def download_file(url: str, destination: Path) -> None:
print(f"Downloading '{url}' to '{destination}'")
resp: HTTPResponse
with urlopen(url) as resp, open(destination, "wb") as file:
file.write(resp.read())
with urlopen(url) as resp:
destination.write_bytes(resp.read())
def extract_archive(archive_path: StrPath, destination: StrPath) -> None:
+2 -2
View File
@@ -33,7 +33,7 @@ PROTO_FILE_PATTERN = re.compile(r'"//:(.*)_proto"')
def extract_python_version(file_path: Path) -> str:
"""Extract the Python version from https://github.com/protocolbuffers/protobuf/blob/main/version.json ."""
with open(file_path) as file:
with file_path.open() as file:
data: dict[str, Any] = json.load(file)
# The root key will be the protobuf source code version
version = next(iter(data.values()))["languages"]["python"]
@@ -47,7 +47,7 @@ def extract_proto_file_paths(temp_dir: Path) -> list[str]:
as described in py_proto_library calls in
https://github.com/protocolbuffers/protobuf/blob/main/python/dist/BUILD.bazel .
"""
with open(temp_dir / EXTRACTED_PACKAGE_DIR / "python" / "dist" / "BUILD.bazel") as file:
with (temp_dir / EXTRACTED_PACKAGE_DIR / "python" / "dist" / "BUILD.bazel").open() as file:
matched_lines = filter(None, (re.search(PROTO_FILE_PATTERN, line) for line in file))
proto_files = [
EXTRACTED_PACKAGE_DIR + "/src/google/protobuf/" + match.group(1).replace("compiler_", "compiler/") + ".proto"
+3 -6
View File
@@ -6,7 +6,6 @@ Generally, new minor versions are a good time to update the stubs.
from __future__ import annotations
import os
import re
import shutil
import subprocess
@@ -72,21 +71,19 @@ def post_creation() -> None:
for path in STUBS_FOLDER.rglob("*_pb2.pyi"):
print(f"Fixing imports in '{path}'")
with open(path, encoding="utf-8") as file:
filedata = file.read()
filedata = path.read_text(encoding="utf-8")
# Replace the target string
filedata = re.sub(TSL_IMPORT_PATTERN, "\\1tensorflow.tsl.", filedata)
filedata = re.sub(XLA_IMPORT_PATTERN, "\\1tensorflow.compiler.xla.", filedata)
# Write the file out again
with open(path, "w", encoding="utf-8") as file:
file.write(filedata)
path.write_text(filedata, encoding="utf-8")
print()
for to_remove in PROTOS_TO_REMOVE:
file_path = STUBS_FOLDER / "tensorflow" / to_remove
os.remove(file_path)
file_path.unlink()
print(f"Removed '{file_path}'")