aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/helper.py2
-rw-r--r--test/test_execution.py3
-rw-r--r--test/test_http.py29
-rw-r--r--test/test_utils.py3
-rw-r--r--yt_dlp/YoutubeDL.py6
-rw-r--r--yt_dlp/__init__.py9
-rw-r--r--yt_dlp/__main__.py3
-rw-r--r--yt_dlp/compat.py24
-rw-r--r--yt_dlp/extractor/bpb.py1
-rw-r--r--yt_dlp/extractor/common.py4
-rw-r--r--yt_dlp/extractor/commonmistakes.py6
-rw-r--r--yt_dlp/extractor/generic.py4
-rw-r--r--yt_dlp/update.py36
-rw-r--r--yt_dlp/utils.py247
14 files changed, 32 insertions, 345 deletions
diff --git a/test/helper.py b/test/helper.py
index 28c21b2eb..804e954a3 100644
--- a/test/helper.py
+++ b/test/helper.py
@@ -64,7 +64,7 @@ def report_warning(message):
else:
_msg_header = 'WARNING:'
output = '%s %s\n' % (_msg_header, message)
- if 'b' in getattr(sys.stderr, 'mode', '') or sys.version_info[0] < 3:
+ if 'b' in getattr(sys.stderr, 'mode', ''):
output = output.encode(preferredencoding())
sys.stderr.write(output)
diff --git a/test/test_execution.py b/test/test_execution.py
index cf6b6b913..4981786e1 100644
--- a/test/test_execution.py
+++ b/test/test_execution.py
@@ -26,8 +26,7 @@ class TestExecution(unittest.TestCase):
subprocess.check_call([sys.executable, '-c', 'import yt_dlp'], cwd=rootDir)
def test_module_exec(self):
- if sys.version_info >= (2, 7): # Python 2.6 doesn't support package execution
- subprocess.check_call([sys.executable, '-m', 'yt_dlp', '--version'], cwd=rootDir, stdout=_DEV_NULL)
+ subprocess.check_call([sys.executable, '-m', 'yt_dlp', '--version'], cwd=rootDir, stdout=_DEV_NULL)
def test_main_exec(self):
subprocess.check_call([sys.executable, 'yt_dlp/__main__.py', '--version'], cwd=rootDir, stdout=_DEV_NULL)
diff --git a/test/test_http.py b/test/test_http.py
index 40df167e0..eec8684b1 100644
--- a/test/test_http.py
+++ b/test/test_http.py
@@ -32,17 +32,6 @@ class HTTPTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
self.send_header('Content-Type', 'video/mp4')
self.end_headers()
self.wfile.write(b'\x00\x00\x00\x00\x20\x66\x74[video]')
- elif self.path == '/302':
- if sys.version_info[0] == 3:
- # XXX: Python 3 http server does not allow non-ASCII header values
- self.send_response(404)
- self.end_headers()
- return
-
- new_url = 'http://127.0.0.1:%d/中文.html' % http_server_port(self.server)
- self.send_response(302)
- self.send_header(b'Location', new_url.encode('utf-8'))
- self.end_headers()
elif self.path == '/%E4%B8%AD%E6%96%87.html':
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
@@ -72,15 +61,6 @@ class TestHTTP(unittest.TestCase):
self.server_thread.daemon = True
self.server_thread.start()
- def test_unicode_path_redirection(self):
- # XXX: Python 3 http server does not allow non-ASCII header values
- if sys.version_info[0] == 3:
- return
-
- ydl = YoutubeDL({'logger': FakeLogger()})
- r = ydl.extract_info('http://127.0.0.1:%d/302' % self.port)
- self.assertEqual(r['entries'][0]['url'], 'http://127.0.0.1:%d/vid.mp4' % self.port)
-
class TestHTTPS(unittest.TestCase):
def setUp(self):
@@ -95,11 +75,10 @@ class TestHTTPS(unittest.TestCase):
self.server_thread.start()
def test_nocheckcertificate(self):
- if sys.version_info >= (2, 7, 9): # No certificate checking anyways
- ydl = YoutubeDL({'logger': FakeLogger()})
- self.assertRaises(
- Exception,
- ydl.extract_info, 'https://127.0.0.1:%d/video.html' % self.port)
+ ydl = YoutubeDL({'logger': FakeLogger()})
+ self.assertRaises(
+ Exception,
+ ydl.extract_info, 'https://127.0.0.1:%d/video.html' % self.port)
ydl = YoutubeDL({'logger': FakeLogger(), 'nocheckcertificate': True})
r = ydl.extract_info('https://127.0.0.1:%d/video.html' % self.port)
diff --git a/test/test_utils.py b/test/test_utils.py
index 1f826c2f2..c1228c74a 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -538,9 +538,6 @@ class TestUtil(unittest.TestCase):
self.assertEqual(str_to_int('123,456'), 123456)
self.assertEqual(str_to_int('123.456'), 123456)
self.assertEqual(str_to_int(523), 523)
- # Python 3 has no long
- if sys.version_info < (3, 0):
- eval('self.assertEqual(str_to_int(123456L), 123456)')
self.assertEqual(str_to_int('noninteger'), None)
self.assertEqual(str_to_int([]), None)
diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py
index fef05d517..c626ea3fd 100644
--- a/yt_dlp/YoutubeDL.py
+++ b/yt_dlp/YoutubeDL.py
@@ -1008,12 +1008,6 @@ class YoutubeDL(object):
expand_path(paths.get('home', '').strip()),
expand_path(paths.get(dir_type, '').strip()) if dir_type else '',
filename or '')
-
- # Temporary fix for #4787
- # 'Treat' all problem characters by passing filename through preferredencoding
- # to workaround encoding issues with subprocess on python2 @ Windows
- if sys.version_info < (3, 0) and sys.platform == 'win32':
- path = encodeFilename(path, True).decode(preferredencoding())
return sanitize_path(path, force=self.params.get('windowsfilenames'))
@staticmethod
diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py
index ebf2d227a..10dc221b4 100644
--- a/yt_dlp/__init__.py
+++ b/yt_dlp/__init__.py
@@ -5,7 +5,6 @@ f'You are using an unsupported version of Python. Only Python versions 3.6 and a
__license__ = 'Public Domain'
-import codecs
import io
import itertools
import os
@@ -18,7 +17,6 @@ from .compat import (
compat_getpass,
compat_os_name,
compat_shlex_quote,
- workaround_optparse_bug9161,
)
from .cookies import SUPPORTED_BROWSERS, SUPPORTED_KEYRINGS
from .utils import (
@@ -807,13 +805,6 @@ def parse_options(argv=None):
def _real_main(argv=None):
- # Compatibility fixes for Windows
- if sys.platform == 'win32':
- # https://github.com/ytdl-org/youtube-dl/issues/820
- codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
-
- workaround_optparse_bug9161()
-
setproctitle('yt-dlp')
parser, opts, all_urls, ydl_opts = parse_options(argv)
diff --git a/yt_dlp/__main__.py b/yt_dlp/__main__.py
index c9f41473d..fb2726bd3 100644
--- a/yt_dlp/__main__.py
+++ b/yt_dlp/__main__.py
@@ -2,8 +2,7 @@
from __future__ import unicode_literals
# Execute with
-# $ python yt_dlp/__main__.py (2.6+)
-# $ python -m yt_dlp (2.7+)
+# $ python -m yt_dlp
import sys
diff --git a/yt_dlp/compat.py b/yt_dlp/compat.py
index 0a0d3b351..6128ff524 100644
--- a/yt_dlp/compat.py
+++ b/yt_dlp/compat.py
@@ -13,7 +13,6 @@ import http.cookiejar
import http.cookies
import http.server
import itertools
-import optparse
import os
import re
import shlex
@@ -86,28 +85,6 @@ 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:
@@ -207,6 +184,7 @@ compat_numeric_types = (int, float, complex)
compat_str = str
compat_xpath = lambda xpath: xpath
compat_zip = zip
+workaround_optparse_bug9161 = lambda: None
compat_collections_abc = collections.abc
compat_HTMLParser = html.parser.HTMLParser
diff --git a/yt_dlp/extractor/bpb.py b/yt_dlp/extractor/bpb.py
index 8f6ef3cf0..98491975c 100644
--- a/yt_dlp/extractor/bpb.py
+++ b/yt_dlp/extractor/bpb.py
@@ -16,7 +16,6 @@ class BpbIE(InfoExtractor):
_TEST = {
'url': 'http://www.bpb.de/mediathek/297/joachim-gauck-zu-1989-und-die-erinnerung-an-die-ddr',
- # md5 fails in Python 2.6 due to buggy server response and wrong handling of urllib2
'md5': 'c4f84c8a8044ca9ff68bb8441d300b3f',
'info_dict': {
'id': '297',
diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py
index 9914910d0..48f302f86 100644
--- a/yt_dlp/extractor/common.py
+++ b/yt_dlp/extractor/common.py
@@ -3606,9 +3606,7 @@ class InfoExtractor(object):
for header, cookies in url_handle.headers.items():
if header.lower() != 'set-cookie':
continue
- if sys.version_info[0] >= 3:
- cookies = cookies.encode('iso-8859-1')
- cookies = cookies.decode('utf-8')
+ cookies = cookies.encode('iso-8859-1').decode('utf-8')
cookie_value = re.search(
r'%s=(.+?);.*?\b[Dd]omain=(.+?)(?:[,;]|$)' % cookie, cookies)
if cookie_value:
diff --git a/yt_dlp/extractor/commonmistakes.py b/yt_dlp/extractor/commonmistakes.py
index 051269652..e0a9f5956 100644
--- a/yt_dlp/extractor/commonmistakes.py
+++ b/yt_dlp/extractor/commonmistakes.py
@@ -1,7 +1,5 @@
from __future__ import unicode_literals
-import sys
-
from .common import InfoExtractor
from ..utils import ExtractorError
@@ -35,9 +33,7 @@ class UnicodeBOMIE(InfoExtractor):
IE_DESC = False
_VALID_URL = r'(?P<bom>\ufeff)(?P<id>.*)$'
- # Disable test for python 3.2 since BOM is broken in re in this version
- # (see https://github.com/ytdl-org/youtube-dl/issues/9751)
- _TESTS = [] if (3, 0) < sys.version_info <= (3, 3) else [{
+ _TESTS = [{
'url': '\ufeffhttp://www.youtube.com/watch?v=BaW_jenozKc',
'only_matching': True,
}]
diff --git a/yt_dlp/extractor/generic.py b/yt_dlp/extractor/generic.py
index bd56ad289..f11fc844d 100644
--- a/yt_dlp/extractor/generic.py
+++ b/yt_dlp/extractor/generic.py
@@ -4,7 +4,6 @@ from __future__ import unicode_literals
import os
import re
-import sys
from .common import InfoExtractor
from .youtube import YoutubeIE
@@ -4011,9 +4010,6 @@ class GenericIE(InfoExtractor):
# Look also in Refresh HTTP header
refresh_header = head_response.headers.get('Refresh')
if refresh_header:
- # In python 2 response HTTP headers are bytestrings
- if sys.version_info < (3, 0) and isinstance(refresh_header, str):
- refresh_header = refresh_header.decode('iso-8859-1')
found = re.search(REDIRECT_REGEX, refresh_header)
if found:
new_url = compat_urlparse.urljoin(url, unescapeHTML(found.group(1)))
diff --git a/yt_dlp/update.py b/yt_dlp/update.py
index a208e163c..f6ac207a1 100644
--- a/yt_dlp/update.py
+++ b/yt_dlp/update.py
@@ -15,22 +15,6 @@ from .utils import encode_compat_str, Popen, write_string
from .version import __version__
-''' # Not signed
-def rsa_verify(message, signature, key):
- from hashlib import sha256
- assert isinstance(message, bytes)
- byte_size = (len(bin(key[0])) - 2 + 8 - 1) // 8
- signature = ('%x' % pow(int(signature, 16), key[1], key[0])).encode()
- signature = (byte_size * 2 - len(signature)) * b'0' + signature
- asn1 = b'3031300d060960864801650304020105000420'
- asn1 += sha256(message).hexdigest().encode()
- if byte_size < len(asn1) // 2 + 11:
- return False
- expected = b'0001' + (byte_size - len(asn1) // 2 - 3) * b'ff' + b'00' + asn1
- return expected == signature
-'''
-
-
def detect_variant():
if hasattr(sys, 'frozen'):
prefix = 'mac' if sys.platform == 'darwin' else 'win'
@@ -39,7 +23,7 @@ def detect_variant():
return f'{prefix}_dir'
return f'{prefix}_exe'
return 'py2exe'
- elif isinstance(globals().get('__loader__'), zipimporter):
+ elif isinstance(__loader__, zipimporter):
return 'zip'
elif os.path.basename(sys.argv[0]) == '__main__.py':
return 'source'
@@ -232,24 +216,6 @@ def run_update(ydl):
assert False, f'Unhandled variant: {variant}'
-''' # UNUSED
-def get_notes(versions, fromVersion):
- notes = []
- for v, vdata in sorted(versions.items()):
- if v > fromVersion:
- notes.extend(vdata.get('notes', []))
- return notes
-
-
-def print_notes(to_screen, versions, fromVersion=__version__):
- notes = get_notes(versions, fromVersion)
- if notes:
- to_screen('PLEASE NOTE:')
- for note in notes:
- to_screen(note)
-'''
-
-
# Deprecated
def update_self(to_screen, verbose, opener):
diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py
index 14dbbf59f..324b54e78 100644
--- a/yt_dlp/utils.py
+++ b/yt_dlp/utils.py
@@ -50,7 +50,6 @@ from .compat import (
compat_brotli,
compat_chr,
compat_cookiejar,
- compat_ctypes_WINFUNCTYPE,
compat_etree_fromstring,
compat_expanduser,
compat_html_entities,
@@ -288,37 +287,9 @@ def preferredencoding():
def write_json_file(obj, fn):
""" Encode obj as JSON and write it to fn, atomically if possible """
- fn = encodeFilename(fn)
- if sys.version_info < (3, 0) and sys.platform != 'win32':
- encoding = get_filesystem_encoding()
- # os.path.basename returns a bytes object, but NamedTemporaryFile
- # will fail if the filename contains non ascii characters unless we
- # use a unicode object
- path_basename = lambda f: os.path.basename(fn).decode(encoding)
- # the same for os.path.dirname
- path_dirname = lambda f: os.path.dirname(fn).decode(encoding)
- else:
- path_basename = os.path.basename
- path_dirname = os.path.dirname
-
- args = {
- 'suffix': '.tmp',
- 'prefix': path_basename(fn) + '.',
- 'dir': path_dirname(fn),
- 'delete': False,
- }
-
- # In Python 2.x, json.dump expects a bytestream.
- # In Python 3.x, it writes to a character stream
- if sys.version_info < (3, 0):
- args['mode'] = 'wb'
- else:
- args.update({
- 'mode': 'w',
- 'encoding': 'utf-8',
- })
-
- tf = tempfile.NamedTemporaryFile(**compat_kwargs(args))
+ tf = tempfile.NamedTemporaryFile(
+ prefix=f'{os.path.basename(fn)}.', dir=os.path.dirname(fn),
+ suffix='.tmp', delete=False, mode='w', encoding='utf-8')
try:
with tf:
@@ -345,20 +316,11 @@ def write_json_file(obj, fn):
raise
-if sys.version_info >= (2, 7):
- def find_xpath_attr(node, xpath, key, val=None):
- """ Find the xpath xpath[@key=val] """
- assert re.match(r'^[a-zA-Z_-]+$', key)
- expr = xpath + ('[@%s]' % key if val is None else "[@%s='%s']" % (key, val))
- return node.find(expr)
-else:
- def find_xpath_attr(node, xpath, key, val=None):
- for f in node.findall(compat_xpath(xpath)):
- if key not in f.attrib:
- continue
- if val is None or f.attrib.get(key) == val:
- return f
- return None
+def find_xpath_attr(node, xpath, key, val=None):
+ """ Find the xpath xpath[@key=val] """
+ assert re.match(r'^[a-zA-Z_-]+$', key)
+ expr = xpath + ('[@%s]' % key if val is None else "[@%s='%s']" % (key, val))
+ return node.find(expr)
# On python2.6 the xml.etree.ElementTree.Element methods don't support
# the namespace parameter
@@ -626,8 +588,6 @@ def extract_attributes(html_element):
'empty': '', 'noval': None, 'entity': '&',
'sq': '"', 'dq': '\''
}.
- NB HTMLParser is stricter in Python 2.6 & 3.2 than in later versions,
- but the cases in the unit test will work for all of 2.6, 2.7, 3.2-3.5.
"""
parser = HTMLAttributeParser()
try:
@@ -763,8 +723,6 @@ def sanitize_path(s, force=False):
if sys.platform == 'win32':
force = False
drive_or_unc, _ = os.path.splitdrive(s)
- if sys.version_info < (2, 7) and not drive_or_unc:
- drive_or_unc, _ = os.path.splitunc(s)
elif force:
drive_or_unc = ''
else:
@@ -922,51 +880,23 @@ def get_subprocess_encoding():
def encodeFilename(s, for_subprocess=False):
- """
- @param s The name of the file
- """
-
- assert type(s) == compat_str
-
- # Python 3 has a Unicode API
- if sys.version_info >= (3, 0):
- return s
-
- # Pass '' directly to use Unicode APIs on Windows 2000 and up
- # (Detecting Windows NT 4 is tricky because 'major >= 4' would
- # match Windows 9x series as well. Besides, NT 4 is obsolete.)
- if not for_subprocess and sys.platform == 'win32' and sys.getwindowsversion()[0] >= 5:
- return s
-
- # Jython assumes filenames are Unicode strings though reported as Python 2.x compatible
- if sys.platform.startswith('java'):
- return s
-
- return s.encode(get_subprocess_encoding(), 'ignore')
+ assert type(s) == str
+ return s
def decodeFilename(b, for_subprocess=False):
-
- if sys.version_info >= (3, 0):
- return b
-
- if not isinstance(b, bytes):
- return b
-
- return b.decode(get_subprocess_encoding(), 'ignore')
+ return b
def encodeArgument(s):
- if not isinstance(s, compat_str):
- # Legacy code that uses byte strings
- # Uncomment the following line after fixing all post processors
- # assert False, 'Internal error: %r should be of type %r, is %r' % (s, compat_str, type(s))
- s = s.decode('ascii')
- return encodeFilename(s, True)
+ # Legacy code that uses byte strings
+ # Uncomment the following line after fixing all post processors
+ # assert isinstance(s, str), 'Internal error: %r should be of type %r, is %r' % (s, compat_str, type(s))
+ return s if isinstance(s, str) else s.decode('ascii')
def decodeArgument(b):
- return decodeFilename(b, True)
+ return b
def decodeOption(optval):
@@ -1263,11 +1193,6 @@ class XAttrUnavailableError(YoutubeDLError):
def _create_http_connection(ydl_handler, http_class, is_https, *args, **kwargs):
- # Working around python 2 bug (see http://bugs.python.org/issue17849) by limiting
- # expected HTTP responses to meet HTTP/1.0 or later (see also
- # https://github.com/ytdl-org/youtube-dl/issues/6727)
- if sys.version_info < (3, 0):
- kwargs['strict'] = True
hc = http_class(*args, **compat_kwargs(kwargs))
source_address = ydl_handler._params.get('source_address')
@@ -1309,20 +1234,7 @@ def _create_http_connection(ydl_handler, http_class, is_https, *args, **kwargs):
raise socket.error('getaddrinfo returns an empty list')
if hasattr(hc, '_create_connection'):
hc._create_connection = _create_connection
- sa = (source_address, 0)
- if hasattr(hc, 'source_address'): # Python 2.7+
- hc.source_address = sa
- else: # Python 2.6
- def _hc_connect(self, *args, **kwargs):
- sock = _create_connection(
- (self.host, self.port), self.timeout, sa)
- if is_https:
- self.sock = ssl.wrap_socket(
- sock, self.key_file, self.cert_file,
- ssl_version=ssl.PROTOCOL_TLSv1)
- else:
- self.sock = sock
- hc.connect = functools.partial(_hc_connect, hc)
+ hc.source_address = (source_address, 0)
return hc
@@ -1413,11 +1325,6 @@ class YoutubeDLHandler(compat_urllib_request.HTTPHandler):
req.headers = handle_youtubedl_headers(req.headers)
- if sys.version_info < (2, 7) and '#' in req.get_full_url():
- # Python 2.6 is brain-dead when it comes to fragments
- req._Request__original = req._Request__original.partition('#')[0]
- req._Request__r_type = req._Request__r_type.partition('#')[0]
-
return req
def http_response(self, req, resp):
@@ -1461,15 +1368,10 @@ class YoutubeDLHandler(compat_urllib_request.HTTPHandler):
location = resp.headers.get('Location')
if location:
# As of RFC 2616 default charset is iso-8859-1 that is respected by python 3
- if sys.version_info >= (3, 0):
- location = location.encode('iso-8859-1').decode('utf-8')
- else:
- location = location.decode('utf-8')
+ location = location.encode('iso-8859-1').decode('utf-8')
location_escaped = escape_url(location)
if location != location_escaped:
del resp.headers['Location']
- if sys.version_info < (3, 0):
- location_escaped = location_escaped.encode('utf-8')
resp.headers['Location'] = location_escaped
return resp
@@ -1668,19 +1570,6 @@ class YoutubeDLCookieProcessor(compat_urllib_request.HTTPCookieProcessor):
compat_urllib_request.HTTPCookieProcessor.__init__(self, cookiejar)
def http_response(self, request, response):
- # Python 2 will choke on next HTTP request in row if there are non-ASCII
- # characters in Set-Cookie HTTP header of last response (see
- # https://github.com/ytdl-org/youtube-dl/issues/6769).
- # In order to at least prevent crashing we will percent encode Set-Cookie
- # header before HTTPCookieProcessor starts processing it.
- # if sys.version_info < (3, 0) and response.headers:
- # for set_cookie_header in ('Set-Cookie', 'Set-Cookie2'):
- # set_cookie = response.headers.get(set_cookie_header)
- # if set_cookie:
- # set_cookie_escaped = compat_urllib_parse.quote(set_cookie, b"%/;:@&=+$,!~*'()?#[] ")
- # if set_cookie != set_cookie_escaped:
- # del response.headers[set_cookie_header]
- # response.headers[set_cookie_header] = set_cookie_escaped
return compat_urllib_request.HTTPCookieProcessor.http_response(self, request, response)
https_request = compat_urllib_request.HTTPCookieProcessor.http_request
@@ -1724,12 +1613,6 @@ class YoutubeDLRedirectHandler(compat_urllib_request.HTTPRedirectHandler):
# essentially all clients do redirect in this case, so we do
# the same.
- # On python 2 urlh.geturl() may sometimes return redirect URL
- # as byte string instead of unicode. This workaround allows
- # to force it always return unicode.
- if sys.version_info[0] < 3:
- newurl = compat_str(newurl)
-
# Be conciliant with URIs containing a space. This is mainly
# redundant with the more complete encoding done in http_error_302(),
# but it is kept for compatibility with other callers.
@@ -2013,91 +1896,12 @@ def get_windows_version():
return None
-def _windows_write_string(s, out):
- """ Returns True if the string was written using special methods,
- False if it has yet to be written out."""
- # Adapted from http://stackoverflow.com/a/3259271/35070
-
- import ctypes.wintypes
-
- WIN_OUTPUT_IDS = {
- 1: -11,
- 2: -12,
- }
-
- try:
- fileno = out.fileno()
- except AttributeError:
- # If the output stream doesn't have a fileno, it's virtual
- return False
- except io.UnsupportedOperation:
- # Some strange Windows pseudo files?
- return False
- if fileno not in WIN_OUTPUT_IDS:
- return False
-
- GetStdHandle = compat_ctypes_WINFUNCTYPE(
- ctypes.wintypes.HANDLE, ctypes.wintypes.DWORD)(
- ('GetStdHandle', ctypes.windll.kernel32))
- h = GetStdHandle(WIN_OUTPUT_IDS[fileno])
-
- WriteConsoleW = compat_ctypes_WINFUNCTYPE(
- ctypes.wintypes.BOOL, ctypes.wintypes.HANDLE, ctypes.wintypes.LPWSTR,
- ctypes.wintypes.DWORD, ctypes.POINTER(ctypes.wintypes.DWORD),
- ctypes.wintypes.LPVOID)(('WriteConsoleW', ctypes.windll.kernel32))
- written = ctypes.wintypes.DWORD(0)
-
- GetFileType = compat_ctypes_WINFUNCTYPE(ctypes.wintypes.DWORD, ctypes.wintypes.DWORD)(('GetFileType', ctypes.windll.kernel32))
- FILE_TYPE_CHAR = 0x0002
- FILE_TYPE_REMOTE = 0x8000
- GetConsoleMode = compat_ctypes_WINFUNCTYPE(
- ctypes.wintypes.BOOL, ctypes.wintypes.HANDLE,
- ctypes.POINTER(ctypes.wintypes.DWORD))(
- ('GetConsoleMode', ctypes.windll.kernel32))
- INVALID_HANDLE_VALUE = ctypes.wintypes.DWORD(-1).value
-
- def not_a_console(handle):
- if handle == INVALID_HANDLE_VALUE or handle is None:
- return True
- return ((GetFileType(handle) & ~FILE_TYPE_REMOTE) != FILE_TYPE_CHAR
- or GetConsoleMode(handle, ctypes.byref(ctypes.wintypes.DWORD())) == 0)
-
- if not_a_console(h):
- return False
-
- def next_nonbmp_pos(s):
- try:
- return next(i for i, c in enumerate(s) if ord(c) > 0xffff)
- except StopIteration:
- return len(s)
-
- while s:
- count = min(next_nonbmp_pos(s), 1024)
-
- ret = WriteConsoleW(
- h, s, count if count else 2, ctypes.byref(written), None)
- if ret == 0:
- raise OSError('Failed to write string')
- if not count: # We just wrote a non-BMP character
- assert written.value == 2
- s = s[1:]
- else:
- assert written.value > 0
- s = s[written.value:]
- return True
-
-
def write_string(s, out=None, encoding=None):
if out is None:
out = sys.stderr
assert type(s) == compat_str
- if sys.platform == 'win32' and encoding is None and hasattr(out, 'fileno'):
- if _windows_write_string(s, out):
- return
-
- if ('b' in getattr(out, 'mode', '')
- or sys.version_info[0] < 3): # Python 2 lies about mode of sys.stderr
+ if 'b' in getattr(out, 'mode', ''):
byt = s.encode(encoding or preferredencoding(), 'ignore')
out.write(byt)
elif hasattr(out, 'buffer'):
@@ -2985,8 +2789,6 @@ def lowercase_escape(s):
def escape_rfc3986(s):
"""Escape non-ASCII characters as suggested by RFC 3986"""
- if sys.version_info < (3, 0) and isinstance(s, compat_str):
- s = s.encode('utf-8')
return compat_urllib_parse.quote(s, b"%/;:@&=+$,!~*'()?#[]")
@@ -3335,12 +3137,7 @@ def args_to_str(args):
def error_to_compat_str(err):
- err_str = str(err)
- # On python 2 error byte string must be decoded with proper
- # encoding rather than ascii
- if sys.version_info[0] < 3:
- err_str = err_str.decode(preferredencoding())
- return err_str
+ return str(err)
def error_to_str(err):
@@ -5144,7 +4941,7 @@ def get_executable_path():
from zipimport import zipimporter
if hasattr(sys, 'frozen'): # Running from PyInstaller
path = os.path.dirname(sys.executable)
- elif isinstance(globals().get('__loader__'), zipimporter): # Running from ZIP
+ elif isinstance(__loader__, zipimporter): # Running from ZIP
path = os.path.join(os.path.dirname(__file__), '../..')
else:
path = os.path.join(os.path.dirname(__file__), '..')
@@ -5436,8 +5233,6 @@ class Config:
try:
# FIXME: https://github.com/ytdl-org/youtube-dl/commit/dfe5fa49aed02cf36ba9f743b11b0903554b5e56
contents = optionf.read()
- if sys.version_info < (3,):
- contents = contents.decode(preferredencoding())
res = compat_shlex_split(contents, comments=True)
finally:
optionf.close()