try to simplify script
This commit is contained in:
parent
54a034d4a7
commit
f8a2f03130
3 changed files with 25 additions and 49 deletions
|
|
@ -181,13 +181,18 @@ class Script:
|
|||
self._ensure_custom_function_usage_num_input_arguments_valid()
|
||||
|
||||
def resolve(
|
||||
self, pre_resolved_variables: Optional[Dict[str, Resolvable]] = None
|
||||
self,
|
||||
pre_resolved_variables: Optional[Dict[str, Resolvable]] = None,
|
||||
unresolvable: Optional[Set[str]] = None,
|
||||
) -> Dict[str, Resolvable]:
|
||||
"""
|
||||
Parameters
|
||||
----------
|
||||
pre_resolved_variables
|
||||
Optional variables that have been resolved elsewhere and could be used in this script
|
||||
unresolvable
|
||||
Variables that cannot be resolved, forcing any variable that depends on it to not be
|
||||
resolved.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
|
@ -197,60 +202,26 @@ class Script:
|
|||
Variable(name): ast for name, ast in self._variables.items()
|
||||
}
|
||||
|
||||
unresolvable_variables: Set[Variable] = set(Variable(var) for var in (unresolvable or {}))
|
||||
resolved_variables: Dict[Variable, Resolvable] = {
|
||||
Variable(name): value for name, value in (pre_resolved_variables or {}).items()
|
||||
}
|
||||
unresolved_variables: Set[Variable] = set(variables.keys()) - set(resolved_variables.keys())
|
||||
|
||||
while unresolved_variables:
|
||||
unresolved_count: int = len(unresolved_variables)
|
||||
|
||||
for variable in copy.deepcopy(unresolved_variables):
|
||||
if 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: Set[Variable] = (
|
||||
set(variables.keys()) - set(resolved_variables.keys()) - unresolvable_variables
|
||||
)
|
||||
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()}
|
||||
|
||||
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):
|
||||
# If the variable's variable dependencies contain an unresolvable variable,
|
||||
# declare it as unresolvable and continue
|
||||
if variables[variable].contains(unresolvable_variables):
|
||||
unresolvable_variables.add(variable)
|
||||
unresolved_variables.remove(variable)
|
||||
elif not variables[variable].has_variable_dependency(
|
||||
resolved_variables=resolved_variables
|
||||
):
|
||||
|
||||
# Otherwise, resolve it
|
||||
elif not variables[variable].is_subset_of(variables=resolved_variables.keys()):
|
||||
resolved_variables[variable] = variables[variable].resolve(
|
||||
resolved_variables=resolved_variables,
|
||||
custom_functions=self._functions,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from abc import ABC
|
|||
from abc import abstractmethod
|
||||
from dataclasses import dataclass
|
||||
from typing import Dict
|
||||
from typing import Iterable
|
||||
from typing import List
|
||||
from typing import Set
|
||||
from typing import final
|
||||
|
|
@ -94,10 +95,14 @@ class VariableDependency(ABC):
|
|||
raise UNREACHABLE
|
||||
|
||||
@final
|
||||
def has_variable_dependency(self, resolved_variables: Dict[Variable, Resolvable]) -> bool:
|
||||
def is_subset_of(self, variables: Iterable[Variable]) -> bool:
|
||||
"""
|
||||
Returns
|
||||
-------
|
||||
True if variable dependency. False otherwise.
|
||||
"""
|
||||
return not self.variables.issubset(set(resolved_variables.keys()))
|
||||
return not self.variables.issubset(variables)
|
||||
|
||||
@final
|
||||
def contains(self, variables: Iterable[Variable]) -> bool:
|
||||
return len(self.variables.intersection(variables)) > 0
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ class TestScript:
|
|||
"bb": "b",
|
||||
"cc": "{%custom_func(aa, bb)}",
|
||||
}
|
||||
).partial_resolve(unresolvable={"bb"}) == {"aa": String("a")}
|
||||
).resolve(unresolvable={"bb"}) == {"aa": String("a")}
|
||||
|
||||
def test_partial_update_script(self):
|
||||
script = Script(
|
||||
|
|
@ -37,7 +37,7 @@ class TestScript:
|
|||
}
|
||||
)
|
||||
|
||||
overrides = script.partial_resolve(unresolvable={"entry"})
|
||||
overrides = script.resolve(unresolvable={"entry"})
|
||||
assert overrides == {"override": String("hi")}
|
||||
|
||||
entry_map = ResolvedMap({String("title"): String("the title")})
|
||||
|
|
|
|||
Loading…
Reference in a new issue