Restore renamed yaml loader classes and warn when used (#104818)

This commit is contained in:
Erik Montnemery 2023-11-30 18:14:48 +01:00 committed by Franck Nijhof
parent 7739f99233
commit 45f79ee1ba
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
2 changed files with 79 additions and 1 deletions

View File

@ -23,6 +23,7 @@ except ImportError:
) )
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.frame import report
from .const import SECRET_YAML from .const import SECRET_YAML
from .objects import Input, NodeDictClass, NodeListClass, NodeStrClass from .objects import Input, NodeDictClass, NodeListClass, NodeStrClass
@ -136,6 +137,18 @@ class FastSafeLoader(FastestAvailableSafeLoader, _LoaderMixin):
self.secrets = secrets self.secrets = secrets
class SafeLoader(FastSafeLoader):
"""Provided for backwards compatibility. Logs when instantiated."""
def __init__(*args: Any, **kwargs: Any) -> None:
"""Log a warning and call super."""
report(
"uses deprecated 'SafeLoader' instead of 'FastSafeLoader', "
"which will stop working in HA Core 2024.6,"
)
FastSafeLoader.__init__(*args, **kwargs)
class PythonSafeLoader(yaml.SafeLoader, _LoaderMixin): class PythonSafeLoader(yaml.SafeLoader, _LoaderMixin):
"""Python safe loader.""" """Python safe loader."""
@ -145,6 +158,18 @@ class PythonSafeLoader(yaml.SafeLoader, _LoaderMixin):
self.secrets = secrets self.secrets = secrets
class SafeLineLoader(PythonSafeLoader):
"""Provided for backwards compatibility. Logs when instantiated."""
def __init__(*args: Any, **kwargs: Any) -> None:
"""Log a warning and call super."""
report(
"uses deprecated 'SafeLineLoader' instead of 'PythonSafeLoader', "
"which will stop working in HA Core 2024.6,"
)
PythonSafeLoader.__init__(*args, **kwargs)
LoaderType = FastSafeLoader | PythonSafeLoader LoaderType = FastSafeLoader | PythonSafeLoader

View File

@ -1,11 +1,12 @@
"""Test Home Assistant yaml loader.""" """Test Home Assistant yaml loader."""
from collections.abc import Generator
import importlib import importlib
import io import io
import os import os
import pathlib import pathlib
from typing import Any from typing import Any
import unittest import unittest
from unittest.mock import patch from unittest.mock import Mock, patch
import pytest import pytest
import voluptuous as vol import voluptuous as vol
@ -585,6 +586,58 @@ async def test_loading_actual_file_with_syntax_error(
await hass.async_add_executor_job(load_yaml_config_file, fixture_path) await hass.async_add_executor_job(load_yaml_config_file, fixture_path)
@pytest.fixture
def mock_integration_frame() -> Generator[Mock, None, None]:
"""Mock as if we're calling code from inside an integration."""
correct_frame = Mock(
filename="/home/paulus/homeassistant/components/hue/light.py",
lineno="23",
line="self.light.is_on",
)
with patch(
"homeassistant.helpers.frame.extract_stack",
return_value=[
Mock(
filename="/home/paulus/homeassistant/core.py",
lineno="23",
line="do_something()",
),
correct_frame,
Mock(
filename="/home/paulus/aiohue/lights.py",
lineno="2",
line="something()",
),
],
):
yield correct_frame
@pytest.mark.parametrize(
("loader_class", "message"),
[
(yaml.loader.SafeLoader, "'SafeLoader' instead of 'FastSafeLoader'"),
(
yaml.loader.SafeLineLoader,
"'SafeLineLoader' instead of 'PythonSafeLoader'",
),
],
)
async def test_deprecated_loaders(
hass: HomeAssistant,
mock_integration_frame: Mock,
caplog: pytest.LogCaptureFixture,
loader_class,
message: str,
) -> None:
"""Test instantiating the deprecated yaml loaders logs a warning."""
with pytest.raises(TypeError), patch(
"homeassistant.helpers.frame._REPORTED_INTEGRATIONS", set()
):
loader_class()
assert (f"Detected that integration 'hue' uses deprecated {message}") in caplog.text
def test_string_annotated(try_both_loaders) -> None: def test_string_annotated(try_both_loaders) -> None:
"""Test strings are annotated with file + line.""" """Test strings are annotated with file + line."""
conf = ( conf = (