]> jfr.im git - yt-dlp.git/commitdiff
[utils] Add `deprecation_warning`
authorpukkandan <redacted>
Tue, 30 Aug 2022 15:28:28 +0000 (20:58 +0530)
committerpukkandan <redacted>
Tue, 30 Aug 2022 15:33:07 +0000 (21:03 +0530)
See https://github.com/yt-dlp/yt-dlp/pull/2173#issuecomment-1097021515

12 files changed:
yt_dlp/YoutubeDL.py
yt_dlp/__init__.py
yt_dlp/__main__.py
yt_dlp/downloader/common.py
yt_dlp/downloader/fragment.py
yt_dlp/extractor/common.py
yt_dlp/extractor/youtube.py
yt_dlp/options.py
yt_dlp/postprocessor/common.py
yt_dlp/postprocessor/ffmpeg.py
yt_dlp/update.py
yt_dlp/utils.py

index 4330006ccb3c31b6515d7b4e91e54c2faba29596..491e02dec69f3888eeb580524e1a040ba0c9f6ec 100644 (file)
@@ -90,6 +90,7 @@
     args_to_str,
     bug_reports_message,
     date_from_str,
+    deprecation_warning,
     determine_ext,
     determine_protocol,
     encode_compat_str,
@@ -631,7 +632,7 @@ def check_deprecated(param, option, suggestion):
         for msg in self.params.get('_warnings', []):
             self.report_warning(msg)
         for msg in self.params.get('_deprecation_warnings', []):
-            self.deprecation_warning(msg)
+            self.deprecated_feature(msg)
 
         self.params['compat_opts'] = set(self.params.get('compat_opts', ()))
         if 'list-formats' in self.params['compat_opts']:
@@ -835,9 +836,11 @@ def _write_string(self, message, out=None, only_once=False):
     def to_stdout(self, message, skip_eol=False, quiet=None):
         """Print message to stdout"""
         if quiet is not None:
-            self.deprecation_warning('"YoutubeDL.to_stdout" no longer accepts the argument quiet. Use "YoutubeDL.to_screen" instead')
+            self.deprecation_warning('"YoutubeDL.to_stdout" no longer accepts the argument quiet. '
+                                     'Use "YoutubeDL.to_screen" instead')
         if skip_eol is not False:
-            self.deprecation_warning('"YoutubeDL.to_stdout" no longer accepts the argument skip_eol. Use "YoutubeDL.to_screen" instead')
+            self.deprecation_warning('"YoutubeDL.to_stdout" no longer accepts the argument skip_eol. '
+                                     'Use "YoutubeDL.to_screen" instead')
         self._write_string(f'{self._bidi_workaround(message)}\n', self._out_files.out)
 
     def to_screen(self, message, skip_eol=False, quiet=None):
@@ -973,11 +976,14 @@ def report_warning(self, message, only_once=False):
                 return
             self.to_stderr(f'{self._format_err("WARNING:", self.Styles.WARNING)} {message}', only_once)
 
-    def deprecation_warning(self, message):
+    def deprecation_warning(self, message, *, stacklevel=0):
+        deprecation_warning(
+            message, stacklevel=stacklevel + 1, printer=self.report_error, is_error=False)
+
+    def deprecated_feature(self, message):
         if self.params.get('logger') is not None:
