Skip to content

Commit

Permalink
Enable Ruff PTH for the script directory (#124441)
Browse files Browse the repository at this point in the history
* Enable Ruff PTH for the script directory

* Address review comments

* Fix translations script

* Update script/hassfest/config_flow.py

Co-authored-by: Martin Hjelmare <[email protected]>

---------

Co-authored-by: Martin Hjelmare <[email protected]>
  • Loading branch information
autinerd and MartinHjelmare authored Sep 6, 2024
1 parent 7752789 commit 1db6832
Show file tree
Hide file tree
Showing 18 changed files with 125 additions and 163 deletions.
5 changes: 5 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,7 @@ select = [
"PIE", # flake8-pie
"PL", # pylint
"PT", # flake8-pytest-style
"PTH", # flake8-pathlib
"PYI", # flake8-pyi
"RET", # flake8-return
"RSE", # flake8-raise
Expand Down Expand Up @@ -905,5 +906,9 @@ split-on-trailing-comma = false
"homeassistant/scripts/*" = ["T201"]
"script/*" = ["T20"]

# Temporary
"homeassistant/**" = ["PTH"]
"tests/**" = ["PTH"]

[tool.ruff.lint.mccabe]
max-complexity = 25
12 changes: 5 additions & 7 deletions script/gen_requirements_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import difflib
import importlib
from operator import itemgetter
import os
from pathlib import Path
import pkgutil
import re
Expand Down Expand Up @@ -82,8 +81,8 @@
)


CONSTRAINT_PATH = os.path.join(
os.path.dirname(__file__), "../homeassistant/package_constraints.txt"
CONSTRAINT_PATH = (
Path(__file__).parent.parent / "homeassistant" / "package_constraints.txt"
)
CONSTRAINT_BASE = """
# Constrain pycryptodome to avoid vulnerability
Expand Down Expand Up @@ -256,8 +255,7 @@ def explore_module(package: str, explore_children: bool) -> list[str]:

def core_requirements() -> list[str]:
"""Gather core requirements out of pyproject.toml."""
with open("pyproject.toml", "rb") as fp:
data = tomllib.load(fp)
data = tomllib.loads(Path("pyproject.toml").read_text())
dependencies: list[str] = data["project"]["dependencies"]
return dependencies

Expand Down Expand Up @@ -528,7 +526,7 @@ def diff_file(filename: str, content: str) -> list[str]:

def main(validate: bool, ci: bool) -> int:
"""Run the script."""
if not os.path.isfile("requirements_all.txt"):
if not Path("requirements_all.txt").is_file():
print("Run this from HA root dir")
return 1

Expand Down Expand Up @@ -590,7 +588,7 @@ def main(validate: bool, ci: bool) -> int:
def _get_hassfest_config() -> Config:
"""Get hassfest config."""
return Config(
root=Path(".").absolute(),
root=Path().absolute(),
specific_integrations=None,
action="validate",
requirements=True,
Expand Down
17 changes: 7 additions & 10 deletions script/hassfest/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import argparse
from operator import attrgetter
import pathlib
from pathlib import Path
import sys
from time import monotonic

Expand Down Expand Up @@ -63,9 +63,9 @@
]


def valid_integration_path(integration_path: pathlib.Path | str) -> pathlib.Path:
def valid_integration_path(integration_path: Path | str) -> Path:
"""Test if it's a valid integration."""
path = pathlib.Path(integration_path)
path = Path(integration_path)
if not path.is_dir():
raise argparse.ArgumentTypeError(f"{integration_path} is not a directory.")

Expand Down Expand Up @@ -109,8 +109,8 @@ def get_config() -> Config:
)
parser.add_argument(
"--core-integrations-path",
type=pathlib.Path,
default=pathlib.Path("homeassistant/components"),
type=Path,
default=Path("homeassistant/components"),
help="Path to core integrations",
)
parsed = parser.parse_args()
Expand All @@ -123,14 +123,11 @@ def get_config() -> Config:
"Generate is not allowed when limiting to specific integrations"
)

