recursive var names

This commit is contained in:
jbannon 2022-04-06 06:41:29 +00:00
parent 451b3564c5
commit 5fed8a7b64
2 changed files with 68 additions and 1 deletions

View file

@ -8,6 +8,7 @@ from ytdl_subscribe.validators.base.string_formatter_validators import (
from ytdl_subscribe.validators.config.overrides.overrides_validator import (
OverridesValidator,
)
from ytdl_subscribe.validators.exceptions import ValidationException
class TestEntry(object):
@ -68,6 +69,45 @@ class TestEntry(object):
== expected_string
)
def test_entry_formatter_override_recursive(self, mock_entry):
overrides = OverridesValidator(
name="test",
value={
"level_a": "level a",
"level_b": "level b and {level_a}",
"level_c": "level c and {level_b}",
},
)
format_string = StringFormatterValidator(
name="test", value="level d and {level_c}"
)
expected_string = "level d and level c and level b and level a"
assert (
mock_entry.apply_formatter(format_string, overrides=overrides)
== expected_string
)
def test_entry_formatter_override_recursive_fail_cycle(self, mock_entry):
overrides = OverridesValidator(
name="test",
value={
"level_a": "{level_b}",
"level_b": "{level_a}",
},
)
expected_error_msg = (
f"Attempted to format 'test' but failed after reaching max recursion depth of 3. "
f"Try to keep variables dependent on only one other variable."
)
format_string = StringFormatterValidator(name="test", value="{level_a}")
with pytest.raises(ValidationException, match=expected_error_msg):
_ = mock_entry.apply_formatter(format_string, overrides=overrides)
def test_entry_missing_kwarg(self, mock_entry):
key = "dne"
expected_error_msg = f"Expected '{key}' in Entry but does not exist."

View file

@ -1,3 +1,4 @@
from collections import OrderedDict
from pathlib import Path
from typing import Any
from typing import Dict
@ -11,6 +12,7 @@ from ytdl_subscribe.validators.base.string_formatter_validators import (
from ytdl_subscribe.validators.config.overrides.overrides_validator import (
OverridesValidator,
)
from ytdl_subscribe.validators.exceptions import ValidationException
class Entry:
@ -18,6 +20,8 @@ class Entry:
Entry object to represent a single media object returned from yt-dlp.
"""
_MAX_FORMATTER_RECURSION = 3
def __init__(self, **kwargs):
"""
Initialize the entry using ytdl metadata
@ -129,4 +133,27 @@ class Entry:
f"for {self.__class__.__name__}. Available fields: {available_fields}"
)
return formatter.format_string.format(**entry_dict)
format_string = formatter.format_string
variables_present = True
recursion_depth = 0
while variables_present and recursion_depth < self._MAX_FORMATTER_RECURSION:
format_string = format_string.format(**OrderedDict(entry_dict))
variables_present = (
len(
StringFormatterValidator(
name="__recursive_formatter_update__",
value=format_string,
).format_variables
)
> 0
)
recursion_depth += 1
if variables_present:
raise ValidationException(
f"Attempted to format '{formatter._name}' but failed after reaching max recursion "
f"depth of {self._MAX_FORMATTER_RECURSION}. Try to keep variables dependent on "
f"only one other variable."
)
return format_string