[REFACTOR] OptionsValidator + OptionsDictValidator (#657)

* [REFACTOR] OptionsValidator + OptionsDictValidator

* more
This commit is contained in:
Jesse Bannon 2023-07-24 10:12:38 -07:00 committed by GitHub
parent 3404ed9cc5
commit 7e997f304d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 39 additions and 35 deletions

View file

@ -13,6 +13,7 @@ from mergedeep import mergedeep
from ytdl_sub.config.config_validator import ConfigValidator from ytdl_sub.config.config_validator import ConfigValidator
from ytdl_sub.config.preset_class_mappings import DownloadStrategyMapping from ytdl_sub.config.preset_class_mappings import DownloadStrategyMapping
from ytdl_sub.config.preset_class_mappings import PluginMapping from ytdl_sub.config.preset_class_mappings import PluginMapping
from ytdl_sub.config.preset_options import OptionsValidator
from ytdl_sub.config.preset_options import OutputOptions from ytdl_sub.config.preset_options import OutputOptions
from ytdl_sub.config.preset_options import Overrides from ytdl_sub.config.preset_options import Overrides
from ytdl_sub.config.preset_options import YTDLOptions from ytdl_sub.config.preset_options import YTDLOptions
@ -20,7 +21,6 @@ from ytdl_sub.downloaders.base_downloader import BaseDownloader
from ytdl_sub.downloaders.base_downloader import BaseDownloaderValidator from ytdl_sub.downloaders.base_downloader import BaseDownloaderValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.plugins.plugin import PluginOptionsT from ytdl_sub.plugins.plugin import PluginOptionsT
from ytdl_sub.prebuilt_presets import PREBUILT_PRESET_NAMES from ytdl_sub.prebuilt_presets import PREBUILT_PRESET_NAMES
from ytdl_sub.prebuilt_presets import PUBLISHED_PRESET_NAMES from ytdl_sub.prebuilt_presets import PUBLISHED_PRESET_NAMES
@ -67,9 +67,9 @@ def _parent_preset_error_message(
class PresetPlugins: class PresetPlugins:
def __init__(self): def __init__(self):
self.plugin_types: List[Type[Plugin]] = [] self.plugin_types: List[Type[Plugin]] = []
self.plugin_options: List[PluginOptions] = [] self.plugin_options: List[OptionsValidator] = []
def add(self, plugin_type: Type[Plugin], plugin_options: PluginOptions) -> "PresetPlugins": def add(self, plugin_type: Type[Plugin], plugin_options: OptionsValidator) -> "PresetPlugins":
""" """
Add a pair of plugin type and options to the list Add a pair of plugin type and options to the list
""" """
@ -77,7 +77,7 @@ class PresetPlugins:
self.plugin_options.append(plugin_options) self.plugin_options.append(plugin_options)
return self return self
def zipped(self) -> Iterable[Tuple[Type[Plugin], PluginOptions]]: def zipped(self) -> Iterable[Tuple[Type[Plugin], OptionsValidator]]:
""" """
Returns Returns
------- -------

View file

@ -18,11 +18,12 @@ from ytdl_sub.validators.string_formatter_validators import OverridesStringForma
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
from ytdl_sub.validators.validators import BoolValidator from ytdl_sub.validators.validators import BoolValidator
from ytdl_sub.validators.validators import LiteralDictValidator from ytdl_sub.validators.validators import LiteralDictValidator
from ytdl_sub.validators.validators import Validator
# pylint: disable=no-self-use # pylint: disable=no-self-use
# pylint: disable=unused-argument # pylint: disable=unused-argument
class OptionsValidator(StrictDictValidator, ABC): class OptionsValidator(Validator, ABC):
""" """
Abstract class that validates options for preset sections (plugins, downloaders) Abstract class that validates options for preset sections (plugins, downloaders)
""" """
@ -70,6 +71,10 @@ class OptionsValidator(StrictDictValidator, ABC):
return None return None
class OptionsDictValidator(StrictDictValidator, OptionsValidator, ABC):
pass
# pylint: enable=no-self-use # pylint: enable=no-self-use
# pylint: enable=unused-argument # pylint: enable=unused-argument

View file

@ -6,7 +6,7 @@ from typing import List
from typing import Type from typing import Type
from typing import TypeVar from typing import TypeVar
from ytdl_sub.config.preset_options import OptionsValidator from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.config.preset_options import Overrides from ytdl_sub.config.preset_options import Overrides
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
@ -14,7 +14,7 @@ from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.ytdl_additions.enhanced_download_archive import DownloadArchiver from ytdl_sub.ytdl_additions.enhanced_download_archive import DownloadArchiver
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
BaseDownloaderValidator = OptionsValidator BaseDownloaderValidator = OptionsDictValidator
BaseDownloaderOptionsT = TypeVar("BaseDownloaderOptionsT", bound=BaseDownloaderValidator) BaseDownloaderOptionsT = TypeVar("BaseDownloaderOptionsT", bound=BaseDownloaderValidator)

View file

@ -3,7 +3,7 @@ from typing import Dict
from typing import List from typing import List
from typing import Optional from typing import Optional
from ytdl_sub.config.preset_options import OptionsValidator from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.validators.strict_dict_validator import StrictDictValidator from ytdl_sub.validators.strict_dict_validator import StrictDictValidator
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator from ytdl_sub.validators.string_formatter_validators import OverridesStringFormatterValidator
@ -172,7 +172,7 @@ class UrlListValidator(ListValidator[UrlValidator]):
collection_variables[var] = added_variables[var] collection_variables[var] = added_variables[var]
class MultiUrlValidator(OptionsValidator): class MultiUrlValidator(OptionsDictValidator):
""" """
Downloads from multiple URLs. If an entry is returned from more than one URL, it will Downloads from multiple URLs. If an entry is returned from more than one URL, it will
resolve to the bottom-most URL settings. resolve to the bottom-most URL settings.

View file

@ -3,17 +3,17 @@ from typing import Any
from typing import Dict from typing import Dict
from typing import Optional from typing import Optional
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.exceptions import FileNotDownloadedException from ytdl_sub.utils.exceptions import FileNotDownloadedException
from ytdl_sub.validators.audo_codec_validator import AUDIO_CODEC_TYPES_EXTENSION_MAPPING from ytdl_sub.validators.audo_codec_validator import AUDIO_CODEC_TYPES_EXTENSION_MAPPING
from ytdl_sub.validators.audo_codec_validator import AudioTypeValidator from ytdl_sub.validators.audo_codec_validator import AudioTypeValidator
from ytdl_sub.validators.validators import FloatValidator from ytdl_sub.validators.validators import FloatValidator
class AudioExtractOptions(PluginOptions): class AudioExtractOptions(OptionsDictValidator):
""" """
Extracts audio from a video file. Extracts audio from a video file.

View file

@ -5,12 +5,12 @@ from typing import List
from typing import Optional from typing import Optional
from typing import Set from typing import Set
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.variables.kwargs import COMMENTS from ytdl_sub.entries.variables.kwargs import COMMENTS
from ytdl_sub.entries.variables.kwargs import YTDL_SUB_CUSTOM_CHAPTERS from ytdl_sub.entries.variables.kwargs import YTDL_SUB_CUSTOM_CHAPTERS
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.chapters import Chapters from ytdl_sub.utils.chapters import Chapters
from ytdl_sub.utils.ffmpeg import set_ffmpeg_metadata_chapters from ytdl_sub.utils.ffmpeg import set_ffmpeg_metadata_chapters
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
@ -58,7 +58,7 @@ class SponsorBlockCategoryListValidator(ListValidator[SponsorBlockCategoriesVali
_inner_list_type = SponsorBlockCategoriesValidator _inner_list_type = SponsorBlockCategoriesValidator
class ChaptersOptions(PluginOptions): class ChaptersOptions(OptionsDictValidator):
""" """
Embeds chapters to video files if they are present. Additional options to add SponsorBlock Embeds chapters to video files if they are present. Additional options to add SponsorBlock
chapters and remove specific ones. Can also remove chapters using regex. chapters and remove specific ones. Can also remove chapters using regex.

View file

@ -1,14 +1,14 @@
from typing import Dict from typing import Dict
from typing import Optional from typing import Optional
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.datetime import to_date_range from ytdl_sub.utils.datetime import to_date_range
from ytdl_sub.validators.string_datetime import StringDatetimeValidator from ytdl_sub.validators.string_datetime import StringDatetimeValidator
class DateRangeOptions(PluginOptions): class DateRangeOptions(OptionsDictValidator):
""" """
Only download files uploaded within the specified date range. Only download files uploaded within the specified date range.

View file

@ -3,10 +3,10 @@ from typing import Any
from typing import Dict from typing import Dict
from typing import Optional from typing import Optional
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.variables.kwargs import EXT from ytdl_sub.entries.variables.kwargs import EXT
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.plugins.plugin import PluginPriority from ytdl_sub.plugins.plugin import PluginPriority
from ytdl_sub.utils.exceptions import FileNotDownloadedException from ytdl_sub.utils.exceptions import FileNotDownloadedException
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
@ -22,7 +22,7 @@ class FileConvertWithValidator(StringSelectValidator):
_select_values = {"yt-dlp", "ffmpeg"} _select_values = {"yt-dlp", "ffmpeg"}
class FileConvertOptions(PluginOptions): class FileConvertOptions(OptionsDictValidator):
""" """
Converts video files from one extension to another. Converts video files from one extension to another.

View file

@ -1,17 +1,17 @@
import copy import copy
from typing import Optional from typing import Optional
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.config.preset_options import Overrides from ytdl_sub.config.preset_options import Overrides
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.output_directory_nfo_tags import OutputDirectoryNfoTagsOptions from ytdl_sub.plugins.output_directory_nfo_tags import OutputDirectoryNfoTagsOptions
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.plugins.plugin import PluginPriority from ytdl_sub.plugins.plugin import PluginPriority
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive from ytdl_sub.ytdl_additions.enhanced_download_archive import EnhancedDownloadArchive
class ViewOptions(PluginOptions): class ViewOptions(OptionsDictValidator):
""" """
INTERNAL PLUGIN. Do not expose in documentation INTERNAL PLUGIN. Do not expose in documentation
""" """

View file

@ -5,10 +5,10 @@ from typing import Optional
from yt_dlp import match_filter_func from yt_dlp import match_filter_func
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.variables.kwargs import YTDL_SUB_MATCH_FILTER_REJECT from ytdl_sub.entries.variables.kwargs import YTDL_SUB_MATCH_FILTER_REJECT
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.plugins.plugin import PluginPriority from ytdl_sub.plugins.plugin import PluginPriority
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
from ytdl_sub.validators.validators import StringListValidator from ytdl_sub.validators.validators import StringListValidator
@ -16,7 +16,7 @@ from ytdl_sub.validators.validators import StringListValidator
logger = Logger.get("match_filters") logger = Logger.get("match_filters")
class MatchFiltersOptions(PluginOptions): class MatchFiltersOptions(OptionsDictValidator):
""" """
Set ``--match-filters``` to pass into yt-dlp to filter entries from being downloaded. Set ``--match-filters``` to pass into yt-dlp to filter entries from being downloaded.
Uses the same syntax as yt-dlp. Uses the same syntax as yt-dlp.

View file

@ -5,9 +5,9 @@ from typing import List
import mediafile import mediafile
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
from ytdl_sub.utils.thumbnail import convert_download_thumbnail from ytdl_sub.utils.thumbnail import convert_download_thumbnail
@ -45,7 +45,7 @@ class MusicTagsValidator(StrictDictValidator):
return self._tags return self._tags
class MusicTagsOptions(PluginOptions): class MusicTagsOptions(OptionsDictValidator):
""" """
Adds tags to every download audio file using Adds tags to every download audio file using
`MediaFile <https://mediafile.readthedocs.io/en/latest/>`_, `MediaFile <https://mediafile.readthedocs.io/en/latest/>`_,

View file

@ -7,9 +7,9 @@ from typing import Dict
from typing import List from typing import List
from typing import Optional from typing import Optional
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.file_handler import FileHandler from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.xml import XmlElement from ytdl_sub.utils.xml import XmlElement
@ -23,7 +23,7 @@ from ytdl_sub.validators.string_formatter_validators import StringFormatterValid
from ytdl_sub.validators.validators import BoolValidator from ytdl_sub.validators.validators import BoolValidator
class SharedNfoTagsOptions(PluginOptions): class SharedNfoTagsOptions(OptionsDictValidator):
""" """
Shared code between NFO tags and Ouptut Directory NFO Tags Shared code between NFO tags and Ouptut Directory NFO Tags
""" """

View file

@ -40,8 +40,7 @@ class PluginPriority:
return self.modify_entry >= PluginPriority.MODIFY_ENTRY_AFTER_SPLIT return self.modify_entry >= PluginPriority.MODIFY_ENTRY_AFTER_SPLIT
PluginOptions = OptionsValidator PluginOptionsT = TypeVar("PluginOptionsT", bound=OptionsValidator)
PluginOptionsT = TypeVar("PluginOptionsT", bound=PluginOptions)
class Plugin(DownloadArchiver, Generic[PluginOptionsT], ABC): class Plugin(DownloadArchiver, Generic[PluginOptionsT], ABC):

View file

@ -5,10 +5,10 @@ from typing import Optional
from yt_dlp.utils import sanitize_filename from yt_dlp.utils import sanitize_filename
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.variables.kwargs import YTDL_SUB_REGEX_SOURCE_VARS from ytdl_sub.entries.variables.kwargs import YTDL_SUB_REGEX_SOURCE_VARS
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.plugins.plugin import PluginPriority from ytdl_sub.plugins.plugin import PluginPriority
from ytdl_sub.utils.exceptions import RegexNoMatchException from ytdl_sub.utils.exceptions import RegexNoMatchException
from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException from ytdl_sub.utils.exceptions import StringFormattingVariableNotFoundException
@ -121,7 +121,7 @@ class FromSourceVariablesRegex(StrictDictValidator):
} }
class RegexOptions(PluginOptions): class RegexOptions(OptionsDictValidator):
r""" r"""
Performs regex matching on an entry's source or override variables. Regex can be used to filter Performs regex matching on an entry's source or override variables. Regex can be used to filter
entries from proceeding with download or capture groups to create new source variables. NOTE to entries from proceeding with download or capture groups to create new source variables. NOTE to

View file

@ -8,13 +8,13 @@ from typing import Tuple
from yt_dlp.utils import sanitize_filename from yt_dlp.utils import sanitize_filename
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.entries.variables.kwargs import CHAPTERS from ytdl_sub.entries.variables.kwargs import CHAPTERS
from ytdl_sub.entries.variables.kwargs import SPLIT_BY_CHAPTERS_PARENT_ENTRY from ytdl_sub.entries.variables.kwargs import SPLIT_BY_CHAPTERS_PARENT_ENTRY
from ytdl_sub.entries.variables.kwargs import SPONSORBLOCK_CHAPTERS from ytdl_sub.entries.variables.kwargs import SPONSORBLOCK_CHAPTERS
from ytdl_sub.entries.variables.kwargs import UID from ytdl_sub.entries.variables.kwargs import UID
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.chapters import Chapters from ytdl_sub.utils.chapters import Chapters
from ytdl_sub.utils.chapters import Timestamp from ytdl_sub.utils.chapters import Timestamp
from ytdl_sub.utils.exceptions import ValidationException from ytdl_sub.utils.exceptions import ValidationException
@ -47,7 +47,7 @@ class WhenNoChaptersValidator(StringSelectValidator):
_select_values = {"pass", "drop", "error"} _select_values = {"pass", "drop", "error"}
class SplitByChaptersOptions(PluginOptions): class SplitByChaptersOptions(OptionsDictValidator):
""" """
Splits a file by chapters into multiple files. Each file becomes its own entry with the Splits a file by chapters into multiple files. Each file becomes its own entry with the
new source variables ``chapter_title``, ``chapter_title_sanitized``, ``chapter_index``, new source variables ``chapter_title``, ``chapter_title_sanitized``, ``chapter_index``,

View file

@ -3,10 +3,10 @@ from typing import Dict
from typing import List from typing import List
from typing import Optional from typing import Optional
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder from ytdl_sub.downloaders.ytdl_options_builder import YTDLOptionsBuilder
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.file_handler import FileHandler from ytdl_sub.utils.file_handler import FileHandler
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.utils.logger import Logger from ytdl_sub.utils.logger import Logger
@ -25,7 +25,7 @@ class SubtitlesTypeValidator(StringSelectValidator):
_select_values = SUBTITLE_EXTENSIONS _select_values = SUBTITLE_EXTENSIONS
class SubtitleOptions(PluginOptions): class SubtitleOptions(OptionsDictValidator):
""" """
Defines how to download and store subtitles. Using this plugin creates two new variables: Defines how to download and store subtitles. Using this plugin creates two new variables:
``lang`` and ``subtitles_ext``. ``lang`` is dynamic since you can download multiple subtitles. ``lang`` and ``subtitles_ext``. ``lang`` is dynamic since you can download multiple subtitles.

View file

@ -1,15 +1,15 @@
from typing import Any from typing import Any
from typing import Dict from typing import Dict
from ytdl_sub.config.preset_options import OptionsDictValidator
from ytdl_sub.entries.entry import Entry from ytdl_sub.entries.entry import Entry
from ytdl_sub.plugins.plugin import Plugin from ytdl_sub.plugins.plugin import Plugin
from ytdl_sub.plugins.plugin import PluginOptions
from ytdl_sub.utils.ffmpeg import add_ffmpeg_metadata_key_values from ytdl_sub.utils.ffmpeg import add_ffmpeg_metadata_key_values
from ytdl_sub.utils.file_handler import FileMetadata from ytdl_sub.utils.file_handler import FileMetadata
from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator from ytdl_sub.validators.string_formatter_validators import DictFormatterValidator
class VideoTagsOptions(PluginOptions): class VideoTagsOptions(OptionsDictValidator):
""" """
Adds tags to every downloaded video file using ffmpeg ``-metadata key=value`` args. Adds tags to every downloaded video file using ffmpeg ``-metadata key=value`` args.