From ee8dd27a7351841e1de8cebf8311b69fbef09eab Mon Sep 17 00:00:00 2001 From: pukkandan Date: Mon, 29 Nov 2021 23:16:06 +0530 Subject: [PATCH] [cleanup] Add deprecation warnings --- yt_dlp/YoutubeDL.py | 8 ++++++++ yt_dlp/__init__.py | 19 +++++++++++++++++-- yt_dlp/extractor/common.py | 14 +++++++++++--- yt_dlp/postprocessor/common.py | 6 ++++++ yt_dlp/postprocessor/exec.py | 9 +++++++-- yt_dlp/postprocessor/ffmpeg.py | 7 +++++++ yt_dlp/postprocessor/metadataparser.py | 14 +++++++++++--- yt_dlp/postprocessor/sponskrub.py | 7 ++++++- yt_dlp/update.py | 8 ++++---- yt_dlp/utils.py | 7 ++++--- 10 files changed, 81 insertions(+), 18 deletions(-) diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 593f73f87..a6e0163af 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -566,6 +566,8 @@ class YoutubeDL(object): for msg in self.params.get('_warnings', []): self.report_warning(msg) + for msg in self.params.get('_deprecation_warnings', []): + self.deprecation_warning(msg) if 'list-formats' in self.params.get('compat_opts', []): self.params['listformats_table'] = False @@ -886,6 +888,12 @@ class YoutubeDL(object): return self.to_stderr(f'{self._format_err("WARNING:", self.Styles.WARNING)} {message}', only_once) + def deprecation_warning(self, message): + if self.params.get('logger') is not None: + self.params['logger'].warning('DeprecationWarning: {message}') + else: + self.to_stderr(f'{self._format_err("DeprecationWarning:", self.Styles.ERROR)} {message}', True) + def report_error(self, message, tb=None): ''' Do the same as trouble, but prefixes the message with 'ERROR:', colored diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index 13d20611f..92d1fa16c 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -71,7 +71,7 @@ def _real_main(argv=None): setproctitle('yt-dlp') parser, opts, args = parseOpts(argv) - warnings = [] + warnings, deprecation_warnings = [], [] # Set user agent if opts.user_agent is not None: @@ -536,7 +536,7 @@ def _real_main(argv=None): 'add_metadata': opts.addmetadata, 'add_infojson': opts.embed_infojson, }) - # Note: Deprecated + # Deprecated # This should be above EmbedThumbnail since sponskrub removes the thumbnail attachment # but must be below EmbedSubtitle and FFmpegMetadata # See https://github.com/yt-dlp/yt-dlp/issues/204 , https://github.com/faissaloo/SponSkrub/issues/29 @@ -549,6 +549,7 @@ def _real_main(argv=None): 'cut': opts.sponskrub_cut, 'force': opts.sponskrub_force, 'ignoreerror': opts.sponskrub is None, + '_from_cli': True, }) if opts.embedthumbnail: already_have_thumbnail = opts.writethumbnail or opts.write_all_thumbnails @@ -588,6 +589,19 @@ def _real_main(argv=None): opts.postprocessor_args.setdefault('sponskrub', []) opts.postprocessor_args['default'] = opts.postprocessor_args['default-compat'] + def report_deprecation(val, old, new=None): + if not val: + return + deprecation_warnings.append( + f'{old} is deprecated and may be removed in a future version. Use {new} instead' if new + else f'{old} is deprecated and may not work as expected') + + report_deprecation(opts.sponskrub, '--sponskrub', '--sponsorblock-mark or --sponsorblock-remove') + report_deprecation(not opts.prefer_ffmpeg, '--prefer-avconv', 'ffmpeg') + report_deprecation(opts.include_ads, '--include-ads') + # report_deprecation(opts.call_home, '--call-home') # We may re-implement this in future + # report_deprecation(opts.writeannotations, '--write-annotations') # It's just that no website has it + final_ext = ( opts.recodevideo if opts.recodevideo in FFmpegVideoConvertorPP.SUPPORTED_EXTS else opts.remuxvideo if opts.remuxvideo in FFmpegVideoRemuxerPP.SUPPORTED_EXTS @@ -756,6 +770,7 @@ def _real_main(argv=None): 'geo_bypass_country': opts.geo_bypass_country, 'geo_bypass_ip_block': opts.geo_bypass_ip_block, '_warnings': warnings, + '_deprecation_warnings': deprecation_warnings, 'compat_opts': compat_opts, } diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py index 374aa9829..37e69d409 100644 --- a/yt_dlp/extractor/common.py +++ b/yt_dlp/extractor/common.py @@ -1586,7 +1586,7 @@ class InfoExtractor(object): 'res': {'type': 'multiple', 'field': ('height', 'width'), 'function': lambda it: (lambda l: min(l) if l else 0)(tuple(filter(None, it)))}, - # Most of these exist only for compatibility reasons + # Deprecated 'dimension': {'type': 'alias', 'field': 'res'}, 'resolution': {'type': 'alias', 'field': 'res'}, 'extension': {'type': 'alias', 'field': 'ext'}, @@ -1595,7 +1595,7 @@ class InfoExtractor(object): 'video_bitrate': {'type': 'alias', 'field': 'vbr'}, 'audio_bitrate': {'type': 'alias', 'field': 'abr'}, 'framerate': {'type': 'alias', 'field': 'fps'}, - 'language_preference': {'type': 'alias', 'field': 'lang'}, # not named as 'language' because such a field exists + 'language_preference': {'type': 'alias', 'field': 'lang'}, 'protocol': {'type': 'alias', 'field': 'proto'}, 'source_preference': {'type': 'alias', 'field': 'source'}, 'filesize_approx': {'type': 'alias', 'field': 'fs_approx'}, @@ -1624,6 +1624,11 @@ class InfoExtractor(object): def _get_field_setting(self, field, key): if field not in self.settings: + if key in ('forced', 'priority'): + return False + self.ydl.deprecation_warning( + f'Using arbitrary fields ({field}) for format sorting is deprecated ' + 'and may be removed in a future version') self.settings[field] = {} propObj = self.settings[field] if key not in propObj: @@ -1706,7 +1711,10 @@ class InfoExtractor(object): if field is None: continue if self._get_field_setting(field, 'type') == 'alias': - field = self._get_field_setting(field, 'field') + alias, field = field, self._get_field_setting(field, 'field') + self.ydl.deprecation_warning( + f'Format sorting alias {alias} is deprecated ' + f'and may be removed in a future version. Please use {field} instead') reverse = match.group('reverse') is not None closest = match.group('separator') == '~' limit_text = match.group('limit') diff --git a/yt_dlp/postprocessor/common.py b/yt_dlp/postprocessor/common.py index b36716743..ab9eb6acf 100644 --- a/yt_dlp/postprocessor/common.py +++ b/yt_dlp/postprocessor/common.py @@ -9,6 +9,7 @@ from ..utils import ( _configuration_args, encodeFilename, PostProcessingError, + write_string, ) @@ -74,6 +75,11 @@ class PostProcessor(metaclass=PostProcessorMetaClass): if self._downloader: return self._downloader.report_warning(text, *args, **kwargs) + def deprecation_warning(self, text): + if self._downloader: + return self._downloader.deprecation_warning(text) + write_string(f'DeprecationWarning: {text}') + def report_error(self, text, *args, **kwargs): # Exists only for compatibility. Do not use if self._downloader: diff --git a/yt_dlp/postprocessor/exec.py b/yt_dlp/postprocessor/exec.py index 7a3cb4999..28a7c3d70 100644 --- a/yt_dlp/postprocessor/exec.py +++ b/yt_dlp/postprocessor/exec.py @@ -38,5 +38,10 @@ class ExecPP(PostProcessor): return [], info -class ExecAfterDownloadPP(ExecPP): # for backward compatibility - pass +# Deprecated +class ExecAfterDownloadPP(ExecPP): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.deprecation_warning( + 'yt_dlp.postprocessor.ExecAfterDownloadPP is deprecated ' + 'and may be removed in a future version. Use yt_dlp.postprocessor.ExecPP instead') diff --git a/yt_dlp/postprocessor/ffmpeg.py b/yt_dlp/postprocessor/ffmpeg.py index f712547a8..609f97e47 100644 --- a/yt_dlp/postprocessor/ffmpeg.py +++ b/yt_dlp/postprocessor/ffmpeg.py @@ -167,6 +167,13 @@ class FFmpegPostProcessor(PostProcessor): self.probe_basename = p break + if self.basename == 'avconv': + self.deprecation_warning( + 'Support for avconv is deprecated and may be removed in a future version. Use ffmpeg instead') + if self.probe_basename == 'avprobe': + self.deprecation_warning( + 'Support for avprobe is deprecated and may be removed in a future version. Use ffprobe instead') + @property def available(self): return self.basename is not None diff --git a/yt_dlp/postprocessor/metadataparser.py b/yt_dlp/postprocessor/metadataparser.py index a5762b3c0..54b2c5627 100644 --- a/yt_dlp/postprocessor/metadataparser.py +++ b/yt_dlp/postprocessor/metadataparser.py @@ -96,6 +96,7 @@ class MetadataParserPP(PostProcessor): return f +# Deprecated class MetadataFromFieldPP(MetadataParserPP): @classmethod def to_action(cls, f): @@ -108,9 +109,16 @@ class MetadataFromFieldPP(MetadataParserPP): match.group('out')) def __init__(self, downloader, formats): - MetadataParserPP.__init__(self, downloader, [self.to_action(f) for f in formats]) + super().__init__(self, downloader, [self.to_action(f) for f in formats]) + self.deprecation_warning( + 'yt_dlp.postprocessor.MetadataFromFieldPP is deprecated ' + 'and may be removed in a future version. Use yt_dlp.postprocessor.MetadataParserPP instead') -class MetadataFromTitlePP(MetadataParserPP): # for backward compatibility +# Deprecated +class MetadataFromTitlePP(MetadataParserPP): def __init__(self, downloader, titleformat): - MetadataParserPP.__init__(self, downloader, [(self.Actions.INTERPRET, 'title', titleformat)]) + super().__init__(self, downloader, [(self.Actions.INTERPRET, 'title', titleformat)]) + self.deprecation_warning( + 'yt_dlp.postprocessor.MetadataFromTitlePP is deprecated ' + 'and may be removed in a future version. Use yt_dlp.postprocessor.MetadataParserPP instead') diff --git a/yt_dlp/postprocessor/sponskrub.py b/yt_dlp/postprocessor/sponskrub.py index 37e7411e4..86149aeef 100644 --- a/yt_dlp/postprocessor/sponskrub.py +++ b/yt_dlp/postprocessor/sponskrub.py @@ -22,13 +22,18 @@ class SponSkrubPP(PostProcessor): _temp_ext = 'spons' _exe_name = 'sponskrub' - def __init__(self, downloader, path='', args=None, ignoreerror=False, cut=False, force=False): + def __init__(self, downloader, path='', args=None, ignoreerror=False, cut=False, force=False, _from_cli=False): PostProcessor.__init__(self, downloader) self.force = force self.cutout = cut self.args = str_or_none(args) or '' # For backward compatibility self.path = self.get_exe(path) + if not _from_cli: + self.deprecation_warning( + 'yt_dlp.postprocessor.SponSkrubPP support is deprecated and may be removed in a future version. ' + 'Use yt_dlp.postprocessor.SponsorBlock and yt_dlp.postprocessor.ModifyChaptersPP instead') + if not ignoreerror and self.path is None: if path: raise PostProcessingError('sponskrub not found in "%s"' % path) diff --git a/yt_dlp/update.py b/yt_dlp/update.py index 4225512e9..aebd5d1e1 100644 --- a/yt_dlp/update.py +++ b/yt_dlp/update.py @@ -10,7 +10,7 @@ import traceback from zipimport import zipimporter from .compat import compat_realpath -from .utils import encode_compat_str, Popen +from .utils import encode_compat_str, Popen, write_string from .version import __version__ @@ -251,13 +251,13 @@ def print_notes(to_screen, versions, fromVersion=__version__): ''' +# Deprecated def update_self(to_screen, verbose, opener): - ''' Exists for backward compatibility ''' printfn = to_screen - printfn( - 'WARNING: "yt_dlp.update.update_self" is deprecated and may be removed in a future version. ' + write_string( + 'DeprecationWarning: "yt_dlp.update.update_self" is deprecated and may be removed in a future version. ' 'Use "yt_dlp.update.run_update(ydl)" instead') class FakeYDL(): diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py index 176656b19..b40e275c0 100644 --- a/yt_dlp/utils.py +++ b/yt_dlp/utils.py @@ -6552,10 +6552,11 @@ def traverse_obj( return default +# Deprecated def traverse_dict(dictn, keys, casesense=True): - ''' For backward compatibility. Do not use ''' - return traverse_obj(dictn, keys, casesense=casesense, - is_user_input=True, traverse_string=True) + write_string('DeprecationWarning: yt_dlp.utils.traverse_dict is deprecated ' + 'and may be removed in a future version. Use yt_dlp.utils.traverse_obj instead') + return traverse_obj(dictn, keys, casesense=casesense, is_user_input=True, traverse_string=True) def variadic(x, allowed_types=(str, bytes)):