diff --git a/homeassistant/helpers/frame.py b/homeassistant/helpers/frame.py index 3416c8d49f6e436c341c5ad7cf36507dfeafc88b..acdadb9578889ef14ce2fb36073b895fdc3acddb 100644 --- a/homeassistant/helpers/frame.py +++ b/homeassistant/helpers/frame.py @@ -150,44 +150,6 @@ class MissingIntegrationFrame(HomeAssistantError): """Raised when no integration is found in the frame.""" -def report( - what: str, - *, - exclude_integrations: set[str] | None = None, - error_if_core: bool = True, - error_if_integration: bool = False, - level: int = logging.WARNING, - log_custom_component_only: bool = False, -) -> None: - """Report incorrect usage. - - If error_if_core is True, raise instead of log if an integration is not found - when unwinding the stack frame. - If error_if_integration is True, raise instead of log if an integration is found - when unwinding the stack frame. - """ - core_behavior = ReportBehavior.ERROR if error_if_core else ReportBehavior.LOG - core_integration_behavior = ( - ReportBehavior.ERROR if error_if_integration else ReportBehavior.LOG - ) - custom_integration_behavior = core_integration_behavior - - if log_custom_component_only: - if core_behavior is ReportBehavior.LOG: - core_behavior = ReportBehavior.IGNORE - if core_integration_behavior is ReportBehavior.LOG: - core_integration_behavior = ReportBehavior.IGNORE - - report_usage( - what, - core_behavior=core_behavior, - core_integration_behavior=core_integration_behavior, - custom_integration_behavior=custom_integration_behavior, - exclude_integrations=exclude_integrations, - level=level, - ) - - class ReportBehavior(enum.Enum): """Enum for behavior on code usage.""" @@ -406,25 +368,26 @@ def warn_use[_CallableT: Callable](func: _CallableT, what: str) -> _CallableT: @functools.wraps(func) async def report_use(*args: Any, **kwargs: Any) -> None: - report(what) + report_usage(what) else: @functools.wraps(func) def report_use(*args: Any, **kwargs: Any) -> None: - report(what) + report_usage(what) return cast(_CallableT, report_use) def report_non_thread_safe_operation(what: str) -> None: """Report a non-thread safe operation.""" - report( + report_usage( f"calls {what} from a thread other than the event loop, " "which may cause Home Assistant to crash or data to corrupt. " "For more information, see " "https://developers.home-assistant.io/docs/asyncio_thread_safety/" f"#{what.replace('.', '')}", - error_if_core=True, - error_if_integration=True, + core_behavior=ReportBehavior.ERROR, + core_integration_behavior=ReportBehavior.ERROR, + custom_integration_behavior=ReportBehavior.ERROR, ) diff --git a/tests/helpers/snapshots/test_frame.ambr b/tests/helpers/snapshots/test_frame.ambr index abdaff6c1b73a53ddf379a01bc53c935e25fe5e5..e74a4b2947ae1be2caff77dd5b7ac86b535c0923 100644 --- a/tests/helpers/snapshots/test_frame.ambr +++ b/tests/helpers/snapshots/test_frame.ambr @@ -1,42 +1,4 @@ # serializer version: 1 -# name: test_report[core default] - list([ - ]) -# --- -# name: test_report[core integration default] - list([ - "Detected that integration 'test_core_integration' test_report_string at homeassistant/components/test_core_integration/light.py, line 23: self.light.is_on. Please create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+test_core_integration%22", - ]) -# --- -# name: test_report[custom integration default] - list([ - "Detected that custom integration 'test_custom_integration' test_report_string at custom_components/test_custom_integration/light.py, line 23: self.light.is_on. Please report it to the author of the 'test_custom_integration' custom integration", - ]) -# --- -# name: test_report[disable error_if_core] - list([ - 'Detected code that test_report_string. Please report this issue', - ]) -# --- -# name: test_report[error_if_integration with core integration] - list([ - "Detected that integration 'test_integration_frame' test_report_string at homeassistant/components/test_integration_frame/light.py, line 23: self.light.is_on. Please create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+test_integration_frame%22", - ]) -# --- -# name: test_report[error_if_integration with custom integration] - list([ - "Detected that custom integration 'test_integration_frame' test_report_string at custom_components/test_integration_frame/light.py, line 23: self.light.is_on. Please report it to the author of the 'test_integration_frame' custom integration", - ]) -# --- -# name: test_report[log_custom_component_only with core integration] - list([ - ]) -# --- -# name: test_report[log_custom_component_only with custom integration] - list([ - "Detected that custom integration 'test_integration_frame' test_report_string at custom_components/test_integration_frame/light.py, line 23: self.light.is_on. Please report it to the author of the 'test_integration_frame' custom integration", - ]) -# --- # name: test_report_usage[core default] list([ ]) diff --git a/tests/helpers/test_frame.py b/tests/helpers/test_frame.py index 9bec7cce996dcdb79c8f66748c12bd81441dfeba..6127761d69b1611877aceb94e96e9b433386e3e3 100644 --- a/tests/helpers/test_frame.py +++ b/tests/helpers/test_frame.py @@ -395,14 +395,14 @@ async def test_prevent_flooding( f"q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+{integration}%22" ) - frame.report(what, error_if_core=False) + frame.report_usage(what, core_behavior=frame.ReportBehavior.LOG) assert expected_message in caplog.text assert key in frame._REPORTED_INTEGRATIONS assert len(frame._REPORTED_INTEGRATIONS) == 1 caplog.clear() - frame.report(what, error_if_core=False) + frame.report_usage(what, core_behavior=frame.ReportBehavior.LOG) assert expected_message not in caplog.text assert key in frame._REPORTED_INTEGRATIONS assert len(frame._REPORTED_INTEGRATIONS) == 1 @@ -442,13 +442,13 @@ async def test_report_missing_integration_frame( "homeassistant.helpers.frame.get_integration_frame", side_effect=frame.MissingIntegrationFrame, ): - frame.report(what, error_if_core=False) + frame.report_usage(what, core_behavior=frame.ReportBehavior.LOG) assert what in caplog.text assert caplog.text.count(what) == 1 caplog.clear() - frame.report(what, error_if_core=False, log_custom_component_only=True) + frame.report_usage(what, core_behavior=frame.ReportBehavior.IGNORE) assert caplog.text == "" @@ -492,94 +492,9 @@ async def test_report_error_if_integration( ), ), ): - frame.report("did a bad thing", error_if_integration=True) - - -@pytest.mark.parametrize( - ("integration_frame_path", "keywords", "expected_result", "expected_log"), - [ - pytest.param( - "homeassistant/test_core", - {}, - pytest.raises(RuntimeError, match="test_report_string"), - 0, - id="core default", - ), - pytest.param( - "homeassistant/components/test_core_integration", - {}, - does_not_raise(), - 1, - id="core integration default", - ), - pytest.param( - "custom_components/test_custom_integration", - {}, - does_not_raise(), - 1, - id="custom integration default", - ), - pytest.param( - "custom_components/test_integration_frame", - {"log_custom_component_only": True}, - does_not_raise(), - 1, - id="log_custom_component_only with custom integration", - ), - pytest.param( - "homeassistant/components/test_integration_frame", - {"log_custom_component_only": True}, - does_not_raise(), - 0, - id="log_custom_component_only with core integration", - ), - pytest.param( - "homeassistant/test_integration_frame", - {"error_if_core": False}, - does_not_raise(), - 1, - id="disable error_if_core", - ), - pytest.param( - "custom_components/test_integration_frame", - {"error_if_integration": True}, - pytest.raises(RuntimeError, match="test_report_string"), - 1, - id="error_if_integration with custom integration", - ), - pytest.param( - "homeassistant/components/test_integration_frame", - {"error_if_integration": True}, - pytest.raises(RuntimeError, match="test_report_string"), - 1, - id="error_if_integration with core integration", - ), - ], -) -@pytest.mark.usefixtures("hass", "mock_integration_frame") -async def test_report( - caplog: pytest.LogCaptureFixture, - snapshot: SnapshotAssertion, - keywords: dict[str, Any], - expected_result: AbstractContextManager, - expected_log: int, -) -> None: - """Test report. - - Note: This test doesn't set up mock integrations, so it will not - find the correct issue tracker URL, and we don't check for that. - """ - - what = "test_report_string" - - with patch.object(frame, "_REPORTED_INTEGRATIONS", set()), expected_result: - frame.report(what, **keywords) - - assert caplog.text.count(what) == expected_log - reports = [ - rec.message for rec in caplog.records if rec.message.startswith("Detected") - ] - assert reports == snapshot + frame.report_usage( + "did a bad thing", core_integration_behavior=frame.ReportBehavior.ERROR + ) @pytest.mark.parametrize(