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 GitHub
parent 9447d954d6
commit abc05451a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 79 additions and 1 deletions

View File

@ -23,6 +23,7 @@ except ImportError:
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.frame import report
from .const import SECRET_YAML
from .objects import Input, NodeDictClass, NodeListClass, NodeStrClass
@ -136,6 +137,18 @@ class FastSafeLoader(FastestAvailableSafeLoader, _LoaderMixin):
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):
"""Python safe loader."""
@ -145,6 +158,18 @@ class PythonSafeLoader(yaml.SafeLoader, _LoaderMixin):
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

View File

@ -1,11 +1,12 @@
"""Test Home Assistant yaml loader."""
from collections.abc import Generator
import importlib
import io
import os
import pathlib
from typing import Any
import unittest
from unittest.mock import patch
from unittest.mock import Mock, patch
import pytest
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)
@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:
"""Test strings are annotated with file + line."""
conf = (