mirror of
https://github.com/ytdl-org/youtube-dl.git
synced 2024-11-25 03:32:05 +00:00
[test] Fixes for old Pythons
This commit is contained in:
parent
1634b1d61e
commit
1d8d5a93f7
6 changed files with 30 additions and 15 deletions
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
|
@ -301,7 +301,7 @@ jobs:
|
||||||
if: ${{ matrix.python-version == '2.6' }}
|
if: ${{ matrix.python-version == '2.6' }}
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
# see pip for Jython
|
# Work around deprecation of support for non-SNI clients at PyPI CDN (see https://status.python.org/incidents/hzmjhqsdjqgb)
|
||||||
$PIP -qq show unittest2 || { \
|
$PIP -qq show unittest2 || { \
|
||||||
for u in "65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl" \
|
for u in "65/26/32b8464df2a97e6dd1b656ed26b2c194606c16fe163c695a992b36c11cdf/six-1.13.0-py2.py3-none-any.whl" \
|
||||||
"f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl" \
|
"f2/94/3af39d34be01a24a6e65433d19e107099374224905f1e0cc6bbe1fd22a2f/argparse-1.4.0-py2.py3-none-any.whl" \
|
||||||
|
@ -312,7 +312,7 @@ jobs:
|
||||||
$PIP install ${u##*/}; \
|
$PIP install ${u##*/}; \
|
||||||
done; }
|
done; }
|
||||||
# make tests use unittest2
|
# make tests use unittest2
|
||||||
for test in ./test/test_*.py; do
|
for test in ./test/test_*.py ./test/helper.py; do
|
||||||
sed -r -i -e '/^import unittest$/s/test/test2 as unittest/' "$test"
|
sed -r -i -e '/^import unittest$/s/test/test2 as unittest/' "$test"
|
||||||
done
|
done
|
||||||
#-------- nose --------
|
#-------- nose --------
|
||||||
|
|
|
@ -9,6 +9,7 @@ import re
|
||||||
import types
|
import types
|
||||||
import ssl
|
import ssl
|
||||||
import sys
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
import youtube_dl.extractor
|
import youtube_dl.extractor
|
||||||
from youtube_dl import YoutubeDL
|
from youtube_dl import YoutubeDL
|
||||||
|
@ -17,6 +18,7 @@ from youtube_dl.compat import (
|
||||||
compat_str,
|
compat_str,
|
||||||
)
|
)
|
||||||
from youtube_dl.utils import (
|
from youtube_dl.utils import (
|
||||||
|
IDENTITY,
|
||||||
preferredencoding,
|
preferredencoding,
|
||||||
write_string,
|
write_string,
|
||||||
)
|
)
|
||||||
|
@ -298,3 +300,7 @@ def http_server_port(httpd):
|
||||||
else:
|
else:
|
||||||
sock = httpd.socket
|
sock = httpd.socket
|
||||||
return sock.getsockname()[1]
|
return sock.getsockname()[1]
|
||||||
|
|
||||||
|
|
||||||
|
def expectedFailureIf(cond):
|
||||||
|
return unittest.expectedFailure if cond else IDENTITY
|
||||||
|
|
|
@ -8,6 +8,7 @@ import sys
|
||||||
import unittest
|
import unittest
|
||||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||||
|
|
||||||
|
import contextlib
|
||||||
import gzip
|
import gzip
|
||||||
import io
|
import io
|
||||||
import ssl
|
import ssl
|
||||||
|
@ -154,7 +155,7 @@ class HTTPTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
|
||||||
|
|
||||||
def gzip_compress(p):
|
def gzip_compress(p):
|
||||||
buf = io.BytesIO()
|
buf = io.BytesIO()
|
||||||
with gzip.GzipFile(fileobj=buf, mode='wb') as f:
|
with contextlib.closing(gzip.GzipFile(fileobj=buf, mode='wb')) as f:
|
||||||
f.write(p)
|
f.write(p)
|
||||||
return buf.getvalue()
|
return buf.getvalue()
|
||||||
|
|
||||||
|
@ -306,6 +307,10 @@ class TestHTTP(unittest.TestCase):
|
||||||
else self.https_port if scheme == 'https'
|
else self.https_port if scheme == 'https'
|
||||||
else self.http_port, path)
|
else self.http_port, path)
|
||||||
|
|
||||||
|
@unittest.skipUnless(
|
||||||
|
sys.version_info >= (3, 2)
|
||||||
|
or (sys.version_info[0] == 2 and sys.version_info[1:] >= (7, 9)),
|
||||||
|
'No support for certificate check in SSL')
|
||||||
def test_nocheckcertificate(self):
|
def test_nocheckcertificate(self):
|
||||||
with FakeYDL({'logger': FakeLogger()}) as ydl:
|
with FakeYDL({'logger': FakeLogger()}) as ydl:
|
||||||
with self.assertRaises(compat_urllib_error.URLError):
|
with self.assertRaises(compat_urllib_error.URLError):
|
||||||
|
|
|
@ -1617,7 +1617,7 @@ Line 1
|
||||||
self.assertEqual(traverse_obj(_TEST_DATA, lambda x, y: x == 'urls' and isinstance(y, list)),
|
self.assertEqual(traverse_obj(_TEST_DATA, lambda x, y: x == 'urls' and isinstance(y, list)),
|
||||||
[_TEST_DATA['urls']],
|
[_TEST_DATA['urls']],
|
||||||
msg='function as query key should perform a filter based on (key, value)')
|
msg='function as query key should perform a filter based on (key, value)')
|
||||||
self.assertCountEqual(traverse_obj(_TEST_DATA, lambda _, x: isinstance(x[0], str)), {'str'},
|
self.assertCountEqual(traverse_obj(_TEST_DATA, lambda _, x: isinstance(x[0], str)), set(('str',)),
|
||||||
msg='exceptions in the query function should be catched')
|
msg='exceptions in the query function should be catched')
|
||||||
self.assertEqual(traverse_obj(iter(range(4)), lambda _, x: x % 2 == 0), [0, 2],
|
self.assertEqual(traverse_obj(iter(range(4)), lambda _, x: x % 2 == 0), [0, 2],
|
||||||
msg='function key should accept iterables')
|
msg='function key should accept iterables')
|
||||||
|
@ -1643,7 +1643,7 @@ Line 1
|
||||||
with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
|
with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
|
||||||
traverse_obj(_TEST_DATA, set())
|
traverse_obj(_TEST_DATA, set())
|
||||||
with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
|
with self.assertRaises(Exception, msg='Sets with length != 1 should raise in debug'):
|
||||||
traverse_obj(_TEST_DATA, {str.upper, str})
|
traverse_obj(_TEST_DATA, set((str.upper, str)))
|
||||||
|
|
||||||
# Test `slice` as a key
|
# Test `slice` as a key
|
||||||
_SLICE_DATA = [0, 1, 2, 3, 4]
|
_SLICE_DATA = [0, 1, 2, 3, 4]
|
||||||
|
@ -1779,7 +1779,7 @@ Line 1
|
||||||
{0: 100}, msg='type as expected_type should filter dict values')
|
{0: 100}, msg='type as expected_type should filter dict values')
|
||||||
self.assertEqual(traverse_obj(_TEST_DATA, {0: 100, 1: 1.2, 2: 'None'}, expected_type=str_or_none),
|
self.assertEqual(traverse_obj(_TEST_DATA, {0: 100, 1: 1.2, 2: 'None'}, expected_type=str_or_none),
|
||||||
{0: '100', 1: '1.2'}, msg='function as expected_type should transform dict values')
|
{0: '100', 1: '1.2'}, msg='function as expected_type should transform dict values')
|
||||||
self.assertEqual(traverse_obj(_TEST_DATA, ({0: 1.2}, 0, {int_or_none}), expected_type=int),
|
self.assertEqual(traverse_obj(_TEST_DATA, ({0: 1.2}, 0, set((int_or_none,))), expected_type=int),
|
||||||
1, msg='expected_type should not filter non final dict values')
|
1, msg='expected_type should not filter non final dict values')
|
||||||
self.assertEqual(traverse_obj(_TEST_DATA, {0: {0: 100, 1: 'str'}}, expected_type=int),
|
self.assertEqual(traverse_obj(_TEST_DATA, {0: {0: 100, 1: 'str'}}, expected_type=int),
|
||||||
{0: {0: 100}}, msg='expected_type should transform deep dict values')
|
{0: {0: 100}}, msg='expected_type should transform deep dict values')
|
||||||
|
|
|
@ -280,16 +280,16 @@ class JSInterpreter(object):
|
||||||
# make Py 2.6 conform to its lying documentation
|
# make Py 2.6 conform to its lying documentation
|
||||||
if name == 'flags':
|
if name == 'flags':
|
||||||
self.flags = self.__flags
|
self.flags = self.__flags
|
||||||
|
return self.flags
|
||||||
elif name == 'pattern':
|
elif name == 'pattern':
|
||||||
self.pattern = self.__pattern_txt
|
self.pattern = self.__pattern_txt
|
||||||
|
return self.pattern
|
||||||
|
elif hasattr(self.__self, name):
|
||||||
|
v = getattr(self.__self, name)
|
||||||
|
setattr(self, name, v)
|
||||||
|
return v
|
||||||
elif name in ('groupindex', 'groups'):
|
elif name in ('groupindex', 'groups'):
|
||||||
# in case these get set after a match?
|
return 0 if name == 'groupindex' else {}
|
||||||
if hasattr(self.__self, name):
|
|
||||||
setattr(self, name, getattr(self.__self, name))
|
|
||||||
else:
|
|
||||||
return 0 if name == 'groupindex' else {}
|
|
||||||
if hasattr(self, name):
|
|
||||||
return getattr(self, name)
|
|
||||||
raise AttributeError('{0} has no attribute named {1}'.format(self, name))
|
raise AttributeError('{0} has no attribute named {1}'.format(self, name))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -6198,7 +6198,8 @@ def traverse_obj(obj, *paths, **kwargs):
|
||||||
elif isinstance(obj, compat_re_Match):
|
elif isinstance(obj, compat_re_Match):
|
||||||
result = None
|
result = None
|
||||||
if isinstance(key, int) or casesense:
|
if isinstance(key, int) or casesense:
|
||||||
result = lookup_or_none(obj, key, getter=compat_re_Match.group)
|
# Py 2.6 doesn't have methods in the Match class/type
|
||||||
|
result = lookup_or_none(obj, key, getter=lambda _, k: obj.group(k))
|
||||||
|
|
||||||
elif isinstance(key, str):
|
elif isinstance(key, str):
|
||||||
result = next((v for k, v in obj.groupdict().items()
|
result = next((v for k, v in obj.groupdict().items()
|
||||||
|
@ -6246,7 +6247,10 @@ def traverse_obj(obj, *paths, **kwargs):
|
||||||
|
|
||||||
if __debug__ and callable(key):
|
if __debug__ and callable(key):
|
||||||
# Verify function signature
|
# Verify function signature
|
||||||
inspect.getcallargs(key, None, None)
|
args = inspect.getargspec(key)
|
||||||
|
if len(args.args) != 2:
|
||||||
|
# crash differently in 2.6 !
|
||||||
|
inspect.getcallargs(key, None, None)
|
||||||
|
|
||||||
new_objs = []
|
new_objs = []
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
|
|
Loading…
Reference in a new issue