[BUGFIX] Fix custom function lambda variable dependency issue, part 2 (#1403)

Part two of https://github.com/jmbannon/ytdl-sub/pull/1402 which actually completes the fix.
This commit is contained in:
Jesse Bannon 2025-12-30 23:46:07 -08:00 committed by GitHub
parent d373935fff
commit 7ac525f875
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 31 additions and 13 deletions

View file

@ -288,6 +288,14 @@ class Script:
unresolvable=unresolvable, unresolvable=unresolvable,
) )
for lambda_func in current_var.lambdas:
if lambda_func.value in self._functions:
subset_to_resolve |= self._recursive_get_unresolved_output_filter_variables(
current_var=self._functions[lambda_func.value],
subset_to_resolve=subset_to_resolve,
unresolvable=unresolvable,
)
return subset_to_resolve return subset_to_resolve
def _get_unresolved_output_filter( def _get_unresolved_output_filter(

View file

@ -114,7 +114,6 @@ class VariableDependency(ABC):
output.add(ParsedCustomFunction(name=arg.name, num_input_args=len(arg.args))) output.add(ParsedCustomFunction(name=arg.name, num_input_args=len(arg.args)))
if isinstance(arg, VariableDependency): if isinstance(arg, VariableDependency):
output.update(arg.custom_functions) output.update(arg.custom_functions)
# if isinstance(arg, Lambda)
return output return output
@ -160,6 +159,20 @@ class VariableDependency(ABC):
raise UNREACHABLE raise UNREACHABLE
@final
def _custom_function_dependencies(
self, custom_function_definitions: Dict[str, "VariableDependency"]
) -> Set[ParsedCustomFunction]:
custom_functions = self.custom_functions
for lambda_func in self.lambdas:
if lambda_func.value in custom_function_definitions:
custom_functions.add(
ParsedCustomFunction(
name=lambda_func.value, num_input_args=lambda_func.num_input_args()
)
)
return custom_functions
@final @final
def is_subset_of( def is_subset_of(
self, self,
@ -171,7 +184,8 @@ class VariableDependency(ABC):
------- -------
True if it contains all input variables as a dependency. False otherwise. True if it contains all input variables as a dependency. False otherwise.
""" """
for custom_function in self.custom_functions: # If there are lambdas, see if they are custom functions. If so, check them
for custom_function in self._custom_function_dependencies(custom_function_definitions):
if not custom_function_definitions[custom_function.name].is_subset_of( if not custom_function_definitions[custom_function.name].is_subset_of(
variables=variables, custom_function_definitions=custom_function_definitions variables=variables, custom_function_definitions=custom_function_definitions
): ):
@ -191,16 +205,7 @@ class VariableDependency(ABC):
True if it contains any of the input variables. False otherwise. True if it contains any of the input variables. False otherwise.
""" """
# If there are lambdas, see if they are custom functions. If so, check them # If there are lambdas, see if they are custom functions. If so, check them
custom_functions_to_check = self.custom_functions for custom_function in self._custom_function_dependencies(custom_function_definitions):
for lambda_func in self.lambdas:
if lambda_func.value in custom_function_definitions:
custom_functions_to_check.add(
ParsedCustomFunction(
name=lambda_func.value, num_input_args=lambda_func.num_input_args()
)
)
for custom_function in custom_functions_to_check:
if custom_function_definitions[custom_function.name].contains( if custom_function_definitions[custom_function.name].contains(
variables=variables, custom_function_definitions=custom_function_definitions variables=variables, custom_function_definitions=custom_function_definitions
): ):

View file

@ -241,6 +241,11 @@ def _validate_formatter(
variable_names = {var.name for var in parsed.variables} variable_names = {var.name for var in parsed.variables}
custom_function_names = {f"%{func.name}" for func in parsed.custom_functions} custom_function_names = {f"%{func.name}" for func in parsed.custom_functions}
# Add lambda functions to custom function names, if it's custom
for lambda_func in parsed.lambdas:
if lambda_func in mock_script.function_names:
custom_function_names.add(lambda_func.value)
if not variable_names.issubset(mock_script.variable_names): if not variable_names.issubset(mock_script.variable_names):
raise StringFormattingVariableNotFoundException( raise StringFormattingVariableNotFoundException(
"contains the following variables that do not exist: " "contains the following variables that do not exist: "

View file

@ -81,7 +81,7 @@ class TestLambdaFunction:
Script( Script(
{ {
"the_array": "{ ['a', 'B', 'c', 'D'] }", "the_array": "{ ['a', 'B', 'c', 'D'] }",
"output": "{ %array_apply(the_array, %lower) }", "output": "{ %array_apply(the_array, %custom_cap) }",
"should_lower": "{%bool(True)}", "should_lower": "{%bool(True)}",
"%custom_cap": """{ "%custom_cap": """{
%if( %if(