Remove deprecated hass.components (#141947)

This commit is contained in:
Jan-Philipp Benecke 2025-04-23 14:04:36 +02:00 committed by GitHub
parent 3cb301214f
commit f22eca3d9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 2 additions and 172 deletions

View File

@ -443,7 +443,6 @@ class HomeAssistant:
self.states = StateMachine(self.bus, self.loop) self.states = StateMachine(self.bus, self.loop)
self.config = Config(self, config_dir) self.config = Config(self, config_dir)
self.config.async_initialize() self.config.async_initialize()
self.components = loader.Components(self)
self.helpers = loader.Helpers(self) self.helpers = loader.Helpers(self)
self.state: CoreState = CoreState.not_running self.state: CoreState = CoreState.not_running
self.exit_code: int = 0 self.exit_code: int = 0

View File

@ -1710,45 +1710,6 @@ class ModuleWrapper:
return value return value
class Components:
"""Helper to load components."""
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize the Components class."""
self._hass = hass
def __getattr__(self, comp_name: str) -> ModuleWrapper:
"""Fetch a component."""
# Test integration cache
integration = self._hass.data[DATA_INTEGRATIONS].get(comp_name)
if isinstance(integration, Integration):
component: ComponentProtocol | None = integration.get_component()
else:
# Fallback to importing old-school
component = _load_file(self._hass, comp_name, _lookup_path(self._hass))
if component is None:
raise ImportError(f"Unable to load {comp_name}")
# Local import to avoid circular dependencies
# pylint: disable-next=import-outside-toplevel
from .helpers.frame import ReportBehavior, report_usage
report_usage(
f"accesses hass.components.{comp_name}, which"
f" should be updated to import functions used from {comp_name} directly",
core_behavior=ReportBehavior.IGNORE,
core_integration_behavior=ReportBehavior.IGNORE,
custom_integration_behavior=ReportBehavior.LOG,
breaks_in_ha_version="2025.3",
)
wrapped = ModuleWrapper(self._hass, component)
setattr(self, comp_name, wrapped)
return wrapped
class Helpers: class Helpers:
"""Helper to load helpers.""" """Helper to load helpers."""

View File

@ -84,37 +84,6 @@ class ImportCollector(ast.NodeVisitor):
if name_node.name.startswith("homeassistant.components."): if name_node.name.startswith("homeassistant.components."):
self._add_reference(name_node.name.split(".")[2]) self._add_reference(name_node.name.split(".")[2])
def visit_Attribute(self, node: ast.Attribute) -> None:
"""Visit Attribute node."""
# hass.components.hue.async_create()
# Name(id=hass)
# .Attribute(attr=hue)
# .Attribute(attr=async_create)
# self.hass.components.hue.async_create()
# Name(id=self)
# .Attribute(attr=hass) or .Attribute(attr=_hass)
# .Attribute(attr=hue)
# .Attribute(attr=async_create)
if (
isinstance(node.value, ast.Attribute)
and node.value.attr == "components"
and (
(
isinstance(node.value.value, ast.Name)
and node.value.value.id == "hass"
)
or (
isinstance(node.value.value, ast.Attribute)
and node.value.value.attr in ("hass", "_hass")
)
)
):
self._add_reference(node.attr)
else:
# Have it visit other kids
self.generic_visit(node)
ALLOWED_USED_COMPONENTS = { ALLOWED_USED_COMPONENTS = {
*{platform.value for platform in Platform}, *{platform.value for platform in Platform},

View File

@ -68,33 +68,6 @@ import homeassistant.components.renamed_absolute as hue
assert mock_collector.unfiltered_referenced == {"renamed_absolute"} assert mock_collector.unfiltered_referenced == {"renamed_absolute"}
def test_hass_components_var(mock_collector) -> None:
"""Test detecting a hass_components_var reference."""
mock_collector.visit(
ast.parse(
"""
def bla(hass):
hass.components.hass_components_var.async_do_something()
"""
)
)
assert mock_collector.unfiltered_referenced == {"hass_components_var"}
def test_hass_components_class(mock_collector) -> None:
"""Test detecting a hass_components_class reference."""
mock_collector.visit(
ast.parse(
"""
class Hello:
def something(self):
self.hass.components.hass_components_class.async_yo()
"""
)
)
assert mock_collector.unfiltered_referenced == {"hass_components_class"}
def test_all_imports(mock_collector) -> None: def test_all_imports(mock_collector) -> None:
"""Test all imports together.""" """Test all imports together."""
mock_collector.visit( mock_collector.visit(
@ -108,13 +81,6 @@ from homeassistant.components.subimport.smart_home import EVENT_ALEXA_SMART_HOME
from homeassistant.components.child_import_field import bla from homeassistant.components.child_import_field import bla
import homeassistant.components.renamed_absolute as hue import homeassistant.components.renamed_absolute as hue
def bla(hass):
hass.components.hass_components_var.async_do_something()
class Hello:
def something(self):
self.hass.components.hass_components_class.async_yo()
""" """
) )
) )
@ -123,6 +89,4 @@ class Hello:
"subimport", "subimport",
"child_import_field", "child_import_field",
"renamed_absolute", "renamed_absolute",
"hass_components_var",
"hass_components_class",
} }

View File

@ -12,13 +12,13 @@ from awesomeversion import AwesomeVersion
import pytest import pytest
from homeassistant import loader from homeassistant import loader
from homeassistant.components import http, hue from homeassistant.components import hue
from homeassistant.components.hue import light as hue_light from homeassistant.components.hue import light as hue_light
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.json import json_dumps from homeassistant.helpers.json import json_dumps
from homeassistant.util.json import json_loads from homeassistant.util.json import json_loads
from .common import MockModule, async_get_persistent_notifications, mock_integration from .common import MockModule, mock_integration
async def test_circular_component_dependencies(hass: HomeAssistant) -> None: async def test_circular_component_dependencies(hass: HomeAssistant) -> None:
@ -114,29 +114,6 @@ async def test_nonexistent_component_dependencies(hass: HomeAssistant) -> None:
assert result == {} assert result == {}
def test_component_loader(hass: HomeAssistant) -> None:
"""Test loading components."""
components = loader.Components(hass)
assert components.http.CONFIG_SCHEMA is http.CONFIG_SCHEMA
assert hass.components.http.CONFIG_SCHEMA is http.CONFIG_SCHEMA
def test_component_loader_non_existing(hass: HomeAssistant) -> None:
"""Test loading components."""
components = loader.Components(hass)
with pytest.raises(ImportError):
_ = components.non_existing
async def test_component_wrapper(hass: HomeAssistant) -> None:
"""Test component wrapper."""
components = loader.Components(hass)
components.persistent_notification.async_create("message")
notifications = async_get_persistent_notifications(hass)
assert len(notifications)
async def test_helpers_wrapper(hass: HomeAssistant) -> None: async def test_helpers_wrapper(hass: HomeAssistant) -> None:
"""Test helpers wrapper.""" """Test helpers wrapper."""
helpers = loader.Helpers(hass) helpers = loader.Helpers(hass)
@ -168,10 +145,6 @@ async def test_custom_component_name(hass: HomeAssistant) -> None:
assert int_comp.__name__ == "custom_components.test_package" assert int_comp.__name__ == "custom_components.test_package"
assert int_comp.__package__ == "custom_components.test_package" assert int_comp.__package__ == "custom_components.test_package"
comp = hass.components.test_package
assert comp.__name__ == "custom_components.test_package"
assert comp.__package__ == "custom_components.test_package"
integration = await loader.async_get_integration(hass, "test") integration = await loader.async_get_integration(hass, "test")
platform = integration.get_platform("light") platform = integration.get_platform("light")
assert integration.get_platform_cached("light") is platform assert integration.get_platform_cached("light") is platform
@ -1349,42 +1322,6 @@ async def test_config_folder_not_in_path() -> None:
import tests.testing_config.check_config_not_in_path # noqa: F401 import tests.testing_config.check_config_not_in_path # noqa: F401
@pytest.mark.parametrize(
("integration_frame_path", "expected"),
[
pytest.param(
"custom_components/test_integration_frame", True, id="custom integration"
),
pytest.param(
"homeassistant/components/test_integration_frame",
False,
id="core integration",
),
pytest.param("homeassistant/test_integration_frame", False, id="core"),
],
)
@pytest.mark.usefixtures("mock_integration_frame")
async def test_hass_components_use_reported(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
expected: bool,
) -> None:
"""Test whether use of hass.components is reported."""
with (
patch(
"homeassistant.components.http.start_http_server_and_save_config",
return_value=None,
),
):
await hass.components.http.start_http_server_and_save_config(hass, [], None)
reported = (
"Detected that custom integration 'test_integration_frame'"
" accesses hass.components.http, which should be updated"
) in caplog.text
assert reported == expected
async def test_async_get_component_preloads_config_and_config_flow( async def test_async_get_component_preloads_config_and_config_flow(
hass: HomeAssistant, hass: HomeAssistant,
) -> None: ) -> None: