Skip to content

Commit

Permalink
Don't use deprecated_class decorator on deprecated YAML classes (home…
Browse files Browse the repository at this point in the history
  • Loading branch information
emontnemery authored Dec 5, 2023
1 parent ae002e2 commit 5b59e04
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 13 deletions.
60 changes: 56 additions & 4 deletions homeassistant/util/yaml/loader.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Custom loader."""
from __future__ import annotations

from collections.abc import Iterator
from collections.abc import Callable, Iterator
from contextlib import suppress
import fnmatch
from io import StringIO, TextIOWrapper
Expand All @@ -23,7 +23,7 @@
)

from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.deprecation import deprecated_class
from homeassistant.helpers.frame import report

from .const import SECRET_YAML
from .objects import Input, NodeDictClass, NodeListClass, NodeStrClass
Expand Down Expand Up @@ -137,10 +137,36 @@ def __init__(self, stream: Any, secrets: Secrets | None = None) -> None:
self.secrets = secrets


@deprecated_class("FastSafeLoader")
class SafeLoader(FastSafeLoader):
"""Provided for backwards compatibility. Logs when instantiated."""

def __init__(*args: Any, **kwargs: Any) -> None:
"""Log a warning and call super."""
SafeLoader.__report_deprecated()
FastSafeLoader.__init__(*args, **kwargs)

@classmethod
def add_constructor(cls, tag: str, constructor: Callable) -> None:
"""Log a warning and call super."""
SafeLoader.__report_deprecated()
FastSafeLoader.add_constructor(tag, constructor)

@classmethod
def add_multi_constructor(
cls, tag_prefix: str, multi_constructor: Callable
) -> None:
"""Log a warning and call super."""
SafeLoader.__report_deprecated()
FastSafeLoader.add_multi_constructor(tag_prefix, multi_constructor)

@staticmethod
def __report_deprecated() -> None:
"""Log deprecation warning."""
report(
"uses deprecated 'SafeLoader' instead of 'FastSafeLoader', "
"which will stop working in HA Core 2024.6,"
)


class PythonSafeLoader(yaml.SafeLoader, _LoaderMixin):
"""Python safe loader."""
Expand All @@ -151,10 +177,36 @@ def __init__(self, stream: Any, secrets: Secrets | None = None) -> None:
self.secrets = secrets


@deprecated_class("PythonSafeLoader")
class SafeLineLoader(PythonSafeLoader):
"""Provided for backwards compatibility. Logs when instantiated."""

def __init__(*args: Any, **kwargs: Any) -> None:
"""Log a warning and call super."""
SafeLineLoader.__report_deprecated()
PythonSafeLoader.__init__(*args, **kwargs)

@classmethod
def add_constructor(cls, tag: str, constructor: Callable) -> None:
"""Log a warning and call super."""
SafeLineLoader.__report_deprecated()
PythonSafeLoader.add_constructor(tag, constructor)

@classmethod
def add_multi_constructor(
cls, tag_prefix: str, multi_constructor: Callable
) -> None:
"""Log a warning and call super."""
SafeLineLoader.__report_deprecated()
PythonSafeLoader.add_multi_constructor(tag_prefix, multi_constructor)

@staticmethod
def __report_deprecated() -> None:
"""Log deprecation warning."""
report(
"uses deprecated 'SafeLineLoader' instead of 'PythonSafeLoader', "
"which will stop working in HA Core 2024.6,"
)


LoaderType = FastSafeLoader | PythonSafeLoader

Expand Down
15 changes: 6 additions & 9 deletions tests/util/yaml/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ async def test_loading_actual_file_with_syntax_error(
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/custom_components/hue/light.py",
filename="/home/paulus/homeassistant/components/hue/light.py",
lineno="23",
line="self.light.is_on",
)
Expand All @@ -614,12 +614,12 @@ def mock_integration_frame() -> Generator[Mock, None, None]:


@pytest.mark.parametrize(
("loader_class", "new_class"),
("loader_class", "message"),
[
(yaml.loader.SafeLoader, "FastSafeLoader"),
(yaml.loader.SafeLoader, "'SafeLoader' instead of 'FastSafeLoader'"),
(
yaml.loader.SafeLineLoader,
"PythonSafeLoader",
"'SafeLineLoader' instead of 'PythonSafeLoader'",
),
],
)
Expand All @@ -628,17 +628,14 @@ async def test_deprecated_loaders(
mock_integration_frame: Mock,
caplog: pytest.LogCaptureFixture,
loader_class,
new_class: str,
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"{loader_class.__name__} was instantiated from hue, this is a deprecated "
f"class. Use {new_class} instead"
) in caplog.text
assert (f"Detected that integration 'hue' uses deprecated {message}") in caplog.text


def test_string_annotated(try_both_loaders) -> None:
Expand Down

0 comments on commit 5b59e04

Please sign in to comment.