]> jfr.im git - yt-dlp.git/blob - yt_dlp/compat.py
[cleanup] Misc
[yt-dlp.git] / yt_dlp / compat.py
1 # coding: utf-8
2
3 import asyncio
4 import base64
5 import ctypes
6 import getpass
7 import html
8 import html.parser
9 import http
10 import http.client
11 import http.cookiejar
12 import http.cookies
13 import http.server
14 import itertools
15 import optparse
16 import os
17 import re
18 import shlex
19 import shutil
20 import socket
21 import struct
22 import sys
23 import tokenize
24 import urllib
25 import xml.etree.ElementTree as etree
26 from subprocess import DEVNULL
27
28
29 # HTMLParseError has been deprecated in Python 3.3 and removed in
30 # Python 3.5. Introducing dummy exception for Python >3.5 for compatible
31 # and uniform cross-version exception handling
32 class compat_HTMLParseError(Exception):
33 pass
34
35
36 def compat_ctypes_WINFUNCTYPE(*args, **kwargs):
37 return ctypes.WINFUNCTYPE(*args, **kwargs)
38
39
40 class _TreeBuilder(etree.TreeBuilder):
41 def doctype(self, name, pubid, system):
42 pass
43
44
45 def compat_etree_fromstring(text):
46 return etree.XML(text, parser=etree.XMLParser(target=_TreeBuilder()))
47
48
49 compat_os_name = os._name if os.name == 'java' else os.name
50
51
52 if compat_os_name == 'nt':
53 def compat_shlex_quote(s):
54 return s if re.match(r'^[-_\w./]+$', s) else '"%s"' % s.replace('"', '\\"')
55 else:
56 from shlex import quote as compat_shlex_quote
57
58
59 def compat_ord(c):
60 if type(c) is int:
61 return c
62 else:
63 return ord(c)
64
65
66 def compat_setenv(key, value, env=os.environ):
67 env[key] = value
68
69
70 if compat_os_name == 'nt' and sys.version_info < (3, 8):
71 # os.path.realpath on Windows does not follow symbolic links
72 # prior to Python 3.8 (see https://bugs.python.org/issue9949)
73 def compat_realpath(path):
74 while os.path.islink(path):
75 path = os.path.abspath(os.readlink(path))
76 return path
77 else:
78 compat_realpath = os.path.realpath
79
80
81 def compat_print(s):
82 assert isinstance(s, compat_str)
83 print(s)
84
85
86 # Fix https://github.com/ytdl-org/youtube-dl/issues/4223
87 # See http://bugs.python.org/issue9161 for what is broken
88 def workaround_optparse_bug9161():
89 op = optparse.OptionParser()
90 og = optparse.OptionGroup(op, 'foo')
91 try:
92 og.add_option('-t')
93 except TypeError:
94 real_add_option = optparse.OptionGroup.add_option
95
96 def _compat_add_option(self, *args, **kwargs):
97 enc = lambda v: (
98 v.encode('ascii', 'replace') if isinstance(v, compat_str)
99 else v)
100 bargs = [enc(a) for a in args]
101 bkwargs = dict(
102 (k, enc(v)) for k, v in kwargs.items())
103 return real_add_option(self, *bargs, **bkwargs)
104 optparse.OptionGroup.add_option = _compat_add_option
105
106
107 try:
108 compat_Pattern = re.Pattern
109 except AttributeError:
110 compat_Pattern = type(re.compile(''))
111
112
113 try:
114 compat_Match = re.Match
115 except AttributeError:
116 compat_Match = type(re.compile('').match(''))
117
118
119 try:
120 compat_asyncio_run = asyncio.run # >= 3.7
121 except AttributeError:
122 def compat_asyncio_run(coro):
123 try:
124 loop = asyncio.get_event_loop()
125 except RuntimeError:
126 loop = asyncio.new_event_loop()
127 asyncio.set_event_loop(loop)
128 loop.run_until_complete(coro)
129
130 asyncio.run = compat_asyncio_run
131
132
133 # Deprecated
134
135 compat_basestring = str
136 compat_chr = chr
137 compat_input = input
138 compat_integer_types = (int, )
139 compat_kwargs = lambda kwargs: kwargs
140 compat_numeric_types = (int, float, complex)
141 compat_str = str
142 compat_xpath = lambda xpath: xpath
143 compat_zip = zip
144
145 compat_HTMLParser = html.parser.HTMLParser
146 compat_HTTPError = urllib.error.HTTPError
147 compat_Struct = struct.Struct
148 compat_b64decode = base64.b64decode
149 compat_cookiejar = http.cookiejar
150 compat_cookiejar_Cookie = compat_cookiejar.Cookie
151 compat_cookies = http.cookies
152 compat_cookies_SimpleCookie = compat_cookies.SimpleCookie
153 compat_etree_Element = etree.Element
154 compat_etree_register_namespace = etree.register_namespace
155 compat_expanduser = os.path.expanduser
156 compat_get_terminal_size = shutil.get_terminal_size
157 compat_getenv = os.getenv
158 compat_getpass = getpass.getpass
159 compat_html_entities = html.entities
160 compat_html_entities_html5 = compat_html_entities.html5
161 compat_http_client = http.client
162 compat_http_server = http.server
163 compat_itertools_count = itertools.count
164 compat_parse_qs = urllib.parse.parse_qs
165 compat_shlex_split = shlex.split
166 compat_socket_create_connection = socket.create_connection
167 compat_struct_pack = struct.pack
168 compat_struct_unpack = struct.unpack
169 compat_subprocess_get_DEVNULL = lambda: DEVNULL
170 compat_tokenize_tokenize = tokenize.tokenize
171 compat_urllib_error = urllib.error
172 compat_urllib_parse = urllib.parse
173 compat_urllib_parse_quote = urllib.parse.quote
174 compat_urllib_parse_quote_plus = urllib.parse.quote_plus
175 compat_urllib_parse_unquote = urllib.parse.unquote
176 compat_urllib_parse_unquote_plus = urllib.parse.unquote_plus
177 compat_urllib_parse_unquote_to_bytes = urllib.parse.unquote_to_bytes
178 compat_urllib_parse_urlencode = urllib.parse.urlencode
179 compat_urllib_parse_urlparse = urllib.parse.urlparse
180 compat_urllib_parse_urlunparse = urllib.parse.urlunparse
181 compat_urllib_request = urllib.request
182 compat_urllib_request_DataHandler = urllib.request.DataHandler
183 compat_urllib_response = urllib.response
184 compat_urlparse = urllib.parse
185 compat_urlretrieve = urllib.request.urlretrieve
186 compat_xml_parse_error = etree.ParseError
187
188
189 # Set public objects
190
191 __all__ = [
192 'compat_HTMLParseError',
193 'compat_HTMLParser',
194 'compat_HTTPError',
195 'compat_Match',
196 'compat_Pattern',
197 'compat_Struct',
198 'compat_asyncio_run',
199 'compat_b64decode',
200 'compat_basestring',
201 'compat_chr',
202 'compat_cookiejar',
203 'compat_cookiejar_Cookie',
204 'compat_cookies',
205 'compat_cookies_SimpleCookie',
206 'compat_ctypes_WINFUNCTYPE',
207 'compat_etree_Element',
208 'compat_etree_fromstring',
209 'compat_etree_register_namespace',
210 'compat_expanduser',
211 'compat_get_terminal_size',
212 'compat_getenv',
213 'compat_getpass',
214 'compat_html_entities',
215 'compat_html_entities_html5',
216 'compat_http_client',
217 'compat_http_server',
218 'compat_input',
219 'compat_integer_types',
220 'compat_itertools_count',
221 'compat_kwargs',
222 'compat_numeric_types',
223 'compat_ord',
224 'compat_os_name',
225 'compat_parse_qs',
226 'compat_print',
227 'compat_realpath',
228 'compat_setenv',
229 'compat_shlex_quote',
230 'compat_shlex_split',
231 'compat_socket_create_connection',
232 'compat_str',
233 'compat_struct_pack',
234 'compat_struct_unpack',
235 'compat_subprocess_get_DEVNULL',
236 'compat_tokenize_tokenize',
237 'compat_urllib_error',
238 'compat_urllib_parse',
239 'compat_urllib_parse_quote',
240 'compat_urllib_parse_quote_plus',
241 'compat_urllib_parse_unquote',
242 'compat_urllib_parse_unquote_plus',
243 'compat_urllib_parse_unquote_to_bytes',
244 'compat_urllib_parse_urlencode',
245 'compat_urllib_parse_urlparse',
246 'compat_urllib_parse_urlunparse',
247 'compat_urllib_request',
248 'compat_urllib_request_DataHandler',
249 'compat_urllib_response',
250 'compat_urlparse',
251 'compat_urlretrieve',
252 'compat_xml_parse_error',
253 'compat_xpath',
254 'compat_zip',
255 'workaround_optparse_bug9161',
256 ]