diff --git a/src/ytdl_sub/config/validators/variable_validation.py b/src/ytdl_sub/config/validators/variable_validation.py index 82069d7c..35079c7f 100644 --- a/src/ytdl_sub/config/validators/variable_validation.py +++ b/src/ytdl_sub/config/validators/variable_validation.py @@ -7,6 +7,7 @@ from ytdl_sub.config.plugin.preset_plugins import PresetPlugins from ytdl_sub.config.preset_options import OutputOptions from ytdl_sub.config.validators.options import OptionsValidator from ytdl_sub.downloaders.url.validators import MultiUrlValidator +from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.validators.string_formatter_validators import validate_formatters @@ -26,18 +27,21 @@ class VariableValidation: self.script = self.overrides.script self.unresolved_variables = self.plugins.get_all_variables( additional_options=[self.output_options, self.downloader_options] + ) | {VARIABLES.entry_metadata.variable_name} + self.unresolved_runtime_variables = self.plugins.get_all_variables( + additional_options=[self.output_options, self.downloader_options] ) - def _add_variables(self, plugin_op: PluginOperation, options: OptionsValidator) -> None: + def _add_runtime_variables(self, plugin_op: PluginOperation, options: OptionsValidator) -> None: """ Add dummy variables for script validation """ added_variables = options.added_variables( - unresolved_variables=self.unresolved_variables, + unresolved_variables=self.unresolved_runtime_variables, ).get(plugin_op, set()) modified_variables = options.modified_variables().get(plugin_op, set()) - self.unresolved_variables -= added_variables | modified_variables + self.unresolved_runtime_variables -= added_variables | modified_variables def ensure_proper_usage(self) -> Dict: """ @@ -47,32 +51,38 @@ class VariableValidation: resolved_subscription: Dict = {} - self._add_variables(PluginOperation.DOWNLOADER, options=self.downloader_options) + self._add_runtime_variables(PluginOperation.DOWNLOADER, options=self.downloader_options) # Always add output options first - self._add_variables(PluginOperation.MODIFY_ENTRY_METADATA, options=self.output_options) + self._add_runtime_variables( + PluginOperation.MODIFY_ENTRY_METADATA, options=self.output_options + ) # Metadata variables to be added for plugin_options in PluginMapping.order_options_by( self.plugins.zipped(), PluginOperation.MODIFY_ENTRY_METADATA ): - self._add_variables(PluginOperation.MODIFY_ENTRY_METADATA, options=plugin_options) + self._add_runtime_variables( + PluginOperation.MODIFY_ENTRY_METADATA, options=plugin_options + ) for plugin_options in PluginMapping.order_options_by( self.plugins.zipped(), PluginOperation.MODIFY_ENTRY ): - self._add_variables(PluginOperation.MODIFY_ENTRY, options=plugin_options) + self._add_runtime_variables(PluginOperation.MODIFY_ENTRY, options=plugin_options) # Validate that any formatter in the plugin options can resolve resolved_subscription |= validate_formatters( script=self.script, unresolved_variables=self.unresolved_variables, + unresolved_runtime_variables=self.unresolved_runtime_variables, validator=plugin_options, ) resolved_subscription |= validate_formatters( script=self.script, unresolved_variables=self.unresolved_variables, + unresolved_runtime_variables=self.unresolved_runtime_variables, validator=self.output_options, ) @@ -80,6 +90,7 @@ class VariableValidation: raw_download_output = validate_formatters( script=self.script, unresolved_variables=self.unresolved_variables, + unresolved_runtime_variables=self.unresolved_runtime_variables, validator=self.downloader_options.urls, ) resolved_subscription["download"] = [] @@ -90,5 +101,5 @@ class VariableValidation: if url_output["url"]: resolved_subscription["download"].append(url_output) - assert not self.unresolved_variables + assert not self.unresolved_runtime_variables return resolved_subscription diff --git a/src/ytdl_sub/validators/string_formatter_validators.py b/src/ytdl_sub/validators/string_formatter_validators.py index 21715c03..0e9fea48 100644 --- a/src/ytdl_sub/validators/string_formatter_validators.py +++ b/src/ytdl_sub/validators/string_formatter_validators.py @@ -5,7 +5,6 @@ from typing import Set from typing import Union from typing import final -from ytdl_sub.entries.script.variable_definitions import VARIABLES from ytdl_sub.script.parser import parse from ytdl_sub.script.script import Script from ytdl_sub.script.types.syntax_tree import SyntaxTree @@ -238,6 +237,7 @@ def to_variable_dependency_format_string(script: Script, parsed_format_string: S def _validate_formatter( mock_script: Script, unresolved_variables: Set[str], + unresolved_runtime_variables: Set[str], formatter_validator: Union[StringFormatterValidator, OverridesStringFormatterValidator], ) -> str: parsed = formatter_validator.parsed @@ -245,8 +245,6 @@ def _validate_formatter( return resolved.native is_static_formatter = isinstance(formatter_validator, OverridesStringFormatterValidator) - if is_static_formatter: - unresolved_variables = unresolved_variables.union({VARIABLES.entry_metadata.variable_name}) variable_names = {var.name for var in parsed.variables} custom_function_names = {f"%{func.name}" for func in parsed.custom_functions} @@ -266,7 +264,7 @@ def _validate_formatter( "contains the following custom functions that do not exist: " f"{', '.join(sorted(custom_function_names - mock_script.function_names))}" ) - if unresolved := variable_names.intersection(unresolved_variables): + if unresolved := variable_names.intersection(unresolved_runtime_variables): raise StringFormattingVariableNotFoundException( "contains the following variables that are unresolved when executing this " f"formatter: {', '.join(sorted(unresolved))}" @@ -298,6 +296,7 @@ def _validate_formatter( def validate_formatters( script: Script, unresolved_variables: Set[str], + unresolved_runtime_variables: Set[str], validator: Validator, ) -> Dict: """ @@ -314,6 +313,7 @@ def validate_formatters( resolved_dict[validator.leaf_name] |= validate_formatters( script=script, unresolved_variables=unresolved_variables, + unresolved_runtime_variables=unresolved_runtime_variables, validator=validator_value, ) elif isinstance(validator, ListValidator): @@ -322,6 +322,7 @@ def validate_formatters( list_output = validate_formatters( script=script, unresolved_variables=unresolved_variables, + unresolved_runtime_variables=unresolved_runtime_variables, validator=list_value, ) assert len(list_output) == 1 @@ -330,6 +331,7 @@ def validate_formatters( resolved_dict[validator.leaf_name] = _validate_formatter( mock_script=script, unresolved_variables=unresolved_variables, + unresolved_runtime_variables=unresolved_runtime_variables, formatter_validator=validator, ) elif isinstance(validator, (DictFormatterValidator, OverridesDictFormatterValidator)): @@ -338,6 +340,7 @@ def validate_formatters( resolved_dict[validator.leaf_name] |= _validate_formatter( mock_script=script, unresolved_variables=unresolved_variables, + unresolved_runtime_variables=unresolved_runtime_variables, formatter_validator=validator_value, ) else: