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