From 72eeb4443fff19237b043469285243280da07e99 Mon Sep 17 00:00:00 2001 From: Jesse Bannon Date: Fri, 8 Dec 2023 00:31:09 -0800 Subject: [PATCH] bless yappi --- src/ytdl_sub/config/preset.py | 30 ++++++------------- src/ytdl_sub/config/preset_options.py | 2 +- src/ytdl_sub/downloaders/url/validators.py | 10 +++---- src/ytdl_sub/plugins/regex.py | 2 +- src/ytdl_sub/script/script.py | 17 ++++++----- .../prebuilt_presets/test_prebuilt_presets.py | 3 ++ 6 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/ytdl_sub/config/preset.py b/src/ytdl_sub/config/preset.py index 64ea41ed..8eff310d 100644 --- a/src/ytdl_sub/config/preset.py +++ b/src/ytdl_sub/config/preset.py @@ -180,7 +180,7 @@ class Preset(_PresetShell): return added_variables @functools.cached_property - def _cached_script_builder(self) -> ScriptBuilder: + def _script_builder(self) -> ScriptBuilder: # Set the formatter variables to be the overrides script = ScriptBuilder( Scriptable.add_sanitized_variables(self.overrides.dict_with_format_strings) @@ -194,28 +194,16 @@ class Preset(_PresetShell): _ = script.partial_build() return script - @property - def _script_builder(self) -> ScriptBuilder: - return copy.deepcopy(self._cached_script_builder) - @functools.cached_property - def _script_builder_with_added_variables(self) -> ScriptBuilder: + def _script(self) -> Script: + """ + Contains actualized script which should hold all Override variables + """ return self._script_builder.add( Scriptable.add_sanitized_variables( {source_var: "dummy_string" for source_var in self._added_variables} ) - ) - - @functools.cached_property - def _cached_script(self) -> Script: - """ - Contains actualized script which should hold all Override variables - """ - return self._script_builder_with_added_variables.partial_build() - - @property - def _script(self) -> Script: - return copy.deepcopy(self._cached_script) + ).partial_build() def __validate_and_get_plugins(self) -> PresetPlugins: preset_plugins = PresetPlugins() @@ -232,8 +220,8 @@ class Preset(_PresetShell): return preset_plugins def __validate_added_variables(self): - script_builder = self._script_builder - self.downloader_options.validate_with_variables(script=copy.deepcopy(script_builder)) + script_builder = copy.deepcopy(self._script_builder) + self.downloader_options.validate_with_variables(script=script_builder.partial_build()) script_builder.add( Scriptable.add_sanitized_variables( {name: "dummy_string" for name in self.downloader_options.added_source_variables()} @@ -244,7 +232,7 @@ class Preset(_PresetShell): self.plugins.zipped(), key=lambda pl: pl[0].priority.modify_entry ): # Validate current plugin using source + added plugin variables - plugin_options.validate_with_variables(script=copy.deepcopy(script_builder)) + plugin_options.validate_with_variables(script=script_builder.partial_build()) script_builder.add( Scriptable.add_sanitized_variables( { diff --git a/src/ytdl_sub/config/preset_options.py b/src/ytdl_sub/config/preset_options.py index 33404f00..72fcd5a9 100644 --- a/src/ytdl_sub/config/preset_options.py +++ b/src/ytdl_sub/config/preset_options.py @@ -54,7 +54,7 @@ class OptionsValidator(Validator, ABC): """ return [] - def validate_with_variables(self, script: ScriptBuilder) -> None: + def validate_with_variables(self, script: Script) -> None: """ Optional validation after init with the session's source and override variables. diff --git a/src/ytdl_sub/downloaders/url/validators.py b/src/ytdl_sub/downloaders/url/validators.py index 9d8dde3f..5e431f20 100644 --- a/src/ytdl_sub/downloaders/url/validators.py +++ b/src/ytdl_sub/downloaders/url/validators.py @@ -253,21 +253,19 @@ class MultiUrlValidator(OptionsValidator): """ return list(self._urls.list[0].variables.keys) - def validate_with_variables(self, script: ScriptBuilder) -> None: + def validate_with_variables(self, script: Script) -> None: """ Ensures new variables added are not existing variables """ # Apply formatting to each new source variable, ensure it resolves for collection_url in self.urls.list: - script.add(collection_url.variables.dict_with_format_strings) - - resolved_script = script.partial_build() + for name, definition in collection_url.variables.dict_with_format_strings.items(): + script.is_resolvable(variable_name=name, variable_definition=definition) # Ensure at least URL is non-empty has_non_empty_url = False for url_validator in self.urls.list: - resolved_script.add({"tmp_var_url": url_validator.url.format_string}) - has_non_empty_url |= bool(str(resolved_script.resolve().get_native("tmp_var_url"))) + has_non_empty_url |= bool(str(script.is_resolvable(url_validator.url.format_string))) if not has_non_empty_url: raise self._validation_exception("Must contain at least one url that is non-empty") diff --git a/src/ytdl_sub/plugins/regex.py b/src/ytdl_sub/plugins/regex.py index 014b8487..5b2f2428 100644 --- a/src/ytdl_sub/plugins/regex.py +++ b/src/ytdl_sub/plugins/regex.py @@ -212,7 +212,7 @@ class RegexOptions(OptionsDictValidator): """ return self._skip_if_match_fails - def validate_with_variables(self, script: ScriptBuilder) -> None: + def validate_with_variables(self, script: Script) -> None: for key, regex_options in self.source_variable_capture_dict.items(): # Ensure each variable getting captured is a source variable if key not in script._variables: diff --git a/src/ytdl_sub/script/script.py b/src/ytdl_sub/script/script.py index 57fb3113..e2a9b9d8 100644 --- a/src/ytdl_sub/script/script.py +++ b/src/ytdl_sub/script/script.py @@ -281,14 +281,13 @@ class Script: ) unresolvable: Set[Variable] = {Variable(name) for name in (unresolvable or {})} + unresolved_filter = set(resolved.keys()).union(unresolvable) unresolved: Dict[Variable, SyntaxTree] = { Variable(name): ast for name, ast in self._variables.items() - if Variable(name) not in set(resolved.keys()).union(unresolvable) + if Variable(name) not in unresolved_filter } - tmp = 0 - while unresolved: unresolved_count: int = len(unresolved) @@ -354,17 +353,19 @@ class Script: def is_resolvable( self, variable_definition: str, + variable_name: Optional[str] = None, resolved: Optional[Dict[str, Resolvable]] = None, unresolvable: Optional[Set[str]] = None, ) -> Resolvable: + var_name = variable_name if variable_name else "tmp_var" try: - self.add({"tmp_var": variable_definition}) + self.add({var_name: variable_definition}) return self._resolve( - resolved=resolved, unresolvable=unresolvable, output_filter={"tmp_var"} - ).get("tmp_var") + resolved=resolved, unresolvable=unresolvable, output_filter={var_name} + ).get(var_name) finally: - if "tmp_var" in self._variables: - del self._variables["tmp_var"] + if var_name in self._variables: + del self._variables[var_name] def get(self, variable_name: str) -> Resolvable: if variable_name not in self._variables: diff --git a/tests/unit/prebuilt_presets/test_prebuilt_presets.py b/tests/unit/prebuilt_presets/test_prebuilt_presets.py index 20f5b981..1f0e6d7a 100644 --- a/tests/unit/prebuilt_presets/test_prebuilt_presets.py +++ b/tests/unit/prebuilt_presets/test_prebuilt_presets.py @@ -66,6 +66,8 @@ class TestPrebuiltTVShowPresets: media_player_preset: str, tv_show_structure_preset: str, ): + # yappi.set_clock_type("cpu") # Use set_clock_type("wall") for wall time + # yappi.start() parent_presets = _tv_show_by_date_parent_presets( all_in_one_preset, media_player_preset, tv_show_structure_preset ) @@ -82,6 +84,7 @@ class TestPrebuiltTVShowPresets: }, }, ) + # yappi.get_func_stats().print_all() def test_compilation_many_urls( self,