Use functools.cache instead of global in hassfest requirements (#82124)

This commit is contained in:
Aarni Koskela 2022-11-16 14:13:45 +02:00 committed by GitHub
parent d38bae76be
commit 322cb352ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,6 +2,7 @@
from __future__ import annotations from __future__ import annotations
from collections import deque from collections import deque
from functools import cache
import json import json
import os import os
import re import re
@ -36,7 +37,6 @@ SUPPORTED_PYTHON_VERSIONS = [
".".join(map(str, version_tuple)) for version_tuple in SUPPORTED_PYTHON_TUPLES ".".join(map(str, version_tuple)) for version_tuple in SUPPORTED_PYTHON_TUPLES
] ]
STD_LIBS = {version: set(stdlib_list(version)) for version in SUPPORTED_PYTHON_VERSIONS} STD_LIBS = {version: set(stdlib_list(version)) for version in SUPPORTED_PYTHON_VERSIONS}
PIPDEPTREE_CACHE = None
IGNORE_VIOLATIONS = { IGNORE_VIOLATIONS = {
# Still has standard library requirements. # Still has standard library requirements.
@ -60,8 +60,6 @@ def validate(integrations: dict[str, Integration], config: Config):
validate_requirements_format(integration) validate_requirements_format(integration)
return return
ensure_cache()
# check for incompatible requirements # check for incompatible requirements
disable_tqdm = config.specific_integrations or os.environ.get("CI", False) disable_tqdm = config.specific_integrations or os.environ.get("CI", False)
@ -167,8 +165,9 @@ def validate_requirements(integration: Integration):
) )
def ensure_cache(): @cache
"""Ensure we have a cache of pipdeptree. def get_pipdeptree():
"""Get pipdeptree output. Cached on first invocation.
{ {
"flake8-docstring": { "flake8-docstring": {
@ -179,12 +178,7 @@ def ensure_cache():
} }
} }
""" """
global PIPDEPTREE_CACHE deptree = {}
if PIPDEPTREE_CACHE is not None:
return
cache = {}
for item in json.loads( for item in json.loads(
subprocess.run( subprocess.run(
@ -194,17 +188,16 @@ def ensure_cache():
text=True, text=True,
).stdout ).stdout
): ):
cache[item["package"]["key"]] = { deptree[item["package"]["key"]] = {
**item["package"], **item["package"],
"dependencies": {dep["key"] for dep in item["dependencies"]}, "dependencies": {dep["key"] for dep in item["dependencies"]},
} }
return deptree
PIPDEPTREE_CACHE = cache
def get_requirements(integration: Integration, packages: set[str]) -> set[str]: def get_requirements(integration: Integration, packages: set[str]) -> set[str]:
"""Return all (recursively) requirements for an integration.""" """Return all (recursively) requirements for an integration."""
ensure_cache() deptree = get_pipdeptree()
all_requirements = set() all_requirements = set()
@ -218,7 +211,7 @@ def get_requirements(integration: Integration, packages: set[str]) -> set[str]:
all_requirements.add(package) all_requirements.add(package)
item = PIPDEPTREE_CACHE.get(package) item = deptree.get(package)
if item is None: if item is None:
# Only warn if direct dependencies could not be resolved # Only warn if direct dependencies could not be resolved
@ -238,9 +231,7 @@ def install_requirements(integration: Integration, requirements: set[str]) -> bo
Return True if successful. Return True if successful.
""" """
global PIPDEPTREE_CACHE deptree = get_pipdeptree()
ensure_cache()
for req in requirements: for req in requirements:
match = PIP_REGEX.search(req) match = PIP_REGEX.search(req)
@ -261,7 +252,7 @@ def install_requirements(integration: Integration, requirements: set[str]) -> bo
if normalized and "==" in requirement_arg: if normalized and "==" in requirement_arg:
ver = requirement_arg.split("==")[-1] ver = requirement_arg.split("==")[-1]
item = PIPDEPTREE_CACHE.get(normalized) item = deptree.get(normalized)
is_installed = item and item["installed_version"] == ver is_installed = item and item["installed_version"] == ver
if not is_installed: if not is_installed:
@ -287,7 +278,7 @@ def install_requirements(integration: Integration, requirements: set[str]) -> bo
else: else:
# Clear the pipdeptree cache if something got installed # Clear the pipdeptree cache if something got installed
if "Successfully installed" in result.stdout: if "Successfully installed" in result.stdout:
PIPDEPTREE_CACHE = None get_pipdeptree.cache_clear()
if integration.errors: if integration.errors:
return False return False