]>
Commit | Line | Data |
---|---|---|
dfe5fa49 | 1 | # coding: utf-8 |
451948b2 | 2 | |
c634ad2a | 3 | import asyncio |
f206126d | 4 | import base64 |
d7cd9a9e | 5 | import ctypes |
8c25f81b | 6 | import getpass |
c634ad2a | 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 | |
2384f5a6 | 14 | import itertools |
e07e9313 | 15 | import optparse |
8c25f81b | 16 | import os |
7d4111ed | 17 | import re |
51f579b6 | 18 | import shlex |
003c69a8 | 19 | import shutil |
be4a824d | 20 | import socket |
dab0daee | 21 | import struct |
8c25f81b | 22 | import sys |
c634ad2a | 23 | import tokenize |
24 | import urllib | |
25 | import xml.etree.ElementTree as etree | |
26 | from subprocess import DEVNULL | |
72b40955 | 27 | |
72b40955 | 28 | |
c634ad2a | 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 | |
15707c7e | 34 | |
15707c7e | 35 | |
c634ad2a | 36 | def compat_ctypes_WINFUNCTYPE(*args, **kwargs): |
37 | return ctypes.WINFUNCTYPE(*args, **kwargs) | |
eb7941e3 YCH |
38 | |
39 | ||
40 | class _TreeBuilder(etree.TreeBuilder): | |
41 | def doctype(self, name, pubid, system): | |
42 | pass | |
43 | ||
582be358 | 44 | |
c634ad2a | 45 | def compat_etree_fromstring(text): |
46 | return etree.XML(text, parser=etree.XMLParser(target=_TreeBuilder())) | |
8c25f81b | 47 | |
b08e235f S |
48 | |
49 | compat_os_name = os._name if os.name == 'java' else os.name | |
50 | ||
51 | ||
52 | if compat_os_name == 'nt': | |
702ccf2d | 53 | def compat_shlex_quote(s): |
b08e235f S |
54 | return s if re.match(r'^[-_\w./]+$', s) else '"%s"' % s.replace('"', '\\"') |
55 | else: | |
c634ad2a | 56 | from shlex import quote as compat_shlex_quote |
51f579b6 S |
57 | |
58 | ||
8c25f81b | 59 | def compat_ord(c): |
5f6a1245 JW |
60 | if type(c) is int: |
61 | return c | |
62 | else: | |
63 | return ord(c) | |
8c25f81b PH |
64 | |
65 | ||
c634ad2a | 66 | def compat_setenv(key, value, env=os.environ): |
67 | env[key] = value | |
8c25f81b PH |
68 | |
69 | ||
82fea5b4 S |
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 | ||
c634ad2a | 81 | def compat_print(s): |
82 | assert isinstance(s, compat_str) | |
83 | print(s) | |
be4a824d PH |
84 | |
85 | ||
067aa17e | 86 | # Fix https://github.com/ytdl-org/youtube-dl/issues/4223 |
e07e9313 PH |
87 | # See http://bugs.python.org/issue9161 for what is broken |
88 | def workaround_optparse_bug9161(): | |
07e378fa PH |
89 | op = optparse.OptionParser() |
90 | og = optparse.OptionGroup(op, 'foo') | |
e07e9313 | 91 | try: |
07e378fa | 92 | og.add_option('-t') |
b244b5c3 | 93 | except TypeError: |
e07e9313 PH |
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 | ||
582be358 | 106 | |
4a2f19ab F |
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 | ||
e36d50c5 | 119 | try: |
c634ad2a | 120 | compat_asyncio_run = asyncio.run # >= 3.7 |
e36d50c5 | 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 | ||
c634ad2a | 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 | ||
8c25f81b | 191 | __all__ = [ |
b081f53b | 192 | 'compat_HTMLParseError', |
8bb56eee | 193 | 'compat_HTMLParser', |
8c25f81b | 194 | 'compat_HTTPError', |
4a2f19ab F |
195 | 'compat_Match', |
196 | 'compat_Pattern', | |
65220c3b | 197 | 'compat_Struct', |
e36d50c5 | 198 | 'compat_asyncio_run', |
f206126d | 199 | 'compat_b64decode', |
0196149c | 200 | 'compat_basestring', |
8c25f81b PH |
201 | 'compat_chr', |
202 | 'compat_cookiejar', | |
6d874fee | 203 | 'compat_cookiejar_Cookie', |
799207e8 | 204 | 'compat_cookies', |
f7ad7160 | 205 | 'compat_cookies_SimpleCookie', |
d7cd9a9e | 206 | 'compat_ctypes_WINFUNCTYPE', |
399f7687 | 207 | 'compat_etree_Element', |
36e6f62c | 208 | 'compat_etree_fromstring', |
da162c11 | 209 | 'compat_etree_register_namespace', |
8c25f81b | 210 | 'compat_expanduser', |
003c69a8 | 211 | 'compat_get_terminal_size', |
8c25f81b PH |
212 | 'compat_getenv', |
213 | 'compat_getpass', | |
214 | 'compat_html_entities', | |
9631a94f | 215 | 'compat_html_entities_html5', |
8c25f81b | 216 | 'compat_http_client', |
83fda3c0 | 217 | 'compat_http_server', |
e67f6880 | 218 | 'compat_input', |
075a13d3 | 219 | 'compat_integer_types', |
a0e060ac | 220 | 'compat_itertools_count', |
c7b0add8 | 221 | 'compat_kwargs', |
28572a1a | 222 | 'compat_numeric_types', |
8c25f81b | 223 | 'compat_ord', |
e9c0cdd3 | 224 | 'compat_os_name', |
8c25f81b PH |
225 | 'compat_parse_qs', |
226 | 'compat_print', | |
bfe2b8cf | 227 | 'compat_realpath', |
fe40f9ee | 228 | 'compat_setenv', |
702ccf2d | 229 | 'compat_shlex_quote', |
51f579b6 | 230 | 'compat_shlex_split', |
be4a824d | 231 | 'compat_socket_create_connection', |
987493ae | 232 | 'compat_str', |
edaa23f8 YCH |
233 | 'compat_struct_pack', |
234 | 'compat_struct_unpack', | |
8c25f81b | 235 | 'compat_subprocess_get_DEVNULL', |
67134eab | 236 | 'compat_tokenize_tokenize', |
8c25f81b PH |
237 | 'compat_urllib_error', |
238 | 'compat_urllib_parse', | |
732044af | 239 | 'compat_urllib_parse_quote', |
240 | 'compat_urllib_parse_quote_plus', | |
8c25f81b | 241 | 'compat_urllib_parse_unquote', |
aa99aa4e | 242 | 'compat_urllib_parse_unquote_plus', |
9fefc886 | 243 | 'compat_urllib_parse_unquote_to_bytes', |
15707c7e | 244 | 'compat_urllib_parse_urlencode', |
8c25f81b | 245 | 'compat_urllib_parse_urlparse', |
732044af | 246 | 'compat_urllib_parse_urlunparse', |
8c25f81b | 247 | 'compat_urllib_request', |
0a67a363 YCH |
248 | 'compat_urllib_request_DataHandler', |
249 | 'compat_urllib_response', | |
8c25f81b PH |
250 | 'compat_urlparse', |
251 | 'compat_urlretrieve', | |
252 | 'compat_xml_parse_error', | |
57f7e3c6 | 253 | 'compat_xpath', |
2384f5a6 | 254 | 'compat_zip', |
e07e9313 | 255 | 'workaround_optparse_bug9161', |
8c25f81b | 256 | ] |