make lambda resolvable
This commit is contained in:
parent
35d29ec373
commit
31d8c0a52f
3 changed files with 22 additions and 11 deletions
|
|
@ -28,7 +28,7 @@ from ytdl_sub.script.types.variable import FunctionArgument
|
||||||
from ytdl_sub.script.types.variable import Variable
|
from ytdl_sub.script.types.variable import Variable
|
||||||
from ytdl_sub.script.types.variable_dependency import VariableDependency
|
from ytdl_sub.script.types.variable_dependency import VariableDependency
|
||||||
from ytdl_sub.script.utils.exception_formatters import FunctionArgumentsExceptionFormatter
|
from ytdl_sub.script.utils.exception_formatters import FunctionArgumentsExceptionFormatter
|
||||||
from ytdl_sub.script.utils.exceptions import FunctionDoesNotExist
|
from ytdl_sub.script.utils.exceptions import FunctionDoesNotExist, UNREACHABLE
|
||||||
from ytdl_sub.script.utils.exceptions import FunctionRuntimeException
|
from ytdl_sub.script.utils.exceptions import FunctionRuntimeException
|
||||||
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
|
from ytdl_sub.script.utils.exceptions import UserThrownRuntimeError
|
||||||
from ytdl_sub.script.utils.type_checking import FunctionInputSpec
|
from ytdl_sub.script.utils.type_checking import FunctionInputSpec
|
||||||
|
|
@ -144,10 +144,8 @@ class BuiltInFunction(Function, TypeHintedFunctionType):
|
||||||
)
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def lambda_argument(self) -> Optional[Lambda]:
|
def is_lambda_function(self) -> bool:
|
||||||
if Lambda in (self.input_spec.args or []):
|
return Lambda in (self.input_spec.args or [])
|
||||||
return [lam for lam in self.args if isinstance(lam, Lambda)][0]
|
|
||||||
return None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _arg_output_type(cls, arg: ArgumentType) -> Type[ArgumentType]:
|
def _arg_output_type(cls, arg: ArgumentType) -> Type[ArgumentType]:
|
||||||
|
|
@ -184,8 +182,11 @@ class BuiltInFunction(Function, TypeHintedFunctionType):
|
||||||
2. Preemptively creating the lambda's unresolved output array using output args from (1)
|
2. Preemptively creating the lambda's unresolved output array using output args from (1)
|
||||||
3. Resolve it like any other syntax
|
3. Resolve it like any other syntax
|
||||||
"""
|
"""
|
||||||
assert self.lambda_argument is not None
|
function_input_lambda_args = [arg for arg in resolved_arguments if isinstance(arg, Lambda)]
|
||||||
lambda_function_name = self.lambda_argument.function_name
|
if not self.is_lambda_function or len(function_input_lambda_args) != 1:
|
||||||
|
raise UNREACHABLE
|
||||||
|
|
||||||
|
lambda_function_name = function_input_lambda_args[0].function_name
|
||||||
|
|
||||||
try:
|
try:
|
||||||
lambda_args = self.callable(*resolved_arguments)
|
lambda_args = self.callable(*resolved_arguments)
|
||||||
|
|
@ -222,13 +223,12 @@ class BuiltInFunction(Function, TypeHintedFunctionType):
|
||||||
custom_functions=custom_functions,
|
custom_functions=custom_functions,
|
||||||
)
|
)
|
||||||
for arg in self.args
|
for arg in self.args
|
||||||
if not isinstance(arg, Lambda)
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# If a lambda is in a function's arg, resolve it differently
|
# If a lambda is in a function's arg, resolve it differently
|
||||||
if lambda_argument := self.lambda_argument:
|
if self.is_lambda_function:
|
||||||
return self._resolve_lambda_function(
|
return self._resolve_lambda_function(
|
||||||
resolved_arguments=resolved_arguments + [lambda_argument],
|
resolved_arguments=resolved_arguments,
|
||||||
resolved_variables=resolved_variables,
|
resolved_variables=resolved_variables,
|
||||||
custom_functions=custom_functions,
|
custom_functions=custom_functions,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -135,5 +135,5 @@ class TypeHintedFunctionType(FunctionType, ABC):
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class Lambda(ArgumentType):
|
class Lambda(Resolvable):
|
||||||
function_name: str
|
function_name: str
|
||||||
|
|
|
||||||
|
|
@ -121,3 +121,14 @@ class TestFunction:
|
||||||
assert Script(
|
assert Script(
|
||||||
{"%times_two": "{%mul($0, 2)}", "wip": "{%array_apply([1, 2, 3], %times_two)}"}
|
{"%times_two": "{%mul($0, 2)}", "wip": "{%array_apply([1, 2, 3], %times_two)}"}
|
||||||
).resolve() == {"wip": ResolvedArray([Integer(2), Integer(4), Integer(6)])}
|
).resolve() == {"wip": ResolvedArray([Integer(2), Integer(4), Integer(6)])}
|
||||||
|
|
||||||
|
def test_conditional_lambda_function(self):
|
||||||
|
assert Script(
|
||||||
|
{
|
||||||
|
"%times_three": "{%mul($0, 3)}",
|
||||||
|
"%times_two": "{%mul($0, 2)}",
|
||||||
|
"wip": "{%array_apply([1, 2, 3], %if(False, %times_two, %times_three))}"
|
||||||
|
}
|
||||||
|
).resolve() == {
|
||||||
|
"wip": ResolvedArray([Integer(3), Integer(6), Integer(9)])
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue