function resolving

This commit is contained in:
Jesse Bannon 2023-11-07 00:02:35 -08:00
parent 2bf4f01b8d
commit 870b3ee018
3 changed files with 38 additions and 3 deletions

View file

@ -73,6 +73,8 @@ class SyntaxTree(VariableDependency):
unresolved_variables.remove(variable)
if len(unresolved_variables) == unresolved_count:
raise StringFormattingException("did not resolve any variables, cycle detected")
raise StringFormattingException(
f"Cycle detected within these variables: {', '.join(sorted([var.name for var in unresolved_variables]))}"
)
return {variable.name: resolvable for variable, resolvable in resolved_variables.items()}

View file

@ -15,7 +15,6 @@ from typing import final
from typing import get_origin
from ytdl_sub.script.functions import Functions
from ytdl_sub.script.functions.special_functions import SpecialFunctions
from ytdl_sub.script.types.resolvable import Boolean
from ytdl_sub.script.types.resolvable import Float
from ytdl_sub.script.types.resolvable import Integer
@ -227,4 +226,13 @@ class Function(VariableDependency):
return variables
def resolve(self, resolved_variables: Dict[Variable, Resolvable]) -> Resolvable:
raise NotImplemented()
resolved_args: List[Resolvable] = []
for arg in self.args:
if arg in resolved_variables:
resolved_args.append(resolved_variables[arg])
elif isinstance(arg, Function):
resolved_args.append(arg.resolve(resolved_variables))
else:
resolved_args.append(arg)
return self.callable(*resolved_args)

View file

@ -3,6 +3,7 @@ from typing import Dict
import pytest
from ytdl_sub.script.syntax_tree import SyntaxTree
from ytdl_sub.script.types.function import Function
from ytdl_sub.script.types.resolvable import String
from ytdl_sub.script.types.variable import Variable
from ytdl_sub.utils.exceptions import StringFormattingException
@ -23,6 +24,20 @@ class TestSyntaxTree:
"b_": String(value="b"),
}
def test_simple_with_function(self):
overrides: Dict[str, SyntaxTree] = {
"a": SyntaxTree(ast=[String("a")]),
"b": SyntaxTree(ast=[Function(name="capitalize", args=[Variable("b_")])]),
"b_": SyntaxTree(ast=[String("b")]),
}
resolved = SyntaxTree.resolve_overrides(parsed_overrides=overrides)
assert resolved == {
"a": String(value="a"),
"b": String(value="B"),
"b_": String(value="b"),
}
def test_simple_cycle(self):
overrides: Dict[str, SyntaxTree] = {
"a": SyntaxTree(ast=[Variable("b")]),
@ -31,3 +46,13 @@ class TestSyntaxTree:
with pytest.raises(StringFormattingException):
_ = SyntaxTree.resolve_overrides(parsed_overrides=overrides)
def test_simple_cycle_with_function(self):
overrides: Dict[str, SyntaxTree] = {
"a": SyntaxTree(ast=[String("a")]),
"b": SyntaxTree(ast=[Function(name="capitalize", args=[Variable("b_")])]),
"b_": SyntaxTree(ast=[Variable("b")]),
}
_ = SyntaxTree.resolve_overrides(parsed_overrides=overrides)
with pytest.raises(StringFormattingException):
_ = SyntaxTree.resolve_overrides(parsed_overrides=overrides)