From f76165e7611992d67346f01231d6531565284cd0 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Wed, 21 May 2025 16:17:24 +0200 Subject: [PATCH] Prevent types-*/setuptools/wheel runtime requirements in dependencies (#145381) Prevent setuptools/wheel runtime requirements in dependencies --- script/hassfest/requirements.py | 35 ++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/script/hassfest/requirements.py b/script/hassfest/requirements.py index 998593d20ec..dd5374461c3 100644 --- a/script/hassfest/requirements.py +++ b/script/hassfest/requirements.py @@ -28,6 +28,25 @@ PACKAGE_REGEX = re.compile( PIP_REGEX = re.compile(r"^(--.+\s)?([-_\.\w\d]+.*(?:==|>=|<=|~=|!=|<|>|===)?.*$)") PIP_VERSION_RANGE_SEPARATOR = re.compile(r"^(==|>=|<=|~=|!=|<|>|===)?(.*)$") +FORBIDDEN_PACKAGES = {"setuptools", "wheel"} +FORBIDDEN_PACKAGE_EXCEPTIONS = { + # Direct dependencies + "fitbit", # setuptools (fitbit) + "habitipy", # setuptools (habitica) + "influxdb-client", # setuptools (influxdb) + "microbeespy", # setuptools (microbees) + "pyefergy", # types-pytz (efergy) + "python-mystrom", # setuptools (mystrom) + # Transitive dependencies + "arrow", # types-python-dateutil (opower) + "asyncio-dgram", # setuptools (guardian / keba / minecraft_server) + "colorzero", # setuptools (remote_rpi_gpio / zha) + "incremental", # setuptools (azure_devops / lyric / ovo_energy / system_bridge) + "pbr", # setuptools (cmus / concord232 / mochad / nx584 / opnsense) + "pycountry-convert", # wheel (ecovacs) + "unasync", # setuptools (hive / osoenergy) +} + def validate(integrations: dict[str, Integration], config: Config) -> None: """Handle requirements for integrations.""" @@ -204,7 +223,21 @@ def get_requirements(integration: Integration, packages: set[str]) -> set[str]: ) continue - to_check.extend(item["dependencies"]) + dependencies: set[str] = item["dependencies"] + for pkg in dependencies: + if pkg.startswith("types-") or pkg in FORBIDDEN_PACKAGES: + if package in FORBIDDEN_PACKAGE_EXCEPTIONS: + integration.add_warning( + "requirements", + f"Package {pkg} should not be a runtime dependency in {package}", + ) + else: + integration.add_error( + "requirements", + f"Package {pkg} should not be a runtime dependency in {package}", + ) + + to_check.extend(dependencies) return all_requirements