Skip to content
Merged
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
14 changes: 1 addition & 13 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -1024,18 +1024,6 @@ class MyCoordinator(DataUpdateCoordinator[MyData]):
)
```

### Entity Performance Optimization
```python
# Use __slots__ for memory efficiency
class MySensor(SensorEntity):
__slots__ = ("_attr_native_value", "_attr_available")

@property
def should_poll(self) -> bool:
"""Disable polling when using coordinator."""
return False # ✅ Let coordinator handle updates
```

## Testing Patterns

### Testing Best Practices
Expand Down Expand Up @@ -1181,4 +1169,4 @@ python -m script.hassfest --integration-path homeassistant/components/my_integra
pytest ./tests/components/my_integration \
--cov=homeassistant.components.my_integration \
--cov-report term-missing
```
```
2 changes: 1 addition & 1 deletion homeassistant/components/mobile_app/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"iot_class": "local_push",
"loggers": ["nacl"],
"quality_scale": "internal",
"requirements": ["PyNaCl==1.6.0"]
"requirements": ["PyNaCl==1.6.2"]
}
2 changes: 1 addition & 1 deletion homeassistant/components/owntracks/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
"integration_type": "service",
"iot_class": "local_push",
"loggers": ["nacl"],
"requirements": ["PyNaCl==1.6.0"],
"requirements": ["PyNaCl==1.6.2"],
"single_config_entry": true
}
2 changes: 1 addition & 1 deletion homeassistant/package_constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ propcache==0.4.1
psutil-home-assistant==0.0.1
PyJWT==2.10.1
pymicro-vad==1.0.1
PyNaCl==1.6.0
PyNaCl==1.6.2
pyOpenSSL==25.3.0
pyserial==3.5
pyspeex-noise==1.0.2
Expand Down
2 changes: 1 addition & 1 deletion requirements_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion requirements_test_all.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions tests/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import itertools
from typing import Any, TypedDict

import pytest

from homeassistant.const import (
ATTR_AREA_ID,
ATTR_DEVICE_ID,
Expand Down Expand Up @@ -634,3 +636,37 @@ def other_states(state: StrEnum | Iterable[StrEnum]) -> list[str]:
enum_class = list(state)[0].__class__

return sorted({s.value for s in enum_class} - excluded_values)


async def assert_condition_gated_by_labs_flag(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, condition: str
) -> None:
"""Helper to check that a condition is gated by the labs flag."""

# Local include to avoid importing the automation component unnecessarily
from homeassistant.components import automation # noqa: PLC0415

await async_setup_component(
hass,
automation.DOMAIN,
{
automation.DOMAIN: {
"trigger": {"platform": "event", "event_type": "test_event"},
"condition": {
CONF_CONDITION: condition,
CONF_TARGET: {ATTR_LABEL_ID: "test_label"},
CONF_OPTIONS: {"behavior": "any"},
},
"action": {
"service": "test.automation",
},
}
},
)

assert (
"Unnamed automation failed to setup conditions and has been disabled: "
f"Condition '{condition}' requires the experimental 'New triggers and "
"conditions' feature to be enabled in Home Assistant Labs settings "
"(feature flag: 'new_triggers_conditions')"
) in caplog.text
18 changes: 3 additions & 15 deletions tests/components/alarm_control_panel/test_trigger.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""Test alarm control panel triggers."""

from collections.abc import Generator
from typing import Any
from unittest.mock import patch

import pytest

Expand All @@ -29,16 +27,6 @@ def stub_blueprint_populate_autouse(stub_blueprint_populate: None) -> None:
"""Stub copying the blueprints to the config folder."""


@pytest.fixture(name="enable_experimental_triggers_conditions")
def enable_experimental_triggers_conditions() -> Generator[None]:
"""Enable experimental triggers and conditions."""
with patch(
"homeassistant.components.labs.async_is_preview_feature_enabled",
return_value=True,
):
yield


@pytest.fixture
async def target_alarm_control_panels(hass: HomeAssistant) -> list[str]:
"""Create multiple alarm control panel entities associated with different targets."""
Expand Down Expand Up @@ -70,7 +58,7 @@ async def test_alarm_control_panel_triggers_gated_by_labs_flag(
) in caplog.text


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("alarm_control_panel"),
Expand Down Expand Up @@ -181,7 +169,7 @@ async def test_alarm_control_panel_state_trigger_behavior_any(
service_calls.clear()


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("alarm_control_panel"),
Expand Down Expand Up @@ -291,7 +279,7 @@ async def test_alarm_control_panel_state_trigger_behavior_first(
assert len(service_calls) == 0


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("alarm_control_panel"),
Expand Down
18 changes: 3 additions & 15 deletions tests/components/assist_satellite/test_trigger.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""Test assist satellite triggers."""

from collections.abc import Generator
from typing import Any
from unittest.mock import patch

import pytest

Expand All @@ -26,16 +24,6 @@ def stub_blueprint_populate_autouse(stub_blueprint_populate: None) -> None:
"""Stub copying the blueprints to the config folder."""


@pytest.fixture(name="enable_experimental_triggers_conditions")
def enable_experimental_triggers_conditions() -> Generator[None]:
"""Enable experimental triggers and conditions."""
with patch(
"homeassistant.components.labs.async_is_preview_feature_enabled",
return_value=True,
):
yield


@pytest.fixture
async def target_assist_satellites(hass: HomeAssistant) -> list[str]:
"""Create multiple assist satellite entities associated with different targets."""
Expand Down Expand Up @@ -64,7 +52,7 @@ async def test_assist_satellite_triggers_gated_by_labs_flag(
) in caplog.text


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("assist_satellite"),
Expand Down Expand Up @@ -132,7 +120,7 @@ async def test_assist_satellite_state_trigger_behavior_any(
service_calls.clear()


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("assist_satellite"),
Expand Down Expand Up @@ -199,7 +187,7 @@ async def test_assist_satellite_state_trigger_behavior_first(
assert len(service_calls) == 0


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("assist_satellite"),
Expand Down
18 changes: 3 additions & 15 deletions tests/components/binary_sensor/test_trigger.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
"""Test binary sensor trigger."""

from collections.abc import Generator
from typing import Any
from unittest.mock import patch

import pytest

Expand Down Expand Up @@ -30,16 +28,6 @@ def stub_blueprint_populate_autouse(stub_blueprint_populate: None) -> None:
"""Stub copying the blueprints to the config folder."""


@pytest.fixture(name="enable_experimental_triggers_conditions")
def enable_experimental_triggers_conditions() -> Generator[None]:
"""Enable experimental triggers and conditions."""
with patch(
"homeassistant.components.labs.async_is_preview_feature_enabled",
return_value=True,
):
yield


@pytest.fixture
async def target_binary_sensors(hass: HomeAssistant) -> tuple[list[str], list[str]]:
"""Create multiple binary sensor entities associated with different targets."""
Expand All @@ -66,7 +54,7 @@ async def test_binary_sensor_triggers_gated_by_labs_flag(
) in caplog.text


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("binary_sensor"),
Expand Down Expand Up @@ -136,7 +124,7 @@ async def test_binary_sensor_state_attribute_trigger_behavior_any(
service_calls.clear()


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("binary_sensor"),
Expand Down Expand Up @@ -205,7 +193,7 @@ async def test_binary_sensor_state_attribute_trigger_behavior_first(
assert len(service_calls) == 0


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("binary_sensor"),
Expand Down
15 changes: 1 addition & 14 deletions tests/components/button/test_trigger.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
"""Test button trigger."""

from collections.abc import Generator
from unittest.mock import patch

import pytest

from homeassistant.const import (
Expand All @@ -27,16 +24,6 @@ def stub_blueprint_populate_autouse(stub_blueprint_populate: None) -> None:
"""Stub copying the blueprints to the config folder."""


@pytest.fixture(name="enable_experimental_triggers_conditions")
def enable_experimental_triggers_conditions() -> Generator[None]:
"""Enable experimental triggers and conditions."""
with patch(
"homeassistant.components.labs.async_is_preview_feature_enabled",
return_value=True,
):
yield


@pytest.fixture
async def target_buttons(hass: HomeAssistant) -> list[str]:
"""Create multiple button entities associated with different targets."""
Expand All @@ -57,7 +44,7 @@ async def test_button_triggers_gated_by_labs_flag(
) in caplog.text


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("button"),
Expand Down
26 changes: 7 additions & 19 deletions tests/components/climate/test_trigger.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
"""Test climate trigger."""

from collections.abc import Generator
from contextlib import AbstractContextManager, nullcontext as does_not_raise
from typing import Any
from unittest.mock import patch

import pytest
import voluptuous as vol
Expand Down Expand Up @@ -45,16 +43,6 @@ def stub_blueprint_populate_autouse(stub_blueprint_populate: None) -> None:
"""Stub copying the blueprints to the config folder."""


@pytest.fixture(name="enable_experimental_triggers_conditions")
def enable_experimental_triggers_conditions() -> Generator[None]:
"""Enable experimental triggers and conditions."""
with patch(
"homeassistant.components.labs.async_is_preview_feature_enabled",
return_value=True,
):
yield


@pytest.fixture
async def target_climates(hass: HomeAssistant) -> list[str]:
"""Create multiple climate entities associated with different targets."""
Expand Down Expand Up @@ -91,7 +79,7 @@ async def test_climate_triggers_gated_by_labs_flag(
) in caplog.text


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger", "trigger_options", "expected_result"),
[
Expand Down Expand Up @@ -147,7 +135,7 @@ async def test_climate_trigger_validation(
)


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("climate"),
Expand Down Expand Up @@ -220,7 +208,7 @@ async def test_climate_state_trigger_behavior_any(
service_calls.clear()


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("climate"),
Expand Down Expand Up @@ -315,7 +303,7 @@ async def test_climate_state_attribute_trigger_behavior_any(
service_calls.clear()


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("climate"),
Expand Down Expand Up @@ -389,7 +377,7 @@ async def test_climate_state_trigger_behavior_first(
assert len(service_calls) == 0


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("climate"),
Expand Down Expand Up @@ -471,7 +459,7 @@ async def test_climate_state_attribute_trigger_behavior_first(
assert len(service_calls) == 0


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("climate"),
Expand Down Expand Up @@ -544,7 +532,7 @@ async def test_climate_state_trigger_behavior_last(
service_calls.clear()


@pytest.mark.usefixtures("enable_experimental_triggers_conditions")
@pytest.mark.usefixtures("enable_labs_preview_features")
@pytest.mark.parametrize(
("trigger_target_config", "entity_id", "entities_in_target"),
parametrize_target_entities("climate"),
Expand Down
Loading
Loading