-            self.params['logger'].warning(f'DeprecationWarning: {message}')
-        else:
-            self.to_stderr(f'{self._format_err("DeprecationWarning:", self.Styles.ERROR)} {message}', True)
+            self.params['logger'].warning(f'Deprecated Feature: {message}')
+        self.to_stderr(f'{self._format_err("Deprecated Feature:", self.Styles.ERROR)} {message}', True)
 
     def report_error(self, message, *args, **kwargs):
         '''
index e9234e6f49186257c6e195aa5b742b9b7a6751b3..3dc9b6e569b33eb9a4e6e178c74a7fb3c24732fe 100644 (file)
@@ -63,6 +63,8 @@
 )
 from .YoutubeDL import YoutubeDL
 
+_IN_CLI = False
+
 
 def _exit(status=0, *args):
     for msg in args:
index ff5d71d3c97d6fdeb0fc86d5a5d177b3c8cda652..895918c272405e6cb59b7dd0ce75ce46233f9bfc 100644 (file)
@@ -14,4 +14,5 @@
 import yt_dlp
 
 if __name__ == '__main__':
+    yt_dlp._IN_CLI = True
     yt_dlp.main()
index 4962c0cf8bde8c01646848b1ff0abc88ad957da2..9ade4269e8fc266875b6edf3f57721d093d7211e 100644 (file)
@@ -92,6 +92,7 @@ def _set_ydl(self, ydl):
 
         for func in (
             'deprecation_warning',
+            'deprecated_feature',
             'report_error',
             'report_file_already_downloaded',
             'report_warning',
index b1d3127c323c418e8b06fa1ce37aeff496a394e0..a5d70d0d499f0f4b0d5d35d5205184e1ef4a73f0 100644 (file)
@@ -65,8 +65,8 @@ class FragmentFD(FileDownloader):
     """
 
     def report_retry_fragment(self, err, frag_index, count, retries):
-        self.deprecation_warning(
-            'yt_dlp.downloader.FragmentFD.report_retry_fragment is deprecated. Use yt_dlp.downloader.FileDownloader.report_retry instead')
+        self.deprecation_warning('yt_dlp.downloader.FragmentFD.report_retry_fragment is deprecated. '
+                                 'Use yt_dlp.downloader.FileDownloader.report_retry instead')
         return self.report_retry(err, count, retries, frag_index)
 
     def report_skip_fragment(self, frag_index, err=None):
index 6337a13a4427ee9ed46dbd50ecc05c36e9342524..f950d28ed3f4d256fcb6bf0923392d9ac8945034 100644 (file)
@@ -1766,9 +1766,8 @@ 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.ydl.deprecated_feature(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:
@@ -1853,9 +1852,8 @@ def add_item(field, reverse, closest, limit_text):
                 if self._get_field_setting(field, 'type') == 'alias':
                     alias, field = field, self._get_field_setting(field, 'field')
                     if self._get_field_setting(alias, 'deprecated'):
-                        self.ydl.deprecation_warning(
-                            f'Format sorting alias {alias} is deprecated '
-                            f'and may be removed in a future version. Please use {field} instead')
+                        self.ydl.deprecated_feature(f'Format sorting alias {alias} is deprecated 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')
index 0498f980d210ef1baa9e1a855cf0a96a89c312fe..ee9cce16e7f69f8f2df5f210ac0fb70069cf648c 100644 (file)
@@ -2959,8 +2959,8 @@ def extract_thread(contents):
         # YouTube comments have a max depth of 2
         max_depth = int_or_none(get_single_config_arg('max_comment_depth'))
         if max_depth:
-            self._downloader.deprecation_warning(
-                '[youtube] max_comment_depth extractor argument is deprecated. Set max replies in the max-comments extractor argument instead.')
+            self._downloader.deprecated_feature('[youtube] max_comment_depth extractor argument is deprecated. '
+                                                'Set max replies in the max-comments extractor argument instead')
         if max_depth == 1 and parent:
             return
 
index a0db9bc028cf5f51c6c961f114c99c004f344762..e667384481d97c42563b2f4139b4374d76092acd 100644 (file)
@@ -25,6 +25,7 @@
     OUTTMPL_TYPES,
     POSTPROCESS_WHEN,
     Config,
+    deprecation_warning,
     expand_path,
     format_field,
     get_executable_path,
@@ -1864,7 +1865,6 @@ def _alias_callback(option, opt_str, value, parser, opts, nargs):
 
 
 def _hide_login_info(opts):
-    write_string(
-        'DeprecationWarning: "yt_dlp.options._hide_login_info" is deprecated and may be removed in a future version. '
-        'Use "yt_dlp.utils.Config.hide_login_info" instead\n')
+    deprecation_warning(f'"{__name__}._hide_login_info" is deprecated and may be removed '
+                        'in a future version. Use "yt_dlp.utils.Config.hide_login_info" instead')
     return Config.hide_login_info(opts)
index 20d890df03400ff741717fee7740a4adc6847f68..44feda4278a8ce81d3e02395322120ba89a7629a 100644 (file)
@@ -7,10 +7,10 @@
     PostProcessingError,
     RetryManager,
     _configuration_args,
+    deprecation_warning,
     encodeFilename,
     network_exceptions,
     sanitized_Request,
-    write_string,
 )
 
 
@@ -73,10 +73,14 @@ def report_warning(self, text, *args, **kwargs):
         if self._downloader:
             return self._downloader.report_warning(text, *args, **kwargs)
 
-    def deprecation_warning(self, text):
+    def deprecation_warning(self, msg):
+        warn = getattr(self._downloader, 'deprecation_warning', deprecation_warning)
+        return warn(msg, stacklevel=1)
+
+    def deprecated_feature(self, msg):
         if self._downloader:
-            return self._downloader.deprecation_warning(text)
-        write_string(f'DeprecationWarning: {text}')
+            return self._downloader.deprecated_feature(msg)
+        return deprecation_warning(msg, stacklevel=1)
 
     def report_error(self, text, *args, **kwargs):
         self.deprecation_warning('"yt_dlp.postprocessor.PostProcessor.report_error" is deprecated. '
index a1f367ae42625c4867942ee76ed194c9533d9203..76f9d29c5eead7a07f8ef0189a638d19b82ed810 100644 (file)
@@ -15,6 +15,7 @@
     Popen,
     PostProcessingError,
     _get_exe_version_output,
+    deprecation_warning,
     detect_exe_version,
     determine_ext,
     dfxp2srt,
@@ -30,7 +31,6 @@
     traverse_obj,
     variadic,
     write_json_file,
-    write_string,
 )
 
 EXT_TO_OUT_FORMATS = {
@@ -187,8 +187,8 @@ def _get_version(self, kind):
         else:
             self.probe_basename = basename
         if basename == self._ffmpeg_to_avconv[kind]:
-            self.deprecation_warning(
-                f'Support for {self._ffmpeg_to_avconv[kind]} is deprecated and may be removed in a future version. Use {kind} instead')
+            self.deprecated_feature(f'Support for {self._ffmpeg_to_avconv[kind]} is deprecated and '
+                                    f'may be removed in a future version. Use {kind} instead')
         return version
 
     @functools.cached_property
@@ -1064,7 +1064,7 @@ def __init__(self, downloader=None, format=None):
 
     @classmethod
     def is_webp(cls, path):
-        write_string(f'DeprecationWarning: {cls.__module__}.{cls.__name__}.is_webp is deprecated')
+        deprecation_warning(f'{cls.__module__}.{cls.__name__}.is_webp is deprecated')
         return imghdr.what(path) == 'webp'
 
     def fixup_webp(self, info, idx=-1):
index e82cdf451a58f227f3e17bc24f43fae07792e826..026bc12aa4716ff32f6df37d2dd4c4d916e1d070 100644 (file)
@@ -14,6 +14,7 @@
 from .utils import (
     Popen,
     cached_method,
+    deprecation_warning,
     shell_quote,
     system_identifier,
     traverse_obj,
@@ -302,11 +303,8 @@ def run_update(ydl):
 def update_self(to_screen, verbose, opener):
     import traceback
 
-    from .utils import write_string
-
-    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\n')
+    deprecation_warning(f'"{__name__}.update_self" is deprecated and may be removed '
+                        f'in a future version. Use "{__name__}.run_update(ydl)" instead')
 
     printfn = to_screen
 
index 957c7eaa7969fa6959e75381a16ac0920ca02c97..da2d042cb34b80a9e42c410059d53e776e134979 100644 (file)
@@ -828,8 +828,8 @@ def escapeHTML(text):
 
 
 def process_communicate_or_kill(p, *args, **kwargs):
-    write_string('DeprecationWarning: yt_dlp.utils.process_communicate_or_kill is deprecated '
-                 'and may be removed in a future version. Use yt_dlp.utils.Popen.communicate_or_kill instead')
+    deprecation_warning(f'"{__name__}.process_communicate_or_kill" is deprecated and may be removed '
+                        f'in a future version. Use "{__name__}.Popen.communicate_or_kill" instead')
     return Popen.communicate_or_kill(p, *args, **kwargs)
 
 
@@ -1934,7 +1934,7 @@ def __eq__(self, other):
 
 def platform_name():
     """ Returns the platform name as a str """
-    write_string('DeprecationWarning: yt_dlp.utils.platform_name is deprecated, use platform.platform instead')
+    deprecation_warning(f'"{__name__}.platform_name" is deprecated, use "platform.platform" instead')
     return platform.platform()
 
 
@@ -1980,6 +1980,23 @@ def write_string(s, out=None, encoding=None):
     out.flush()
 
 
+def deprecation_warning(msg, *, printer=None, stacklevel=0, **kwargs):
+    from . import _IN_CLI
+    if _IN_CLI:
+        if msg in deprecation_warning._cache:
+            return
+        deprecation_warning._cache.add(msg)
+        if printer:
+            return printer(f'{msg}{bug_reports_message()}', **kwargs)
+        return write_string(f'ERROR: {msg}{bug_reports_message()}\n', **kwargs)
+    else:
+        import warnings
+        warnings.warn(DeprecationWarning(msg), stacklevel=stacklevel + 3)
+
+
+deprecation_warning._cache = set()
+
+
 def bytes_to_intlist(bs):
     if not bs:
         return []
@@ -4862,8 +4879,8 @@ def decode_base_n(string, n=None, table=None):
 
 
 def decode_base(value, digits):
-    write_string('DeprecationWarning: yt_dlp.utils.decode_base is deprecated '
-                 'and may be removed in a future version. Use yt_dlp.decode_base_n instead')
+    deprecation_warning(f'{__name__}.decode_base is deprecated and may be removed '
+                        f'in a future version. Use {__name__}.decode_base_n instead')
     return decode_base_n(value, table=digits)
 
 
@@ -5332,8 +5349,8 @@ def _traverse_obj(obj, path, _current_depth=0):
 
 
 def traverse_dict(dictn, keys, casesense=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')
+    deprecation_warning(f'"{__name__}.traverse_dict" is deprecated and may be removed '
+                        f'in a future version. Use "{__name__}.traverse_obj" instead')
     return traverse_obj(dictn, keys, casesense=casesense, is_user_input=True, traverse_string=True)