if (
not parsed.integration_path
and not pathlib.Path("requirements_all.txt").is_file()
):
if not parsed.integration_path and not Path("requirements_all.txt").is_file():
raise RuntimeError("Run from Home Assistant root")

return Config(
root=pathlib.Path(".").absolute(),
root=Path().absolute(),
specific_integrations=parsed.integration_path,
action=parsed.action,
requirements=parsed.requirements,
Expand Down
18 changes: 7 additions & 11 deletions script/hassfest/bluetooth.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,15 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

with open(str(bluetooth_path)) as fp:
current = fp.read()
if current != content:
config.add_error(
"bluetooth",
"File bluetooth.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
return
if bluetooth_path.read_text() != content:
config.add_error(
"bluetooth",
"File bluetooth.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate bluetooth file."""
bluetooth_path = config.root / "homeassistant/generated/bluetooth.py"
with open(str(bluetooth_path), "w") as fp:
fp.write(f"{config.cache['bluetooth']}")
bluetooth_path.write_text(f"{config.cache['bluetooth']}")
17 changes: 7 additions & 10 deletions script/hassfest/codeowners.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,15 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

with open(str(codeowners_path)) as fp:
if fp.read().strip() != content:
config.add_error(
"codeowners",
"File CODEOWNERS is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
return
if codeowners_path.read_text() != content + "\n":
config.add_error(
"codeowners",
"File CODEOWNERS is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate CODEOWNERS."""
codeowners_path = config.root / "CODEOWNERS"
with open(str(codeowners_path), "w") as fp:
fp.write(f"{config.cache['codeowners']}\n")
codeowners_path.write_text(f"{config.cache['codeowners']}\n")
38 changes: 16 additions & 22 deletions script/hassfest/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from __future__ import annotations

import json
import pathlib
from typing import Any

from .brand import validate as validate_brands
Expand Down Expand Up @@ -216,36 +215,31 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

brands = Brand.load_dir(pathlib.Path(config.root / "homeassistant/brands"), config)
brands = Brand.load_dir(config.root / "homeassistant/brands", config)
validate_brands(brands, integrations, config)

with open(str(config_flow_path)) as fp:
if fp.read() != content:
config.add_error(
"config_flow",
"File config_flows.py is not up to date. "
"Run python3 -m script.hassfest",
fixable=True,
)
if config_flow_path.read_text() != content:
config.add_error(
"config_flow",
"File config_flows.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)

config.cache["integrations"] = content = _generate_integrations(
brands, integrations, config
)
with open(str(integrations_path)) as fp:
if fp.read() != content + "\n":
config.add_error(
"config_flow",
"File integrations.json is not up to date. "
"Run python3 -m script.hassfest",
fixable=True,
)
if integrations_path.read_text() != content + "\n":
config.add_error(
"config_flow",
"File integrations.json is not up to date. "
"Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate config flow file."""
config_flow_path = config.root / "homeassistant/generated/config_flows.py"
integrations_path = config.root / "homeassistant/generated/integrations.json"
with open(str(config_flow_path), "w") as fp:
fp.write(f"{config.cache['config_flow']}")
with open(str(integrations_path), "w") as fp:
fp.write(f"{config.cache['integrations']}\n")
config_flow_path.write_text(f"{config.cache['config_flow']}")
integrations_path.write_text(f"{config.cache['integrations']}\n")
18 changes: 7 additions & 11 deletions script/hassfest/dhcp.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,15 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

with open(str(dhcp_path)) as fp:
current = fp.read()
if current != content:
config.add_error(
"dhcp",
"File dhcp.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
return
if dhcp_path.read_text() != content:
config.add_error(
"dhcp",
"File dhcp.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate dhcp file."""
dhcp_path = config.root / "homeassistant/generated/dhcp.py"
with open(str(dhcp_path), "w") as fp:
fp.write(f"{config.cache['dhcp']}")
dhcp_path.write_text(f"{config.cache['dhcp']}")
8 changes: 4 additions & 4 deletions script/hassfest/docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@
"""


def _get_package_versions(file: str, packages: set[str]) -> dict[str, str]:
def _get_package_versions(file: Path, packages: set[str]) -> dict[str, str]:
package_versions: dict[str, str] = {}
with open(file, encoding="UTF-8") as fp:
with file.open(encoding="UTF-8") as fp:
for _, line in enumerate(fp):
if package_versions.keys() == packages:
return package_versions
Expand Down Expand Up @@ -173,10 +173,10 @@ def _generate_files(config: Config) -> list[File]:
) * 1000

package_versions = _get_package_versions(
"requirements_test.txt", {"pipdeptree", "tqdm", "uv"}
Path("requirements_test.txt"), {"pipdeptree", "tqdm", "uv"}
)
package_versions |= _get_package_versions(
"requirements_test_pre_commit.txt", {"ruff"}
Path("requirements_test_pre_commit.txt"), {"ruff"}
)

return [
Expand Down
3 changes: 1 addition & 2 deletions script/hassfest/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
def validate(integrations: dict[str, Integration], config: Config) -> None:
"""Validate project metadata keys."""
metadata_path = config.root / "pyproject.toml"
with open(metadata_path, "rb") as fp:
data = tomllib.load(fp)
data = tomllib.loads(metadata_path.read_text())

try:
if data["project"]["version"] != __version__:
Expand Down
16 changes: 7 additions & 9 deletions script/hassfest/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,15 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

with open(str(mqtt_path)) as fp:
if fp.read() != content:
config.add_error(
"mqtt",
"File mqtt.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
if mqtt_path.read_text() != content:
config.add_error(
"mqtt",
"File mqtt.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate MQTT file."""
mqtt_path = config.root / "homeassistant/generated/mqtt.py"
with open(str(mqtt_path), "w") as fp:
fp.write(f"{config.cache['mqtt']}")
mqtt_path.write_text(f"{config.cache['mqtt']}")
16 changes: 7 additions & 9 deletions script/hassfest/ssdp.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,15 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

with open(str(ssdp_path)) as fp:
if fp.read() != content:
config.add_error(
"ssdp",
"File ssdp.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
if ssdp_path.read_text() != content:
config.add_error(
"ssdp",
"File ssdp.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate ssdp file."""
ssdp_path = config.root / "homeassistant/generated/ssdp.py"
with open(str(ssdp_path), "w") as fp:
fp.write(f"{config.cache['ssdp']}")
ssdp_path.write_text(f"{config.cache['ssdp']}")
18 changes: 7 additions & 11 deletions script/hassfest/usb.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,15 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

with open(str(usb_path)) as fp:
current = fp.read()
if current != content:
config.add_error(
"usb",
"File usb.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
return
if usb_path.read_text() != content:
config.add_error(
"usb",
"File usb.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate usb file."""
usb_path = config.root / "homeassistant/generated/usb.py"
with open(str(usb_path), "w") as fp:
fp.write(f"{config.cache['usb']}")
usb_path.write_text(f"{config.cache['usb']}")
18 changes: 7 additions & 11 deletions script/hassfest/zeroconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,15 @@ def validate(integrations: dict[str, Integration], config: Config) -> None:
if config.specific_integrations:
return

with open(str(zeroconf_path)) as fp:
current = fp.read()
if current != content:
config.add_error(
"zeroconf",
"File zeroconf.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)
return
if zeroconf_path.read_text() != content:
config.add_error(
"zeroconf",
"File zeroconf.py is not up to date. Run python3 -m script.hassfest",
fixable=True,
)


def generate(integrations: dict[str, Integration], config: Config) -> None:
"""Generate zeroconf file."""
zeroconf_path = config.root / "homeassistant/generated/zeroconf.py"
with open(str(zeroconf_path), "w") as fp:
fp.write(f"{config.cache['zeroconf']}")
zeroconf_path.write_text(f"{config.cache['zeroconf']}")
Loading

0 comments on commit 1db6832

Please sign in to comment.