Minor improvement of frame helper (#101387)
* Minor improvement of frame helper * Add new custom integration for testing * Make IntegrationFrame kw_onlypull/101418/head
parent
c495d607d8
commit
7e39acda37
|
@ -6,6 +6,7 @@ from collections.abc import Callable
|
|||
from dataclasses import dataclass
|
||||
import functools
|
||||
import logging
|
||||
import sys
|
||||
from traceback import FrameSummary, extract_stack
|
||||
from typing import Any, TypeVar, cast
|
||||
|
||||
|
@ -19,14 +20,15 @@ _REPORTED_INTEGRATIONS: set[str] = set()
|
|||
_CallableT = TypeVar("_CallableT", bound=Callable)
|
||||
|
||||
|
||||
@dataclass
|
||||
@dataclass(kw_only=True)
|
||||
class IntegrationFrame:
|
||||
"""Integration frame container."""
|
||||
|
||||
custom_integration: bool
|
||||
filename: str
|
||||
frame: FrameSummary
|
||||
integration: str
|
||||
module: str | None
|
||||
relative_filename: str
|
||||
|
||||
|
||||
def get_integration_frame(exclude_integrations: set | None = None) -> IntegrationFrame:
|
||||
|
@ -55,11 +57,20 @@ def get_integration_frame(exclude_integrations: set | None = None) -> Integratio
|
|||
if found_frame is None:
|
||||
raise MissingIntegrationFrame
|
||||
|
||||
found_module: str | None = None
|
||||
for module, module_obj in dict(sys.modules).items():
|
||||
if not hasattr(module_obj, "__file__"):
|
||||
continue
|
||||
if module_obj.__file__ == found_frame.filename:
|
||||
found_module = module
|
||||
break
|
||||
|
||||
return IntegrationFrame(
|
||||
path == "custom_components/",
|
||||
found_frame.filename[index:],
|
||||
found_frame,
|
||||
integration,
|
||||
custom_integration=path == "custom_components/",
|
||||
frame=found_frame,
|
||||
integration=integration,
|
||||
module=found_module,
|
||||
relative_filename=found_frame.filename[index:],
|
||||
)
|
||||
|
||||
|
||||
|
@ -121,7 +132,7 @@ def _report_integration(
|
|||
what,
|
||||
extra,
|
||||
integration_frame.integration,
|
||||
integration_frame.filename,
|
||||
integration_frame.relative_filename,
|
||||
found_frame.lineno,
|
||||
(found_frame.line or "?").strip(),
|
||||
)
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
"""Test the frame helper."""
|
||||
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import Mock, patch
|
||||
from unittest.mock import ANY, Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import frame
|
||||
|
||||
|
||||
|
@ -41,7 +42,28 @@ async def test_extract_frame_integration(
|
|||
"""Test extracting the current frame from integration context."""
|
||||
integration_frame = frame.get_integration_frame()
|
||||
assert integration_frame == frame.IntegrationFrame(
|
||||
False, "homeassistant/components/hue/light.py", mock_integration_frame, "hue"
|
||||
custom_integration=False,
|
||||
frame=mock_integration_frame,
|
||||
integration="hue",
|
||||
module=None,
|
||||
relative_filename="homeassistant/components/hue/light.py",
|
||||
)
|
||||
|
||||
|
||||
async def test_extract_frame_resolve_module(
|
||||
hass: HomeAssistant, enable_custom_integrations
|
||||
) -> None:
|
||||
"""Test extracting the current frame from integration context."""
|
||||
from custom_components.test_integration_frame import call_get_integration_frame
|
||||
|
||||
integration_frame = call_get_integration_frame()
|
||||
|
||||
assert integration_frame == frame.IntegrationFrame(
|
||||
custom_integration=True,
|
||||
frame=ANY,
|
||||
integration="test_integration_frame",
|
||||
module="custom_components.test_integration_frame",
|
||||
relative_filename="custom_components/test_integration_frame/__init__.py",
|
||||
)
|
||||
|
||||
|
||||
|
@ -80,7 +102,11 @@ async def test_extract_frame_integration_with_excluded_integration(
|
|||
)
|
||||
|
||||
assert integration_frame == frame.IntegrationFrame(
|
||||
False, "homeassistant/components/mdns/light.py", correct_frame, "mdns"
|
||||
custom_integration=False,
|
||||
frame=correct_frame,
|
||||
integration="mdns",
|
||||
module=None,
|
||||
relative_filename="homeassistant/components/mdns/light.py",
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
"""An integration which calls helpers.frame.get_integration_frame."""
|
||||
|
||||
from homeassistant.helpers import frame
|
||||
|
||||
|
||||
def call_get_integration_frame() -> frame.IntegrationFrame:
|
||||
"""Call get_integration_frame."""
|
||||
return frame.get_integration_frame()
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"domain": "test_integration_frame",
|
||||
"name": "Test Integration Frame",
|
||||
"documentation": "http://example.com",
|
||||
"requirements": [],
|
||||
"dependencies": [],
|
||||
"codeowners": [],
|
||||
"version": "1.2.3"
|
||||
}
|
Loading…
Reference in New Issue