Prioritize integration_domain passed to helper.frame.report_usage (#139819)
* Prioritize integration_domain passed to helper.frame.report_usage * Update tests * Update tests * Improve docstring * Rename according to suggestionpull/139923/head
parent
dc4464a347
commit
c51e644203
|
@ -180,8 +180,8 @@ def report_usage(
|
|||
breaking version
|
||||
:param exclude_integrations: skip specified integration when reviewing the stack.
|
||||
If no integration is found, the core behavior will be applied
|
||||
:param integration_domain: fallback for identifying the integration if the
|
||||
frame is not found
|
||||
:param integration_domain: domain of the integration causing the issue. If None, the
|
||||
stack frame will be searched to identify the integration causing the issue.
|
||||
"""
|
||||
if (hass := _hass.hass) is None:
|
||||
raise RuntimeError("Frame helper not set up")
|
||||
|
@ -220,13 +220,9 @@ def _report_usage(
|
|||
|
||||
Must be called from the event loop.
|
||||
"""
|
||||
try:
|
||||
integration_frame = get_integration_frame(
|
||||
exclude_integrations=exclude_integrations
|
||||
)
|
||||
except MissingIntegrationFrame as err:
|
||||
if integration_domain:
|
||||
if integration := async_get_issue_integration(hass, integration_domain):
|
||||
_report_integration_domain(
|
||||
_report_usage_integration_domain(
|
||||
hass,
|
||||
what,
|
||||
breaks_in_ha_version,
|
||||
|
@ -236,16 +232,15 @@ def _report_usage(
|
|||
level,
|
||||
)
|
||||
return
|
||||
msg = f"Detected code that {what}. Please report this issue"
|
||||
if core_behavior is ReportBehavior.ERROR:
|
||||
raise RuntimeError(msg) from err
|
||||
if core_behavior is ReportBehavior.LOG:
|
||||
if breaks_in_ha_version:
|
||||
msg = (
|
||||
f"Detected code that {what}. This will stop working in Home "
|
||||
f"Assistant {breaks_in_ha_version}, please report this issue"
|
||||
)
|
||||
_LOGGER.warning(msg, stack_info=True)
|
||||
_report_usage_no_integration(what, core_behavior, breaks_in_ha_version, None)
|
||||
return
|
||||
|
||||
try:
|
||||
integration_frame = get_integration_frame(
|
||||
exclude_integrations=exclude_integrations
|
||||
)
|
||||
except MissingIntegrationFrame as err:
|
||||
_report_usage_no_integration(what, core_behavior, breaks_in_ha_version, err)
|
||||
return
|
||||
|
||||
integration_behavior = core_integration_behavior
|
||||
|
@ -253,7 +248,7 @@ def _report_usage(
|
|||
integration_behavior = custom_integration_behavior
|
||||
|
||||
if integration_behavior is not ReportBehavior.IGNORE:
|
||||
_report_integration_frame(
|
||||
_report_usage_integration_frame(
|
||||
hass,
|
||||
what,
|
||||
breaks_in_ha_version,
|
||||
|
@ -263,7 +258,7 @@ def _report_usage(
|
|||
)
|
||||
|
||||
|
||||
def _report_integration_domain(
|
||||
def _report_usage_integration_domain(
|
||||
hass: HomeAssistant | None,
|
||||
what: str,
|
||||
breaks_in_ha_version: str | None,
|
||||
|
@ -313,7 +308,7 @@ def _report_integration_domain(
|
|||
)
|
||||
|
||||
|
||||
def _report_integration_frame(
|
||||
def _report_usage_integration_frame(
|
||||
hass: HomeAssistant,
|
||||
what: str,
|
||||
breaks_in_ha_version: str | None,
|
||||
|
@ -362,6 +357,29 @@ def _report_integration_frame(
|
|||
)
|
||||
|
||||
|
||||
def _report_usage_no_integration(
|
||||
what: str,
|
||||
core_behavior: ReportBehavior,
|
||||
breaks_in_ha_version: str | None,
|
||||
err: MissingIntegrationFrame | None,
|
||||
) -> None:
|
||||
"""Report incorrect usage without an integration.
|
||||
|
||||
This could happen because the offending call happened outside of an integration,
|
||||
or because the integration could not be identified.
|
||||
"""
|
||||
msg = f"Detected code that {what}. Please report this issue"
|
||||
if core_behavior is ReportBehavior.ERROR:
|
||||
raise RuntimeError(msg) from err
|
||||
if core_behavior is ReportBehavior.LOG:
|
||||
if breaks_in_ha_version:
|
||||
msg = (
|
||||
f"Detected code that {what}. This will stop working in Home "
|
||||
f"Assistant {breaks_in_ha_version}, please report this issue"
|
||||
)
|
||||
_LOGGER.warning(msg, stack_info=True)
|
||||
|
||||
|
||||
def warn_use[_CallableT: Callable](func: _CallableT, what: str) -> _CallableT:
|
||||
"""Mock a function to warn when it was about to be used."""
|
||||
if asyncio.iscoroutinefunction(func):
|
||||
|
|
|
@ -292,13 +292,13 @@ async def test_alarm_control_panel_log_deprecated_state_warning_using_state_prop
|
|||
assert state is not None
|
||||
|
||||
assert (
|
||||
"Detected that custom integration 'alarm_control_panel' is setting state"
|
||||
" directly. Entity None (<class 'tests.components.alarm_control_panel."
|
||||
"Detected that custom integration 'test' is setting state "
|
||||
"directly. Entity None (<class 'tests.components.alarm_control_panel."
|
||||
"test_init.test_alarm_control_panel_log_deprecated_state_warning_using"
|
||||
"_state_prop.<locals>.MockLegacyAlarmControlPanel'>) should implement"
|
||||
" the 'alarm_state' property and return its state using the AlarmControlPanelState"
|
||||
" enum at test_init.py, line 123: yield. This will stop working in Home Assistant"
|
||||
" 2025.11, please create a bug report at" in caplog.text
|
||||
" enum. This will stop working in Home Assistant 2025.11, please report it to"
|
||||
" the author of the 'test' custom integration" in caplog.text
|
||||
)
|
||||
|
||||
|
||||
|
@ -345,6 +345,7 @@ async def test_alarm_control_panel_log_deprecated_state_warning_using_attr_state
|
|||
async_setup_entry=help_async_setup_entry_init,
|
||||
async_unload_entry=help_async_unload_entry,
|
||||
),
|
||||
built_in=False,
|
||||
)
|
||||
setup_test_component_platform(
|
||||
hass, ALARM_CONTROL_PANEL_DOMAIN, [entity], from_config_entry=True
|
||||
|
@ -355,7 +356,7 @@ async def test_alarm_control_panel_log_deprecated_state_warning_using_attr_state
|
|||
assert state is not None
|
||||
|
||||
assert (
|
||||
"Detected that custom integration 'alarm_control_panel' is setting state directly."
|
||||
"Detected that custom integration 'test' is setting state directly."
|
||||
not in caplog.text
|
||||
)
|
||||
|
||||
|
@ -364,14 +365,14 @@ async def test_alarm_control_panel_log_deprecated_state_warning_using_attr_state
|
|||
)
|
||||
|
||||
assert (
|
||||
"Detected that custom integration 'alarm_control_panel' is setting state directly."
|
||||
"Detected that custom integration 'test' is setting state directly."
|
||||
" Entity alarm_control_panel.test_alarm_control_panel"
|
||||
" (<class 'tests.components.alarm_control_panel.test_init."
|
||||
"test_alarm_control_panel_log_deprecated_state_warning_using_attr_state_attr."
|
||||
"<locals>.MockLegacyAlarmControlPanel'>) should implement the 'alarm_state' property"
|
||||
" and return its state using the AlarmControlPanelState enum at test_init.py, line 123:"
|
||||
" yield. This will stop working in Home Assistant 2025.11,"
|
||||
" please create a bug report at" in caplog.text
|
||||
" and return its state using the AlarmControlPanelState enum. "
|
||||
"This will stop working in Home Assistant 2025.11, please report "
|
||||
"it to the author of the 'test' custom integration" in caplog.text
|
||||
)
|
||||
caplog.clear()
|
||||
await help_test_async_alarm_control_panel_service(
|
||||
|
@ -379,7 +380,7 @@ async def test_alarm_control_panel_log_deprecated_state_warning_using_attr_state
|
|||
)
|
||||
# Test we only log once
|
||||
assert (
|
||||
"Detected that custom integration 'alarm_control_panel' is setting state directly."
|
||||
"Detected that custom integration 'test' is setting state directly."
|
||||
not in caplog.text
|
||||
)
|
||||
|
||||
|
@ -428,6 +429,7 @@ async def test_alarm_control_panel_deprecated_state_does_not_break_state(
|
|||
async_setup_entry=help_async_setup_entry_init,
|
||||
async_unload_entry=help_async_unload_entry,
|
||||
),
|
||||
built_in=False,
|
||||
)
|
||||
setup_test_component_platform(
|
||||
hass, ALARM_CONTROL_PANEL_DOMAIN, [entity], from_config_entry=True
|
||||
|
|
|
@ -356,6 +356,7 @@ async def test_vacuum_log_deprecated_state_warning_using_state_prop(
|
|||
async_setup_entry=help_async_setup_entry_init,
|
||||
async_unload_entry=help_async_unload_entry,
|
||||
),
|
||||
built_in=False,
|
||||
)
|
||||
setup_test_component_platform(hass, VACUUM_DOMAIN, [entity], from_config_entry=True)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
@ -399,6 +400,7 @@ async def test_vacuum_log_deprecated_state_warning_using_attr_state_attr(
|
|||
async_setup_entry=help_async_setup_entry_init,
|
||||
async_unload_entry=help_async_unload_entry,
|
||||
),
|
||||
built_in=False,
|
||||
)
|
||||
setup_test_component_platform(hass, VACUUM_DOMAIN, [entity], from_config_entry=True)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
@ -463,6 +465,7 @@ async def test_vacuum_deprecated_state_does_not_break_state(
|
|||
async_setup_entry=help_async_setup_entry_init,
|
||||
async_unload_entry=help_async_unload_entry,
|
||||
),
|
||||
built_in=False,
|
||||
)
|
||||
setup_test_component_platform(hass, VACUUM_DOMAIN, [entity], from_config_entry=True)
|
||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
|
|
|
@ -538,21 +538,21 @@ async def test_report_error_if_integration(
|
|||
False,
|
||||
id="custom integration",
|
||||
),
|
||||
# Assert integration found in stack frame has priority over integration_domain
|
||||
# Assert integration_domain has priority over integration found in stack frame
|
||||
pytest.param(
|
||||
"core_integration_behavior",
|
||||
"sensor",
|
||||
"homeassistant/components/hue",
|
||||
"that integration 'hue'",
|
||||
"that integration 'sensor'",
|
||||
False,
|
||||
id="core integration stack mismatch",
|
||||
),
|
||||
# Assert integration found in stack frame has priority over integration_domain
|
||||
# Assert integration_domain has priority over integration found in stack frame
|
||||
pytest.param(
|
||||
"custom_integration_behavior",
|
||||
"test_package",
|
||||
"custom_components/hue",
|
||||
"that custom integration 'hue'",
|
||||
"that custom integration 'test_package'",
|
||||
False,
|
||||
id="custom integration stack mismatch",
|
||||
),
|
||||
|
|
Loading…
Reference in New Issue