fixed lint, tests

This commit is contained in:
Jesse Bannon 2025-12-30 15:36:46 -08:00
parent 25c4b4b14c
commit 7b45d8d4fe
5 changed files with 69 additions and 17 deletions

View file

@ -31,8 +31,8 @@ from ytdl_sub.script.utils.exceptions import InvalidSyntaxException
from ytdl_sub.script.utils.exceptions import InvalidVariableName
from ytdl_sub.script.utils.exceptions import UserException
from ytdl_sub.script.utils.exceptions import VariableDoesNotExist
from ytdl_sub.script.utils.name_validation import function_name
from ytdl_sub.script.utils.name_validation import is_function
from ytdl_sub.script.utils.name_validation import to_function_name
from ytdl_sub.script.utils.name_validation import validate_variable_name
# pylint: disable=invalid-name
@ -147,7 +147,7 @@ class _Parser:
self._text = text
self._name = name
if name and is_function(name):
self._name = function_name(name)
self._name = to_function_name(name)
self._custom_function_names = custom_function_names
self._variable_names = variable_names

View file

@ -20,9 +20,9 @@ from ytdl_sub.script.utils.exceptions import IncompatibleFunctionArguments
from ytdl_sub.script.utils.exceptions import InvalidCustomFunctionArguments
from ytdl_sub.script.utils.exceptions import RuntimeException
from ytdl_sub.script.utils.exceptions import ScriptVariableNotResolved
from ytdl_sub.script.utils.name_validation import function_name
from ytdl_sub.script.utils.name_validation import is_function
from ytdl_sub.script.utils.name_validation import to_function_definition_name
from ytdl_sub.script.utils.name_validation import to_function_name
from ytdl_sub.script.utils.name_validation import validate_variable_name
from ytdl_sub.script.utils.type_checking import FunctionSpec
@ -226,7 +226,7 @@ class Script:
def __init__(self, script: Dict[str, str]):
function_names: Set[str] = {
function_name(name) for name in script.keys() if is_function(name)
to_function_name(name) for name in script.keys() if is_function(name)
}
variable_names: Set[str] = {
validate_variable_name(name) for name in script.keys() if not is_function(name)
@ -235,9 +235,9 @@ class Script:
self._functions: Dict[str, SyntaxTree] = {
# custom_function_name must be passed to properly type custom function
# arguments uniquely if they're nested (i.e. $0 to $custom_func___0)
function_name(function_key): parse(
to_function_name(function_key): parse(
text=function_value,
name=function_name(function_key),
name=to_function_name(function_key),
custom_function_names=function_names,
variable_names=variable_names,
)
@ -470,7 +470,7 @@ class Script:
added_variables_to_validate: Set[str] = set()
functions_to_add = {
function_name(name): definition
to_function_name(name): definition
for name, definition in variables.items()
if is_function(name)
}
@ -522,7 +522,7 @@ class Script:
added_variables_to_validate: Set[str] = set()
functions_to_add = {
function_name(name): definition
to_function_name(name): definition
for name, definition in variables.items()
if is_function(name)
}

View file

@ -67,7 +67,7 @@ def is_function(override_name: str):
return override_name.startswith("%")
def function_name(function_key: str) -> str:
def to_function_name(function_key: str) -> str:
"""
Drop the % in %custom_function
"""

View file

@ -20,6 +20,8 @@ from ytdl_sub.validators.validators import LiteralDictValidator
from ytdl_sub.validators.validators import StringValidator
from ytdl_sub.validators.validators import Validator
# pylint: disable=protected-access
class StringFormatterValidator(StringValidator):
"""
@ -218,10 +220,8 @@ def to_variable_dependency_format_string(script: Script, parsed_format_string: S
dummy_format_string = ""
for var in parsed_format_string.variables:
dummy_format_string += f"{{ {var.name} }}"
# pylint: disable=protected-access
for variable_dependency in script._variables[var.name].variables:
dummy_format_string += f"{{ {variable_dependency.name} }}"
# pylint: enable=protected-access
return dummy_format_string
@ -293,7 +293,6 @@ def validate_formatters(
if isinstance(validator, DictValidator):
resolved_dict[validator.leaf_name] = {}
# pylint: disable=protected-access
# Usage of protected variables in other validators is fine. The reason to keep
# them protected is for readability when using them in subscriptions.
for validator_value in validator._validator_dict.values():
@ -302,7 +301,6 @@ def validate_formatters(
unresolved_variables=unresolved_variables,
validator=validator_value,
)
# pylint: enable=protected-access
elif isinstance(validator, ListValidator):
resolved_dict[validator.leaf_name] = []
for list_value in validator.list:
@ -328,8 +326,6 @@ def validate_formatters(
formatter_validator=validator_value,
)
else:
# pylint: disable=protected-access
resolved_dict[validator.leaf_name] = validator._value
# pylint: enable=protected-access
return resolved_dict

View file

@ -6,6 +6,7 @@ from typing import Dict
from unittest.mock import patch
import pytest
import yaml
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.plugins.nfo_tags import NfoTagsOptions
@ -540,13 +541,69 @@ def test_music_video_subscriptions(default_config: ConfigFile, music_video_subsc
assert gnr.get("url2").native == "https://www.youtube.com/watch?v=OldpIhHPsbs"
def test_default_docker_config_and_subscriptions(docker_default_subscription_path: Path):
def test_default_docker_config_and_subscriptions(docker_default_subscription_path: Path, output_directory: str):
default_config = ConfigFile.from_file_path("docker/root/defaults/config.yaml")
default_subs = Subscription.from_file_path(
config=default_config, subscription_path=docker_default_subscription_path
)
assert len(default_subs) == 1
resolved_yaml_as_json = yaml.safe_load(default_subs[0].resolved_yaml())
# Since this creates random values, ignore it for this test
assert "throttle_protection" in resolved_yaml_as_json
del resolved_yaml_as_json["throttle_protection"]
assert resolved_yaml_as_json == {
"chapters": {
"allow_chapters_from_comments": False,
"embed_chapters": True,
"enable": "True",
"force_key_frames": False,
},
"date_range": {"breaks": "True", "enable": "True", "type": "upload_date"},
"download": [
{
"download_reverse": "True",
"include_sibling_metadata": False,
"playlist_thumbnails": [
{"name": "{avatar_uncropped_thumbnail_file_name}", "uid": "avatar_uncropped"},
{"name": "{banner_uncropped_thumbnail_file_name}", "uid": "banner_uncropped"},
],
"source_thumbnails": [
{"name": "{avatar_uncropped_thumbnail_file_name}", "uid": "avatar_uncropped"},
{"name": "{banner_uncropped_thumbnail_file_name}", "uid": "banner_uncropped"},
],
"url": "https://www.youtube.com/@novapbs",
"variables": {},
"webpage_url": "{modified_webpage_url}",
"ytdl_options": {},
}
],
"file_convert": {"convert_to": "mp4", "convert_with": "yt-dlp", "enable": "True"},
"format": "(bv*[ext=mp4][vcodec~='^((he|a)vc|h26[45])']+ba[ext=m4a]) / (bv[ext=mp4]*+ba[ext=m4a]/b)",
"output_options": {
"download_archive_name": ".ytdl-sub-NOVA PBS-download-archive.json",
"file_name": "{episode_file_path}.{ext}",
"info_json_name": "{episode_file_path}.{info_json_ext}",
"keep_files_date_eval": "{episode_date_standardized}",
"maintain_download_archive": True,
"output_directory": f"{output_directory}/NOVA PBS",
"preserve_mtime": False,
"thumbnail_name": "{thumbnail_file_name}",
},
"video_tags": {
"contentRating": "{episode_content_rating}",
"date": "{episode_date_standardized}",
"episode_id": "{episode_number}",
"genre": "{tv_show_genre}",
"show": "{tv_show_name}",
"synopsis": "{episode_plot}",
"title": "{episode_title}",
"year": "{episode_year}",
},
}
def test_tv_show_resolved_yaml(config_file: ConfigFile, tv_show_subscriptions_path: Path):
subs = Subscription.from_file_path(
@ -555,4 +612,3 @@ def test_tv_show_resolved_yaml(config_file: ConfigFile, tv_show_subscriptions_pa
assert len(subs) == 8
yaml_out = subs[0].resolved_yaml()
print(yaml_out)