Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove deprecated hass.components #125477

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion homeassistant/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ def __init__(self, config_dir: str) -> None:
self.states = StateMachine(self.bus, self.loop)
self.config = Config(self, config_dir)
self.config.async_initialize()
self.components = loader.Components(self)
self.helpers = loader.Helpers(self)
self.state: CoreState = CoreState.not_running
self.exit_code: int = 0
Expand Down
39 changes: 0 additions & 39 deletions homeassistant/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -1530,45 +1530,6 @@ def __getattr__(self, attr: str) -> Any:
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
from .helpers.frame import report # pylint: disable=import-outside-toplevel

report(
(
f"accesses hass.components.{comp_name}."
" This is deprecated and will stop working in Home Assistant 2024.9, it"
f" should be updated to import functions used from {comp_name} directly"
),
error_if_core=False,
log_custom_component_only=True,
)

wrapped = ModuleWrapper(self._hass, component)
setattr(self, comp_name, wrapped)
return wrapped


class Helpers:
"""Helper to load helpers."""

Expand Down
31 changes: 0 additions & 31 deletions script/hassfest/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,37 +74,6 @@ def visit_Import(self, node: ast.Import) -> None:
if name_node.name.startswith("homeassistant.components."):
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 = {
*{platform.value for platform in Platform},
Expand Down
36 changes: 0 additions & 36 deletions tests/hassfest/test_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,33 +68,6 @@ def test_renamed_absolute(mock_collector) -> None:
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:
"""Test all imports together."""
mock_collector.visit(
Expand All @@ -108,13 +81,6 @@ def test_all_imports(mock_collector) -> None:
from homeassistant.components.child_import_field import bla

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()
"""
)
)
Expand All @@ -123,6 +89,4 @@ def something(self):
"subimport",
"child_import_field",
"renamed_absolute",
"hass_components_var",
"hass_components_class",
}
64 changes: 2 additions & 62 deletions tests/test_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
import pytest

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.core import HomeAssistant, callback
from homeassistant.helpers import frame
from homeassistant.helpers.json import json_dumps
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:
Expand Down Expand Up @@ -64,29 +64,6 @@ async def test_nonexistent_component_dependencies(hass: HomeAssistant) -> None:
await loader._async_component_dependencies(hass, mod_1)


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:
"""Test helpers wrapper."""
helpers = loader.Helpers(hass)
Expand Down Expand Up @@ -118,10 +95,6 @@ async def test_custom_component_name(hass: HomeAssistant) -> None:
assert int_comp.__name__ == "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")
platform = integration.get_platform("light")
assert integration.get_platform_cached("light") is platform
Expand Down Expand Up @@ -1269,39 +1242,6 @@ async def test_config_folder_not_in_path() -> None:
import tests.testing_config.check_config_not_in_path # noqa: F401


async def test_hass_components_use_reported(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, mock_integration_frame: Mock
) -> None:
"""Test that use of hass.components is reported."""
mock_integration_frame.filename = (
"/home/paulus/homeassistant/custom_components/demo/light.py"
)
integration_frame = frame.IntegrationFrame(
custom_integration=True,
frame=mock_integration_frame,
integration="test_integration_frame",
module="custom_components.test_integration_frame",
relative_filename="custom_components/test_integration_frame/__init__.py",
)

with (
patch(
"homeassistant.helpers.frame.get_integration_frame",
return_value=integration_frame,
),
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)

assert (
"Detected that custom integration 'test_integration_frame'"
" accesses hass.components.http. This is deprecated"
) in caplog.text


async def test_async_get_component_preloads_config_and_config_flow(
hass: HomeAssistant,
) -> None:
Expand Down
Loading