import asyncio
import base64
+import collections
import ctypes
import getpass
import html
import http.cookies
import http.server
import itertools
-import optparse
import os
import re
import shlex
import shutil
import socket
import struct
+import subprocess
import sys
import tokenize
import urllib
pass
+# compat_ctypes_WINFUNCTYPE = ctypes.WINFUNCTYPE
+# will not work since ctypes.WINFUNCTYPE does not exist in UNIX machines
def compat_ctypes_WINFUNCTYPE(*args, **kwargs):
return ctypes.WINFUNCTYPE(*args, **kwargs)
compat_realpath = os.path.realpath
-def compat_print(s):
- assert isinstance(s, compat_str)
- print(s)
-
-
-# Fix https://github.com/ytdl-org/youtube-dl/issues/4223
-# See http://bugs.python.org/issue9161 for what is broken
-def workaround_optparse_bug9161():
- op = optparse.OptionParser()
- og = optparse.OptionGroup(op, 'foo')
- try:
- og.add_option('-t')
- except TypeError:
- real_add_option = optparse.OptionGroup.add_option
-
- def _compat_add_option(self, *args, **kwargs):
- enc = lambda v: (
- v.encode('ascii', 'replace') if isinstance(v, compat_str)
- else v)
- bargs = [enc(a) for a in args]
- bkwargs = dict(
- (k, enc(v)) for k, v in kwargs.items())
- return real_add_option(self, *bargs, **bkwargs)
- optparse.OptionGroup.add_option = _compat_add_option
-
-
try:
compat_Pattern = re.Pattern
except AttributeError:
asyncio.run = compat_asyncio_run
+try: # >= 3.7
+ asyncio.tasks.all_tasks
+except AttributeError:
+ asyncio.tasks.all_tasks = asyncio.tasks.Task.all_tasks
+
+try:
+ import websockets as compat_websockets
+except ImportError:
+ compat_websockets = None
+
# Python 3.8+ does not honor %HOME% on windows, but this breaks compatibility with youtube-dl
# See https://github.com/yt-dlp/yt-dlp/issues/792
# https://docs.python.org/3/library/os.path.html#os.path.expanduser
compat_expanduser = os.path.expanduser
-# Deprecated
+try:
+ from Cryptodome.Cipher import AES as compat_pycrypto_AES
+except ImportError:
+ try:
+ from Crypto.Cipher import AES as compat_pycrypto_AES
+ except ImportError:
+ compat_pycrypto_AES = None
-compat_basestring = str
-compat_chr = chr
-compat_input = input
-compat_integer_types = (int, )
-compat_kwargs = lambda kwargs: kwargs
-compat_numeric_types = (int, float, complex)
-compat_str = str
-compat_xpath = lambda xpath: xpath
-compat_zip = zip
+try:
+ import brotlicffi as compat_brotli
+except ImportError:
+ try:
+ import brotli as compat_brotli
+ except ImportError:
+ compat_brotli = None
+
+WINDOWS_VT_MODE = False if compat_os_name == 'nt' else None
+
+
+def windows_enable_vt_mode(): # TODO: Do this the proper way https://bugs.python.org/issue30075
+ if compat_os_name != 'nt':
+ return
+ global WINDOWS_VT_MODE
+ startupinfo = subprocess.STARTUPINFO()
+ startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
+ try:
+ subprocess.Popen('', shell=True, startupinfo=startupinfo)
+ WINDOWS_VT_MODE = True
+ except Exception:
+ pass
+
+
+# Deprecated
-compat_HTMLParser = html.parser.HTMLParser
-compat_HTTPError = urllib.error.HTTPError
-compat_Struct = struct.Struct
compat_b64decode = base64.b64decode
+compat_chr = chr
compat_cookiejar = http.cookiejar
-compat_cookiejar_Cookie = compat_cookiejar.Cookie
-compat_cookies = http.cookies
-compat_cookies_SimpleCookie = compat_cookies.SimpleCookie
-compat_etree_Element = etree.Element
-compat_etree_register_namespace = etree.register_namespace
+compat_cookiejar_Cookie = http.cookiejar.Cookie
+compat_cookies_SimpleCookie = http.cookies.SimpleCookie
compat_get_terminal_size = shutil.get_terminal_size
compat_getenv = os.getenv
compat_getpass = getpass.getpass
compat_html_entities = html.entities
-compat_html_entities_html5 = compat_html_entities.html5
+compat_html_entities_html5 = html.entities.html5
+compat_HTMLParser = html.parser.HTMLParser
compat_http_client = http.client
compat_http_server = http.server
+compat_HTTPError = urllib.error.HTTPError
compat_itertools_count = itertools.count
compat_parse_qs = urllib.parse.parse_qs
-compat_shlex_split = shlex.split
-compat_socket_create_connection = socket.create_connection
+compat_str = str
compat_struct_pack = struct.pack
compat_struct_unpack = struct.unpack
-compat_subprocess_get_DEVNULL = lambda: DEVNULL
compat_tokenize_tokenize = tokenize.tokenize
compat_urllib_error = urllib.error
-compat_urllib_parse = urllib.parse
-compat_urllib_parse_quote = urllib.parse.quote
-compat_urllib_parse_quote_plus = urllib.parse.quote_plus
compat_urllib_parse_unquote = urllib.parse.unquote
compat_urllib_parse_unquote_plus = urllib.parse.unquote_plus
-compat_urllib_parse_unquote_to_bytes = urllib.parse.unquote_to_bytes
compat_urllib_parse_urlencode = urllib.parse.urlencode
compat_urllib_parse_urlparse = urllib.parse.urlparse
-compat_urllib_parse_urlunparse = urllib.parse.urlunparse
compat_urllib_request = urllib.request
+compat_urlparse = compat_urllib_parse = urllib.parse
+
+
+# To be removed
+
+compat_basestring = str
+compat_collections_abc = collections.abc
+compat_cookies = http.cookies
+compat_etree_Element = etree.Element
+compat_etree_register_namespace = etree.register_namespace
+compat_filter = filter
+compat_input = input
+compat_integer_types = (int, )
+compat_kwargs = lambda kwargs: kwargs
+compat_map = map
+compat_numeric_types = (int, float, complex)
+compat_print = print
+compat_shlex_split = shlex.split
+compat_socket_create_connection = socket.create_connection
+compat_Struct = struct.Struct
+compat_subprocess_get_DEVNULL = lambda: DEVNULL
+compat_urllib_parse_quote = urllib.parse.quote
+compat_urllib_parse_quote_plus = urllib.parse.quote_plus
+compat_urllib_parse_unquote_to_bytes = urllib.parse.unquote_to_bytes
+compat_urllib_parse_urlunparse = urllib.parse.urlunparse
compat_urllib_request_DataHandler = urllib.request.DataHandler
compat_urllib_response = urllib.response
-compat_urlparse = urllib.parse
compat_urlretrieve = urllib.request.urlretrieve
compat_xml_parse_error = etree.ParseError
+compat_xpath = lambda xpath: xpath
+compat_zip = zip
+workaround_optparse_bug9161 = lambda: None
# Set public objects
__all__ = [
+ 'WINDOWS_VT_MODE',
'compat_HTMLParseError',
'compat_HTMLParser',
'compat_HTTPError',
'compat_asyncio_run',
'compat_b64decode',
'compat_basestring',
+ 'compat_brotli',
'compat_chr',
+ 'compat_collections_abc',
'compat_cookiejar',
'compat_cookiejar_Cookie',
'compat_cookies',
'compat_etree_fromstring',
'compat_etree_register_namespace',
'compat_expanduser',
+ 'compat_filter',
'compat_get_terminal_size',
'compat_getenv',
'compat_getpass',
'compat_integer_types',
'compat_itertools_count',
'compat_kwargs',
+ 'compat_map',
'compat_numeric_types',
'compat_ord',
'compat_os_name',
'compat_parse_qs',
'compat_print',
+ 'compat_pycrypto_AES',
'compat_realpath',
'compat_setenv',
'compat_shlex_quote',
'compat_urllib_response',
'compat_urlparse',
'compat_urlretrieve',
+ 'compat_websockets',
'compat_xml_parse_error',
'compat_xpath',
'compat_zip',
+ 'windows_enable_vt_mode',
'workaround_optparse_bug9161',
]