From 93cfe59330e9bce7302958574e007c821b9e19ae Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Tue, 6 Jan 2026 13:15:03 -0800 Subject: [PATCH] started, check resolution of episode_file_path --- src/ytdl_sub/script/types/function.py | 4 ++- src/ytdl_sub/utils/script.py | 35 +++++++++++++++++++++++--- tests/unit/config/test_subscription.py | 2 +- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/ytdl_sub/script/types/function.py b/src/ytdl_sub/script/types/function.py index 9e69c01a..1b6e08d6 100644 --- a/src/ytdl_sub/script/types/function.py +++ b/src/ytdl_sub/script/types/function.py @@ -346,7 +346,9 @@ class BuiltInFunction(Function, BuiltInFunctionType): # If the function is conditional, only run if its entirety is resolvable if conditional_return_args: - if self.is_subset_of(variables=resolved_variables, custom_function_definitions=custom_functions): + if self.is_subset_of( + variables=resolved_variables, custom_function_definitions=custom_functions + ): return self.resolve( resolved_variables=resolved_variables, custom_functions=custom_functions, diff --git a/src/ytdl_sub/utils/script.py b/src/ytdl_sub/utils/script.py index 07b5f2e2..e95f69aa 100644 --- a/src/ytdl_sub/utils/script.py +++ b/src/ytdl_sub/utils/script.py @@ -2,6 +2,7 @@ import json import re from typing import Any from typing import Dict +from typing import Optional from ytdl_sub.script.parser import parse from ytdl_sub.script.types.array import UnresolvedArray @@ -155,16 +156,42 @@ class ScriptUtils: raise UNREACHABLE return f"{{ {out} }}" if top_level else out + @classmethod + def _is_top_level_string(cls, tree: SyntaxTree) -> Optional[str]: + if not ( + len(tree.ast) == 1 + and isinstance(tree.ast[0], BuiltInFunction) + and tree.ast[0].name == "concat" + ): + return None + + output = "" + for arg in tree.ast[0].args: + if isinstance(arg, BuiltInFunction) and arg.name == "string" and len(arg.args) == 1: + output += cls._to_script_code(arg.args[0], top_level=True) + else: + output += cls._to_script_code(arg, top_level=True) + + return output + + @classmethod + def _syntax_tree_to_native_script(cls, tree: SyntaxTree) -> str: + + if (output := cls._is_top_level_string(tree)) is not None: + return output + + output = "" + for arg in tree.ast: + output += cls._to_script_code(arg, top_level=True) + return output + @classmethod def to_native_script(cls, value: Any) -> str: """ Converts any JSON-compatible value into equivalent script syntax """ if isinstance(value, SyntaxTree): - output = "" - for arg in value.ast: - output += cls._to_script_code(arg, top_level=True) - return output + return cls._syntax_tree_to_native_script(value) return cls._to_script_code(cls._to_script_argument(value), top_level=True) diff --git a/tests/unit/config/test_subscription.py b/tests/unit/config/test_subscription.py index 127c94b8..35720f71 100644 --- a/tests/unit/config/test_subscription.py +++ b/tests/unit/config/test_subscription.py @@ -617,6 +617,6 @@ def test_default_docker_config_and_subscriptions( unresolvable.add("sibling_metadata") out = default_subs[0].overrides.script.resolve_partial(unresolvable=unresolvable) - prev = ScriptUtils.to_native_script(out._variables['episode_file_name']) + prev = ScriptUtils.to_native_script(out._variables["episode_file_name"]) print("hi")