mirror of
https://github.com/home-assistant/core.git
synced 2025-04-19 14:57:52 +00:00
Cache AST module parsing in hassfest (#132244)
This commit is contained in:
parent
e54d929573
commit
9771998415
@ -1 +1,14 @@
|
||||
"""Manifest validator."""
|
||||
|
||||
import ast
|
||||
from functools import lru_cache
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@lru_cache
|
||||
def ast_parse_module(file_path: Path) -> ast.Module:
|
||||
"""Parse a module.
|
||||
|
||||
Cached to avoid parsing the same file for each plugin.
|
||||
"""
|
||||
return ast.parse(file_path.read_text())
|
||||
|
@ -6,6 +6,7 @@ import ast
|
||||
|
||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN
|
||||
|
||||
from . import ast_parse_module
|
||||
from .model import Config, Integration
|
||||
|
||||
CONFIG_SCHEMA_IGNORE = {
|
||||
@ -60,7 +61,7 @@ def _validate_integration(config: Config, integration: Integration) -> None:
|
||||
# Virtual integrations don't have any implementation
|
||||
return
|
||||
|
||||
init = ast.parse(init_file.read_text())
|
||||
init = ast_parse_module(init_file)
|
||||
|
||||
# No YAML Support
|
||||
if not _has_function(
|
||||
@ -81,7 +82,7 @@ def _validate_integration(config: Config, integration: Integration) -> None:
|
||||
|
||||
config_file = integration.path / "config.py"
|
||||
if config_file.is_file():
|
||||
config_module = ast.parse(config_file.read_text())
|
||||
config_module = ast_parse_module(config_file)
|
||||
if _has_function(config_module, ast.AsyncFunctionDef, "async_validate_config"):
|
||||
return
|
||||
|
||||
|
@ -10,6 +10,7 @@ from pathlib import Path
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.requirements import DISCOVERY_INTEGRATIONS
|
||||
|
||||
from . import ast_parse_module
|
||||
from .model import Config, Integration
|
||||
|
||||
|
||||
@ -33,7 +34,7 @@ class ImportCollector(ast.NodeVisitor):
|
||||
self._cur_fil_dir = fil.relative_to(self.integration.path)
|
||||
self.referenced[self._cur_fil_dir] = set()
|
||||
try:
|
||||
self.visit(ast.parse(fil.read_text()))
|
||||
self.visit(ast_parse_module(fil))
|
||||
except SyntaxError as e:
|
||||
e.add_note(f"File: {fil}")
|
||||
raise
|
||||
|
@ -5,6 +5,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/c
|
||||
|
||||
import ast
|
||||
|
||||
from script.hassfest import ast_parse_module
|
||||
from script.hassfest.model import Integration
|
||||
|
||||
|
||||
@ -20,7 +21,7 @@ def validate(integration: Integration) -> list[str] | None:
|
||||
"""Validate that the integration has a config flow."""
|
||||
|
||||
init_file = integration.path / "__init__.py"
|
||||
init = ast.parse(init_file.read_text())
|
||||
init = ast_parse_module(init_file)
|
||||
|
||||
if not _has_unload_entry_function(init):
|
||||
return [
|
||||
|
@ -5,6 +5,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/d
|
||||
|
||||
import ast
|
||||
|
||||
from script.hassfest import ast_parse_module
|
||||
from script.hassfest.model import Integration
|
||||
|
||||
DIAGNOSTICS_FUNCTIONS = {
|
||||
@ -31,7 +32,7 @@ def validate(integration: Integration) -> list[str] | None:
|
||||
"(is missing diagnostics.py)",
|
||||
]
|
||||
|
||||
diagnostics = ast.parse(diagnostics_file.read_text())
|
||||
diagnostics = ast_parse_module(diagnostics_file)
|
||||
|
||||
if not _has_diagnostics_function(diagnostics):
|
||||
return [
|
||||
|
@ -5,6 +5,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/d
|
||||
|
||||
import ast
|
||||
|
||||
from script.hassfest import ast_parse_module
|
||||
from script.hassfest.model import Integration
|
||||
|
||||
MANIFEST_KEYS = [
|
||||
@ -49,7 +50,7 @@ def validate(integration: Integration) -> list[str] | None:
|
||||
return None
|
||||
|
||||
# Fallback => check config_flow step
|
||||
config_flow = ast.parse(config_flow_file.read_text())
|
||||
config_flow = ast_parse_module(config_flow_file)
|
||||
if not (_has_discovery_function(config_flow)):
|
||||
return [
|
||||
f"Integration is missing one of {CONFIG_FLOW_STEPS} "
|
||||
|
@ -5,6 +5,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/r
|
||||
|
||||
import ast
|
||||
|
||||
from script.hassfest import ast_parse_module
|
||||
from script.hassfest.model import Integration
|
||||
|
||||
|
||||
@ -20,7 +21,7 @@ def validate(integration: Integration) -> list[str] | None:
|
||||
"""Validate that the integration has a reauthentication flow."""
|
||||
|
||||
config_flow_file = integration.path / "config_flow.py"
|
||||
config_flow = ast.parse(config_flow_file.read_text())
|
||||
config_flow = ast_parse_module(config_flow_file)
|
||||
|
||||
if not _has_step_reauth_function(config_flow):
|
||||
return [
|
||||
|
@ -5,6 +5,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/r
|
||||
|
||||
import ast
|
||||
|
||||
from script.hassfest import ast_parse_module
|
||||
from script.hassfest.model import Integration
|
||||
|
||||
|
||||
@ -20,7 +21,7 @@ def validate(integration: Integration) -> list[str] | None:
|
||||
"""Validate that the integration has a reconfiguration flow."""
|
||||
|
||||
config_flow_file = integration.path / "config_flow.py"
|
||||
config_flow = ast.parse(config_flow_file.read_text())
|
||||
config_flow = ast_parse_module(config_flow_file)
|
||||
|
||||
if not _has_step_reconfigure_function(config_flow):
|
||||
return [
|
||||
|
@ -5,6 +5,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/r
|
||||
|
||||
import ast
|
||||
|
||||
from script.hassfest import ast_parse_module
|
||||
from script.hassfest.model import Integration
|
||||
|
||||
|
||||
@ -35,7 +36,7 @@ def _get_setup_entry_function(module: ast.Module) -> ast.AsyncFunctionDef | None
|
||||
def validate(integration: Integration) -> list[str] | None:
|
||||
"""Validate correct use of ConfigEntry.runtime_data."""
|
||||
init_file = integration.path / "__init__.py"
|
||||
init = ast.parse(init_file.read_text())
|
||||
init = ast_parse_module(init_file)
|
||||
|
||||
# Should not happen, but better to be safe
|
||||
if not (async_setup_entry := _get_setup_entry_function(init)):
|
||||
|
@ -5,6 +5,7 @@ https://developers.home-assistant.io/docs/core/integration-quality-scale/rules/u
|
||||
|
||||
import ast
|
||||
|
||||
from script.hassfest import ast_parse_module
|
||||
from script.hassfest.model import Integration
|
||||
|
||||
|
||||
@ -36,7 +37,7 @@ def validate(integration: Integration) -> list[str] | None:
|
||||
return None
|
||||
|
||||
config_flow_file = integration.path / "config_flow.py"
|
||||
config_flow = ast.parse(config_flow_file.read_text())
|
||||
config_flow = ast_parse_module(config_flow_file)
|
||||
|
||||
if not (
|
||||
_has_abort_entries_match(config_flow)
|
||||
|
Loading…
x
Reference in New Issue
Block a user