partial resolve, tests
This commit is contained in:
parent
f1e2984702
commit
465c949f5b
2 changed files with 62 additions and 46 deletions
|
|
@ -181,7 +181,7 @@ class Script:
|
||||||
self._ensure_custom_function_usage_num_input_arguments_valid()
|
self._ensure_custom_function_usage_num_input_arguments_valid()
|
||||||
|
|
||||||
def resolve(
|
def resolve(
|
||||||
self, pre_resolved_variables: Optional[Dict[Variable, Resolvable]] = None
|
self, pre_resolved_variables: Optional[Dict[str, Resolvable]] = None
|
||||||
) -> Dict[str, Resolvable]:
|
) -> Dict[str, Resolvable]:
|
||||||
"""
|
"""
|
||||||
Parameters
|
Parameters
|
||||||
|
|
@ -197,10 +197,10 @@ class Script:
|
||||||
Variable(name): ast for name, ast in self._variables.items()
|
Variable(name): ast for name, ast in self._variables.items()
|
||||||
}
|
}
|
||||||
|
|
||||||
unresolved_variables: Set[Variable] = set(variables.keys())
|
resolved_variables: Dict[Variable, Resolvable] = {
|
||||||
resolved_variables: Dict[Variable, Resolvable] = (
|
Variable(name): value for name, value in (pre_resolved_variables or {}).items()
|
||||||
pre_resolved_variables if pre_resolved_variables else {}
|
}
|
||||||
)
|
unresolved_variables: Set[Variable] = set(variables.keys()) - set(resolved_variables.keys())
|
||||||
|
|
||||||
while unresolved_variables:
|
while unresolved_variables:
|
||||||
unresolved_count: int = len(unresolved_variables)
|
unresolved_count: int = len(unresolved_variables)
|
||||||
|
|
@ -221,3 +221,45 @@ class Script:
|
||||||
raise UNREACHABLE
|
raise UNREACHABLE
|
||||||
|
|
||||||
return {variable.name: resolvable for variable, resolvable in resolved_variables.items()}
|
return {variable.name: resolvable for variable, resolvable in resolved_variables.items()}
|
||||||
|
|
||||||
|
def partial_resolve(self, unresolvable: Set[str]) -> Dict[str, Resolvable]:
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
unresolvable
|
||||||
|
Variables that cannot be resolved
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
Dict of resolved values
|
||||||
|
"""
|
||||||
|
variables: Dict[Variable, SyntaxTree] = {
|
||||||
|
Variable(name): ast for name, ast in self._variables.items()
|
||||||
|
}
|
||||||
|
|
||||||
|
unresolvable_variables: Set[Variable] = set(Variable(var) for var in unresolvable)
|
||||||
|
unresolved_variables: Set[Variable] = set(variables.keys()) - unresolvable_variables
|
||||||
|
resolved_variables: Dict[Variable, Resolvable] = {}
|
||||||
|
|
||||||
|
while unresolved_variables:
|
||||||
|
unresolved_count: int = len(unresolved_variables)
|
||||||
|
|
||||||
|
for variable in copy.deepcopy(unresolved_variables):
|
||||||
|
if variables[variable].variables.intersection(unresolvable_variables):
|
||||||
|
unresolvable_variables.add(variable)
|
||||||
|
unresolved_variables.remove(variable)
|
||||||
|
elif not variables[variable].has_variable_dependency(
|
||||||
|
resolved_variables=resolved_variables
|
||||||
|
):
|
||||||
|
resolved_variables[variable] = variables[variable].resolve(
|
||||||
|
resolved_variables=resolved_variables,
|
||||||
|
custom_functions=self._functions,
|
||||||
|
)
|
||||||
|
unresolved_variables.remove(variable)
|
||||||
|
|
||||||
|
if len(unresolved_variables) == unresolved_count:
|
||||||
|
# Implies a cycle within the variables. Should never reach
|
||||||
|
# since cycles are detected in __init__
|
||||||
|
raise UNREACHABLE
|
||||||
|
|
||||||
|
return {variable.name: resolvable for variable, resolvable in resolved_variables.items()}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,9 @@
|
||||||
import re
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
from ytdl_sub.script.script import Script
|
from ytdl_sub.script.script import Script
|
||||||
from ytdl_sub.script.types.resolvable import String
|
from ytdl_sub.script.types.resolvable import String
|
||||||
from ytdl_sub.script.utils.exceptions import CycleDetected
|
|
||||||
|
|
||||||
|
|
||||||
class TestSyntaxTree:
|
class TestScript:
|
||||||
def test_custom_function(self):
|
def test_pre_resolved(self):
|
||||||
assert Script(
|
assert Script(
|
||||||
{
|
{
|
||||||
"%custom_func": "return {[$0, $1]}",
|
"%custom_func": "return {[$0, $1]}",
|
||||||
|
|
@ -16,39 +11,18 @@ class TestSyntaxTree:
|
||||||
"bb": "b",
|
"bb": "b",
|
||||||
"cc": "{%custom_func(aa, bb)}",
|
"cc": "{%custom_func(aa, bb)}",
|
||||||
}
|
}
|
||||||
).resolve() == {"aa": String("a"), "bb": String("b"), "cc": String('return ["a", "b"]')}
|
).resolve(pre_resolved_variables={"bb": String("bb_override")}) == {
|
||||||
|
"aa": String("a"),
|
||||||
def test_simple(self):
|
"bb": String("bb_override"),
|
||||||
assert Script({"a": "a", "b": "{b_}", "b_": "b"}).resolve() == {
|
"cc": String('return ["a", "bb_override"]'),
|
||||||
"a": String("a"),
|
|
||||||
"b": String("b"),
|
|
||||||
"b_": String("b"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def test_multiple_variables(self):
|
def test_partial_resolve(self):
|
||||||
assert Script({"a": "a", "b": "b", "b_": " {a} {b} "}).resolve() == {
|
assert Script(
|
||||||
"a": String("a"),
|
{
|
||||||
"b": String("b"),
|
"%custom_func": "return {[$0, $1]}",
|
||||||
"b_": String(" a b "),
|
"aa": "a",
|
||||||
|
"bb": "b",
|
||||||
|
"cc": "{%custom_func(aa, bb)}",
|
||||||
}
|
}
|
||||||
|
).partial_resolve(unresolvable={"bb"}) == {"aa": String("a")}
|
||||||
def test_simple_with_function(self):
|
|
||||||
assert Script({"a": "a", "b": "{%capitalize(b_)}", "b_": "b"}).resolve() == {
|
|
||||||
"a": String("a"),
|
|
||||||
"b": String("B"),
|
|
||||||
"b_": String("b"),
|
|
||||||
}
|
|
||||||
|
|
||||||
def test_simple_cycle(self):
|
|
||||||
with pytest.raises(
|
|
||||||
CycleDetected,
|
|
||||||
match=re.escape("Cycle detected within these variables: " "a -> b -> a"),
|
|
||||||
):
|
|
||||||
Script({"a": "{b}", "b": "{a}"}).resolve()
|
|
||||||
|
|
||||||
def test_simple_cycle_with_function(self):
|
|
||||||
with pytest.raises(
|
|
||||||
CycleDetected,
|
|
||||||
match=re.escape("Cycle detected within these variables: " "b -> b_ -> b"),
|
|
||||||
):
|
|
||||||
Script({"b": "{%capitalize(b_)}", "b_": "{b}"}).resolve()
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue