aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/helper.py65
-rw-r--r--test/test_InfoExtractor.py41
-rw-r--r--test/test_YoutubeDL.py49
-rw-r--r--test/test_YoutubeDLCookieJar.py7
-rw-r--r--test/test_aes.py32
-rw-r--r--test/test_age_restriction.py5
-rw-r--r--test/test_all_urls.py18
-rw-r--r--test/test_cache.py9
-rw-r--r--test/test_compat.py72
-rw-r--r--test/test_cookies.py4
-rwxr-xr-xtest/test_download.py29
-rw-r--r--test/test_downloader_http.py9
-rw-r--r--test/test_execution.py22
-rw-r--r--test/test_http.py107
-rw-r--r--test/test_jsinterp.py4
-rw-r--r--test/test_netrc.py4
-rw-r--r--test/test_overwrites.py9
-rw-r--r--test/test_post_hooks.py9
-rw-r--r--test/test_postprocessors.py5
-rw-r--r--test/test_socks.py25
-rw-r--r--test/test_subtitles.py68
-rw-r--r--test/test_utils.py143
-rw-r--r--test/test_verbose_output.py22
-rw-r--r--test/test_youtube_lists.py8
-rw-r--r--test/test_youtube_misc.py3
-rw-r--r--test/test_youtube_signature.py19
-rw-r--r--test/testdata/certificate/ca.crt10
-rw-r--r--test/testdata/certificate/ca.key5
-rw-r--r--test/testdata/certificate/ca.srl1
-rw-r--r--test/testdata/certificate/client.crt9
-rw-r--r--test/testdata/certificate/client.csr7
-rw-r--r--test/testdata/certificate/client.key5
-rw-r--r--test/testdata/certificate/clientencrypted.key8
-rw-r--r--test/testdata/certificate/clientwithencryptedkey.crt17
-rw-r--r--test/testdata/certificate/clientwithkey.crt14
-rw-r--r--test/testdata/certificate/instructions.md19
36 files changed, 448 insertions, 435 deletions
diff --git a/test/helper.py b/test/helper.py
index 28c21b2eb..2333ace98 100644
--- a/test/helper.py
+++ b/test/helper.py
@@ -1,26 +1,16 @@
-from __future__ import unicode_literals
-
import errno
-import io
import hashlib
import json
import os.path
import re
-import types
import ssl
import sys
+import types
import yt_dlp.extractor
from yt_dlp import YoutubeDL
-from yt_dlp.compat import (
- compat_os_name,
- compat_str,
-)
-from yt_dlp.utils import (
- preferredencoding,
- write_string,
-)
-
+from yt_dlp.compat import compat_os_name, compat_str
+from yt_dlp.utils import preferredencoding, write_string
if 'pytest' in sys.modules:
import pytest
@@ -35,10 +25,10 @@ def get_params(override=None):
'parameters.json')
LOCAL_PARAMETERS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'local_parameters.json')
- with io.open(PARAMETERS_FILE, encoding='utf-8') as pf:
+ with open(PARAMETERS_FILE, encoding='utf-8') as pf:
parameters = json.load(pf)
if os.path.exists(LOCAL_PARAMETERS_FILE):
- with io.open(LOCAL_PARAMETERS_FILE, encoding='utf-8') as pf:
+ with open(LOCAL_PARAMETERS_FILE, encoding='utf-8') as pf:
parameters.update(json.load(pf))
if override:
parameters.update(override)
@@ -63,8 +53,8 @@ def report_warning(message):
_msg_header = '\033[0;33mWARNING:\033[0m'
else:
_msg_header = 'WARNING:'
- output = '%s %s\n' % (_msg_header, message)
- if 'b' in getattr(sys.stderr, 'mode', '') or sys.version_info[0] < 3:
+ output = f'{_msg_header} {message}\n'
+ if 'b' in getattr(sys.stderr, 'mode', ''):
output = output.encode(preferredencoding())
sys.stderr.write(output)
@@ -74,7 +64,7 @@ class FakeYDL(YoutubeDL):
# Different instances of the downloader can't share the same dictionary
# some test set the "sublang" parameter, which would break the md5 checks.
params = get_params(override=override)
- super(FakeYDL, self).__init__(params, auto_init=False)
+ super().__init__(params, auto_init=False)
self.result = []
def to_screen(self, s, skip_eol=None):
@@ -99,11 +89,10 @@ class FakeYDL(YoutubeDL):
def gettestcases(include_onlymatching=False):
for ie in yt_dlp.extractor.gen_extractors():
- for tc in ie.get_testcases(include_onlymatching):
- yield tc
+ yield from ie.get_testcases(include_onlymatching)
-md5 = lambda s: hashlib.md5(s.encode('utf-8')).hexdigest()
+md5 = lambda s: hashlib.md5(s.encode()).hexdigest()
def expect_value(self, got, expected, field):
@@ -113,33 +102,30 @@ def expect_value(self, got, expected, field):
self.assertTrue(
isinstance(got, compat_str),
- 'Expected a %s object, but got %s for field %s' % (
- compat_str.__name__, type(got).__name__, field))
+ f'Expected a {compat_str.__name__} object, but got {type(got).__name__} for field {field}')
self.assertTrue(
match_rex.match(got),
- 'field %s (value: %r) should match %r' % (field, got, match_str))
+ f'field {field} (value: {got!r}) should match {match_str!r}')
elif isinstance(expected, compat_str) and expected.startswith('startswith:'):
start_str = expected[len('startswith:'):]
self.assertTrue(
isinstance(got, compat_str),
- 'Expected a %s object, but got %s for field %s' % (
- compat_str.__name__, type(got).__name__, field))
+ f'Expected a {compat_str.__name__} object, but got {type(got).__name__} for field {field}')
self.assertTrue(
got.startswith(start_str),
- 'field %s (value: %r) should start with %r' % (field, got, start_str))
+ f'field {field} (value: {got!r}) should start with {start_str!r}')
elif isinstance(expected, compat_str) and expected.startswith('contains:'):
contains_str = expected[len('contains:'):]
self.assertTrue(
isinstance(got, compat_str),
- 'Expected a %s object, but got %s for field %s' % (
- compat_str.__name__, type(got).__name__, field))
+ f'Expected a {compat_str.__name__} object, but got {type(got).__name__} for field {field}')
self.assertTrue(
contains_str in got,
- 'field %s (value: %r) should contain %r' % (field, got, contains_str))
+ f'field {field} (value: {got!r}) should contain {contains_str!r}')
elif isinstance(expected, type):
self.assertTrue(
isinstance(got, expected),
- 'Expected type %r for field %s, but got value %r of type %r' % (expected, field, got, type(got)))
+ f'Expected type {expected!r} for field {field}, but got value {got!r} of type {type(got)!r}')
elif isinstance(expected, dict) and isinstance(got, dict):
expect_dict(self, got, expected)
elif isinstance(expected, list) and isinstance(got, list):
@@ -159,13 +145,12 @@ def expect_value(self, got, expected, field):
if isinstance(expected, compat_str) and expected.startswith('md5:'):
self.assertTrue(
isinstance(got, compat_str),
- 'Expected field %s to be a unicode object, but got value %r of type %r' % (field, got, type(got)))
+ f'Expected field {field} to be a unicode object, but got value {got!r} of type {type(got)!r}')
got = 'md5:' + md5(got)
elif isinstance(expected, compat_str) and re.match(r'^(?:min|max)?count:\d+', expected):
self.assertTrue(
isinstance(got, (list, dict)),
- 'Expected field %s to be a list or a dict, but it is of type %s' % (
- field, type(got).__name__))
+ f'Expected field {field} to be a list or a dict, but it is of type {type(got).__name__}')
op, _, expected_num = expected.partition(':')
expected_num = int(expected_num)
if op == 'mincount':
@@ -185,7 +170,7 @@ def expect_value(self, got, expected, field):
return
self.assertEqual(
expected, got,
- 'Invalid value for field %s, expected %r, got %r' % (field, expected, got))
+ f'Invalid value for field {field}, expected {expected!r}, got {got!r}')
def expect_dict(self, got_dict, expected_dict):
@@ -260,13 +245,13 @@ def expect_info_dict(self, got_dict, expected_dict):
info_dict_str = ''
if len(missing_keys) != len(expected_dict):
info_dict_str += ''.join(
- ' %s: %s,\n' % (_repr(k), _repr(v))
+ f' {_repr(k)}: {_repr(v)},\n'
for k, v in test_info_dict.items() if k not in missing_keys)
if info_dict_str:
info_dict_str += '\n'
info_dict_str += ''.join(
- ' %s: %s,\n' % (_repr(k), _repr(test_info_dict[k]))
+ f' {_repr(k)}: {_repr(test_info_dict[k])},\n'
for k in missing_keys)
write_string(
'\n\'info_dict\': {\n' + info_dict_str + '},\n', out=sys.stderr)
@@ -295,21 +280,21 @@ def assertRegexpMatches(self, text, regexp, msg=None):
def assertGreaterEqual(self, got, expected, msg=None):
if not (got >= expected):
if msg is None:
- msg = '%r not greater than or equal to %r' % (got, expected)
+ msg = f'{got!r} not greater than or equal to {expected!r}'
self.assertTrue(got >= expected, msg)
def assertLessEqual(self, got, expected, msg=None):
if not (got <= expected):
if msg is None:
- msg = '%r not less than or equal to %r' % (got, expected)
+ msg = f'{got!r} not less than or equal to {expected!r}'
self.assertTrue(got <= expected, msg)
def assertEqual(self, got, expected, msg=None):
if not (got == expected):
if msg is None:
- msg = '%r not equal to %r' % (got, expected)
+ msg = f'{got!r} not equal to {expected!r}'
self.assertTrue(got == expected, msg)
diff --git a/test/test_InfoExtractor.py b/test/test_InfoExtractor.py
index 866ded243..257ea7dd3 100644
--- a/test/test_InfoExtractor.py
+++ b/test/test_InfoExtractor.py
@@ -1,21 +1,23 @@
#!/usr/bin/env python3
-
-from __future__ import unicode_literals
-
# Allow direct execution
-import io
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import threading
from test.helper import FakeYDL, expect_dict, expect_value, http_server_port
+
from yt_dlp.compat import compat_etree_fromstring, compat_http_server
-from yt_dlp.extractor.common import InfoExtractor
from yt_dlp.extractor import YoutubeIE, get_info_extractor
-from yt_dlp.utils import encode_data_uri, strip_jsonp, ExtractorError, RegexNotFoundError
-import threading
-
+from yt_dlp.extractor.common import InfoExtractor
+from yt_dlp.utils import (
+ ExtractorError,
+ RegexNotFoundError,
+ encode_data_uri,
+ strip_jsonp,
+)
TEAPOT_RESPONSE_STATUS = 418
TEAPOT_RESPONSE_BODY = "<h1>418 I'm a teapot</h1>"
@@ -1011,8 +1013,7 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
]
for m3u8_file, m3u8_url, expected_formats, expected_subs in _TEST_CASES:
- with io.open('./test/testdata/m3u8/%s.m3u8' % m3u8_file,
- mode='r', encoding='utf-8') as f:
+ with open('./test/testdata/m3u8/%s.m3u8' % m3u8_file, encoding='utf-8') as f:
formats, subs = self.ie._parse_m3u8_formats_and_subtitles(
f.read(), m3u8_url, ext='mp4')
self.ie._sort_formats(formats)
@@ -1357,10 +1358,9 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
]
for mpd_file, mpd_url, mpd_base_url, expected_formats, expected_subtitles in _TEST_CASES:
- with io.open('./test/testdata/mpd/%s.mpd' % mpd_file,
- mode='r', encoding='utf-8') as f:
+ with open('./test/testdata/mpd/%s.mpd' % mpd_file, encoding='utf-8') as f:
formats, subtitles = self.ie._parse_mpd_formats_and_subtitles(
- compat_etree_fromstring(f.read().encode('utf-8')),
+ compat_etree_fromstring(f.read().encode()),
mpd_base_url=mpd_base_url, mpd_url=mpd_url)
self.ie._sort_formats(formats)
expect_value(self, formats, expected_formats, None)
@@ -1549,10 +1549,9 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
]
for ism_file, ism_url, expected_formats, expected_subtitles in _TEST_CASES:
- with io.open('./test/testdata/ism/%s.Manifest' % ism_file,
- mode='r', encoding='utf-8') as f:
+ with open('./test/testdata/ism/%s.Manifest' % ism_file, encoding='utf-8') as f:
formats, subtitles = self.ie._parse_ism_formats_and_subtitles(
- compat_etree_fromstring(f.read().encode('utf-8')), ism_url=ism_url)
+ compat_etree_fromstring(f.read().encode()), ism_url=ism_url)
self.ie._sort_formats(formats)
expect_value(self, formats, expected_formats, None)
expect_value(self, subtitles, expected_subtitles, None)
@@ -1576,10 +1575,9 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
]
for f4m_file, f4m_url, expected_formats in _TEST_CASES:
- with io.open('./test/testdata/f4m/%s.f4m' % f4m_file,
- mode='r', encoding='utf-8') as f:
+ with open('./test/testdata/f4m/%s.f4m' % f4m_file, encoding='utf-8') as f:
formats = self.ie._parse_f4m_formats(
- compat_etree_fromstring(f.read().encode('utf-8')),
+ compat_etree_fromstring(f.read().encode()),
f4m_url, None)
self.ie._sort_formats(formats)
expect_value(self, formats, expected_formats, None)
@@ -1624,10 +1622,9 @@ jwplayer("mediaplayer").setup({"abouttext":"Visit Indie DB","aboutlink":"http:\/
]
for xspf_file, xspf_url, expected_entries in _TEST_CASES:
- with io.open('./test/testdata/xspf/%s.xspf' % xspf_file,
- mode='r', encoding='utf-8') as f:
+ with open('./test/testdata/xspf/%s.xspf' % xspf_file, encoding='utf-8') as f:
entries = self.ie._parse_xspf(
- compat_etree_fromstring(f.read().encode('utf-8')),
+ compat_etree_fromstring(f.read().encode()),
xspf_file, xspf_url=xspf_url, xspf_base_url=xspf_url)
expect_value(self, entries, expected_entries, None)
for i in range(len(entries)):
diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py
index c9108c5b6..1133f6165 100644
--- a/test/test_YoutubeDL.py
+++ b/test/test_YoutubeDL.py
@@ -1,31 +1,38 @@
#!/usr/bin/env python3
-# coding: utf-8
-
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import copy
import json
-
from test.helper import FakeYDL, assertRegexpMatches
+
from yt_dlp import YoutubeDL
-from yt_dlp.compat import compat_os_name, compat_setenv, compat_str, compat_urllib_error
+from yt_dlp.compat import (
+ compat_os_name,
+ compat_setenv,
+ compat_str,
+ compat_urllib_error,
+)
from yt_dlp.extractor import YoutubeIE
from yt_dlp.extractor.common import InfoExtractor
from yt_dlp.postprocessor.common import PostProcessor
-from yt_dlp.utils import ExtractorError, int_or_none, match_filter_func, LazyList
+from yt_dlp.utils import (
+ ExtractorError,
+ LazyList,
+ int_or_none,
+ match_filter_func,
+)
TEST_URL = 'http://localhost/sample.mp4'
class YDL(FakeYDL):
def __init__(self, *args, **kwargs):
- super(YDL, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.downloaded_info_dicts = []
self.msgs = []
@@ -551,11 +558,11 @@ class TestYoutubeDL(unittest.TestCase):
def s_formats(lang, autocaption=False):
return [{
'ext': ext,
- 'url': 'http://localhost/video.%s.%s' % (lang, ext),
+ 'url': f'http://localhost/video.{lang}.{ext}',
'_auto': autocaption,
} for ext in ['vtt', 'srt', 'ass']]
- subtitles = dict((l, s_formats(l)) for l in ['en', 'fr', 'es'])
- auto_captions = dict((l, s_formats(l, True)) for l in ['it', 'pt', 'es'])
+ subtitles = {l: s_formats(l) for l in ['en', 'fr', 'es']}
+ auto_captions = {l: s_formats(l, True) for l in ['it', 'pt', 'es']}
info_dict = {
'id': 'test',
'title': 'Test',
@@ -580,7 +587,7 @@ class TestYoutubeDL(unittest.TestCase):
result = get_info({'writesubtitles': True})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['en']))
+ self.assertEqual(set(subs.keys()), {'en'})
self.assertTrue(subs['en'].get('data') is None)
self.assertEqual(subs['en']['ext'], 'ass')
@@ -591,39 +598,39 @@ class TestYoutubeDL(unittest.TestCase):
result = get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['es', 'fr']))
+ self.assertEqual(set(subs.keys()), {'es', 'fr'})
result = get_info({'writesubtitles': True, 'subtitleslangs': ['all', '-en']})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['es', 'fr']))
+ self.assertEqual(set(subs.keys()), {'es', 'fr'})
result = get_info({'writesubtitles': True, 'subtitleslangs': ['en', 'fr', '-en']})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['fr']))
+ self.assertEqual(set(subs.keys()), {'fr'})
result = get_info({'writesubtitles': True, 'subtitleslangs': ['-en', 'en']})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['en']))
+ self.assertEqual(set(subs.keys()), {'en'})
result = get_info({'writesubtitles': True, 'subtitleslangs': ['e.+']})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['es', 'en']))
+ self.assertEqual(set(subs.keys()), {'es', 'en'})
result = get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['es', 'pt']))
+ self.assertEqual(set(subs.keys()), {'es', 'pt'})
self.assertFalse(subs['es']['_auto'])
self.assertTrue(subs['pt']['_auto'])
result = get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
subs = result['requested_subtitles']
self.assertTrue(subs)
- self.assertEqual(set(subs.keys()), set(['es', 'pt']))
+ self.assertEqual(set(subs.keys()), {'es', 'pt'})
self.assertTrue(subs['es']['_auto'])
self.assertTrue(subs['pt']['_auto'])
@@ -654,7 +661,7 @@ class TestYoutubeDL(unittest.TestCase):
'duration': 100000,
'playlist_index': 1,
'playlist_autonumber': 2,
- '_last_playlist_index': 100,
+ '__last_playlist_index': 100,
'n_entries': 10,
'formats': [{'id': 'id 1'}, {'id': 'id 2'}, {'id': 'id 3'}]
}
@@ -1082,7 +1089,7 @@ class TestYoutubeDL(unittest.TestCase):
class _YDL(YDL):
def __init__(self, *args, **kwargs):
- super(_YDL, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def trouble(self, s, tb=None):
pass
diff --git a/test/test_YoutubeDLCookieJar.py b/test/test_YoutubeDLCookieJar.py
index c514413a4..6280e1f2c 100644
--- a/test/test_YoutubeDLCookieJar.py
+++ b/test/test_YoutubeDLCookieJar.py
@@ -1,13 +1,10 @@
#!/usr/bin/env python3
-# coding: utf-8
-
-from __future__ import unicode_literals
-
import os
import re
import sys
import tempfile
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from yt_dlp.utils import YoutubeDLCookieJar
@@ -20,7 +17,7 @@ class TestYoutubeDLCookieJar(unittest.TestCase):
tf = tempfile.NamedTemporaryFile(delete=False)
try:
cookiejar.save(filename=tf.name, ignore_discard=True, ignore_expires=True)
- temp = tf.read().decode('utf-8')
+ temp = tf.read().decode()
self.assertTrue(re.search(
r'www\.foobar\.foobar\s+FALSE\s+/\s+TRUE\s+0\s+YoutubeDLExpiresEmpty\s+YoutubeDLExpiresEmptyValue', temp))
self.assertTrue(re.search(
diff --git a/test/test_aes.py b/test/test_aes.py
index 5c9273f8a..2b7b7cf54 100644
--- a/test/test_aes.py
+++ b/test/test_aes.py
@@ -1,30 +1,30 @@
#!/usr/bin/env python3
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import base64
+
from yt_dlp.aes import (
- aes_decrypt,
- aes_encrypt,
- aes_ecb_encrypt,
- aes_ecb_decrypt,
+ BLOCK_SIZE_BYTES,
aes_cbc_decrypt,
aes_cbc_decrypt_bytes,
aes_cbc_encrypt,
aes_ctr_decrypt,
aes_ctr_encrypt,
+ aes_decrypt,
+ aes_decrypt_text,
+ aes_ecb_decrypt,
+ aes_ecb_encrypt,
+ aes_encrypt,
aes_gcm_decrypt_and_verify,
aes_gcm_decrypt_and_verify_bytes,
- aes_decrypt_text,
- BLOCK_SIZE_BYTES,
)
-from yt_dlp.compat import compat_pycrypto_AES
+from yt_dlp.dependencies import Cryptodome_AES
from yt_dlp.utils import bytes_to_intlist, intlist_to_bytes
-import base64
# the encrypted data can be generate with 'devscripts/generate_aes_testdata.py'
@@ -45,7 +45,7 @@ class TestAES(unittest.TestCase):
data = b'\x97\x92+\xe5\x0b\xc3\x18\x91ky9m&\xb3\xb5@\xe6\x27\xc2\x96.\xc8u\x88\xab9-[\x9e|\xf1\xcd'
decrypted = intlist_to_bytes(aes_cbc_decrypt(bytes_to_intlist(data), self.key, self.iv))
self.assertEqual(decrypted.rstrip(b'\x08'), self.secret_msg)
- if compat_pycrypto_AES:
+ if Cryptodome_AES:
decrypted = aes_cbc_decrypt_bytes(data, intlist_to_bytes(self.key), intlist_to_bytes(self.iv))
self.assertEqual(decrypted.rstrip(b'\x08'), self.secret_msg)
@@ -75,25 +75,25 @@ class TestAES(unittest.TestCase):
decrypted = intlist_to_bytes(aes_gcm_decrypt_and_verify(
bytes_to_intlist(data), self.key, bytes_to_intlist(authentication_tag), self.iv[:12]))
self.assertEqual(decrypted.rstrip(b'\x08'), self.secret_msg)
- if compat_pycrypto_AES:
+ if Cryptodome_AES:
decrypted = aes_gcm_decrypt_and_verify_bytes(
data, intlist_to_bytes(self.key), authentication_tag, intlist_to_bytes(self.iv[:12]))
self.assertEqual(decrypted.rstrip(b'\x08'), self.secret_msg)
def test_decrypt_text(self):
- password = intlist_to_bytes(self.key).decode('utf-8')
+ password = intlist_to_bytes(self.key).decode()
encrypted = base64.b64encode(
intlist_to_bytes(self.iv[:8])
+ b'\x17\x15\x93\xab\x8d\x80V\xcdV\xe0\t\xcdo\xc2\xa5\xd8ksM\r\xe27N\xae'
- ).decode('utf-8')
+ ).decode()
decrypted = (aes_decrypt_text(encrypted, password, 16))
self.assertEqual(decrypted, self.secret_msg)
- password = intlist_to_bytes(self.key).decode('utf-8')
+ password = intlist_to_bytes(self.key).decode()
encrypted = base64.b64encode(
intlist_to_bytes(self.iv[:8])
+ b'\x0b\xe6\xa4\xd9z\x0e\xb8\xb9\xd0\xd4i_\x85\x1d\x99\x98_\xe5\x80\xe7.\xbf\xa5\x83'
- ).decode('utf-8')
+ ).decode()
decrypted = (aes_decrypt_text(encrypted, password, 32))
self.assertEqual(decrypted, self.secret_msg)
diff --git a/test/test_age_restriction.py b/test/test_age_restriction.py
index 70f9f4845..e1012f69b 100644
--- a/test/test_age_restriction.py
+++ b/test/test_age_restriction.py
@@ -1,13 +1,12 @@
#!/usr/bin/env python3
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from test.helper import try_rm, is_download_test
+from test.helper import is_download_test, try_rm
from yt_dlp import YoutubeDL
diff --git a/test/test_all_urls.py b/test/test_all_urls.py
index 2d89366d4..b6019554e 100644
--- a/test/test_all_urls.py
+++ b/test/test_all_urls.py
@@ -1,22 +1,16 @@
#!/usr/bin/env python3
-
-from __future__ import unicode_literals
-
# Allow direct execution
+import collections
import os
import sys
import unittest
-import collections
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from test.helper import gettestcases
-from yt_dlp.extractor import (
- FacebookIE,
- gen_extractors,
- YoutubeIE,
-)
+from yt_dlp.extractor import FacebookIE, YoutubeIE, gen_extractors
class TestAllURLsMatching(unittest.TestCase):
@@ -81,11 +75,11 @@ class TestAllURLsMatching(unittest.TestCase):
url = tc['url']
for ie in ies:
if type(ie).__name__ in ('GenericIE', tc['name'] + 'IE'):
- self.assertTrue(ie.suitable(url), '%s should match URL %r' % (type(ie).__name__, url))
+ self.assertTrue(ie.suitable(url), f'{type(ie).__name__} should match URL {url!r}')
else:
self.assertFalse(
ie.suitable(url),
- '%s should not match URL %r . That URL belongs to %s.' % (type(ie).__name__, url, tc['name']))
+ f'{type(ie).__name__} should not match URL {url!r} . That URL belongs to {tc["name"]}.')
def test_keywords(self):
self.assertMatch(':ytsubs', ['youtube:subscriptions'])
@@ -120,7 +114,7 @@ class TestAllURLsMatching(unittest.TestCase):
for (ie_name, ie_list) in name_accu.items():
self.assertEqual(
len(ie_list), 1,
- 'Multiple extractors with the same IE_NAME "%s" (%s)' % (ie_name, ', '.join(ie_list)))
+ f'Multiple extractors with the same IE_NAME "{ie_name}" ({", ".join(ie_list)})')
if __name__ == '__main__':
diff --git a/test/test_cache.py b/test/test_cache.py
index 8c4f85387..14e54ba20 100644
--- a/test/test_cache.py
+++ b/test/test_cache.py
@@ -1,18 +1,15 @@
#!/usr/bin/env python3
-# coding: utf-8
-
-from __future__ import unicode_literals
-
-import shutil
-
# Allow direct execution
import os
+import shutil
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from test.helper import FakeYDL
+
from yt_dlp.cache import Cache
diff --git a/test/test_compat.py b/test/test_compat.py
index c9bc4d7fb..224175c65 100644
--- a/test/test_compat.py
+++ b/test/test_compat.py
@@ -1,26 +1,20 @@
#!/usr/bin/env python3
-# coding: utf-8
-
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from yt_dlp import compat
from yt_dlp.compat import (
- compat_getenv,
- compat_setenv,
- compat_etree_Element,
compat_etree_fromstring,
compat_expanduser,
- compat_shlex_split,
+ compat_getenv,
+ compat_setenv,
compat_str,
compat_struct_unpack,
- compat_urllib_parse_quote,
- compat_urllib_parse_quote_plus,
compat_urllib_parse_unquote,
compat_urllib_parse_unquote_plus,
compat_urllib_parse_urlencode,
@@ -28,6 +22,12 @@ from yt_dlp.compat import (
class TestCompat(unittest.TestCase):
+ def test_compat_passthrough(self):
+ with self.assertWarns(DeprecationWarning):
+ compat.compat_basestring
+
+ compat.asyncio.events # Must not raise error
+
def test_compat_getenv(self):
test_str = 'тест'
compat_setenv('yt_dlp_COMPAT_GETENV', test_str)
@@ -42,39 +42,12 @@ class TestCompat(unittest.TestCase):
def test_compat_expanduser(self):
old_home = os.environ.get('HOME')
- test_str = r'C:\Documents and Settings\тест\Application Data'
- compat_setenv('HOME', test_str)
- self.assertEqual(compat_expanduser('~'), test_str)
- compat_setenv('HOME', old_home or '')
-
- def test_all_present(self):
- import yt_dlp.compat
- all_names = yt_dlp.compat.__all__
- present_names = set(filter(
- lambda c: '_' in c and not c.startswith('_'),
- dir(yt_dlp.compat))) - set(['unicode_literals'])
- self.assertEqual(all_names, sorted(present_names))
-
- def test_compat_urllib_parse_quote(self):
- self.assertEqual(compat_urllib_parse_quote('abc def'), 'abc%20def')
- self.assertEqual(compat_urllib_parse_quote('/user/abc+def'), '/user/abc%2Bdef')
- self.assertEqual(compat_urllib_parse_quote('/user/abc+def', safe='+'), '%2Fuser%2Fabc+def')
- self.assertEqual(compat_urllib_parse_quote(''), '')
- self.assertEqual(compat_urllib_parse_quote('%'), '%25')
- self.assertEqual(compat_urllib_parse_quote('%', safe='%'), '%')
- self.assertEqual(compat_urllib_parse_quote('津波'), '%E6%B4%A5%E6%B3%A2')
- self.assertEqual(
- compat_urllib_parse_quote('''<meta property="og:description" content="▁▂▃▄%▅▆▇█" />
-%<a href="https://ar.wikipedia.org/wiki/تسونامي">%a''', safe='<>=":%/ \r\n'),
- '''<meta property="og:description" content="%E2%96%81%E2%96%82%E2%96%83%E2%96%84%%E2%96%85%E2%96%86%E2%96%87%E2%96%88" />
-%<a href="https://ar.wikipedia.org/wiki/%D8%AA%D8%B3%D9%88%D9%86%D8%A7%D9%85%D9%8A">%a''')
- self.assertEqual(
- compat_urllib_parse_quote('''(^◣_◢^)っ︻デ═一 ⇀ ⇀ ⇀ ⇀ ⇀ ↶%I%Break%25Things%''', safe='% '),
- '''%28%5E%E2%97%A3_%E2%97%A2%5E%29%E3%81%A3%EF%B8%BB%E3%83%87%E2%95%90%E4%B8%80 %E2%87%80 %E2%87%80 %E2%87%80 %E2%87%80 %E2%87%80 %E2%86%B6%I%Break%25Things%''')
-
- def test_compat_urllib_parse_quote_plus(self):
- self.assertEqual(compat_urllib_parse_quote_plus('abc def'), 'abc+def')
- self.assertEqual(compat_urllib_parse_quote_plus('/abc def'), '%2Fabc+def')
+ test_str = R'C:\Documents and Settings\тест\Application Data'
+ try:
+ compat_setenv('HOME', test_str)
+ self.assertEqual(compat_expanduser('~'), test_str)
+ finally:
+ compat_setenv('HOME', old_home or '')
def test_compat_urllib_parse_unquote(self):
self.assertEqual(compat_urllib_parse_unquote('abc%20def'), 'abc def')
@@ -109,17 +82,6 @@ class TestCompat(unittest.TestCase):
self.assertEqual(compat_urllib_parse_urlencode([(b'abc', 'def')]), 'abc=def')
self.assertEqual(compat_urllib_parse_urlencode([(b'abc', b'def')]), 'abc=def')
- def test_compat_shlex_split(self):
- self.assertEqual(compat_shlex_split('-option "one two"'), ['-option', 'one two'])
- self.assertEqual(compat_shlex_split('-option "one\ntwo" \n -flag'), ['-option', 'one\ntwo', '-flag'])
- self.assertEqual(compat_shlex_split('-val 中文'), ['-val', '中文'])
-
- def test_compat_etree_Element(self):
- try:
- compat_etree_Element.items
- except AttributeError:
- self.fail('compat_etree_Element is not a type')
-
def test_compat_etree_fromstring(self):
xml = '''
<root foo="bar" spam="中文">
@@ -128,7 +90,7 @@ class TestCompat(unittest.TestCase):
<foo><bar>spam</bar></foo>
</root>
'''
- doc = compat_etree_fromstring(xml.encode('utf-8'))
+ doc = compat_etree_fromstring(xml.encode())
self.assertTrue(isinstance(doc.attrib['foo'], compat_str))
self.assertTrue(isinstance(doc.attrib['spam'], compat_str))
self.assertTrue(isinstance(doc.find('normal').text, compat_str))
diff --git a/test/test_cookies.py b/test/test_cookies.py
index 842ebcb99..5bfaec367 100644
--- a/test/test_cookies.py
+++ b/test/test_cookies.py
@@ -6,10 +6,10 @@ from yt_dlp.cookies import (
LinuxChromeCookieDecryptor,
MacChromeCookieDecryptor,
WindowsChromeCookieDecryptor,
- parse_safari_cookies,
- pbkdf2_sha1,
_get_linux_desktop_environment,
_LinuxDesktopEnvironment,
+ parse_safari_cookies,
+ pbkdf2_sha1,
)
diff --git a/test/test_download.py b/test/test_download.py
index 818a670fb..9a83bee2f 100755
--- a/test/test_download.py
+++ b/test/test_download.py
@@ -1,11 +1,12 @@
#!/usr/bin/env python3
-
-from __future__ import unicode_literals
-
# Allow direct execution
+import hashlib
+import json
import os
+import socket
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from test.helper import (
@@ -19,25 +20,19 @@ from test.helper import (
try_rm,
)
-
-import hashlib
-import io
-import json
-import socket
-
import yt_dlp.YoutubeDL
from yt_dlp.compat import (
compat_http_client,
- compat_urllib_error,
compat_HTTPError,
+ compat_urllib_error,
)
+from yt_dlp.extractor import get_info_extractor
from yt_dlp.utils import (
DownloadError,
ExtractorError,
- format_bytes,
UnavailableVideoError,
+ format_bytes,
)
-from yt_dlp.extractor import get_info_extractor
RETRIES = 3
@@ -46,7 +41,7 @@ class YoutubeDL(yt_dlp.YoutubeDL):
def __init__(self, *args, **kwargs):
self.to_stderr = self.to_screen
self.processed_info_dicts = []
- super(YoutubeDL, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
def report_warning(self, message):
# Don't accept warnings during tests
@@ -54,7 +49,7 @@ class YoutubeDL(yt_dlp.YoutubeDL):
def process_info(self, info_dict):
self.processed_info_dicts.append(info_dict.copy())
- return super(YoutubeDL, self).process_info(info_dict)
+ return super().process_info(info_dict)
def _file_md5(fn):
@@ -80,7 +75,7 @@ class TestDownload(unittest.TestCase):
def strclass(cls):
"""From 2.7's unittest; 2.6 had _strclass so we can't import it."""
- return '%s.%s' % (cls.__module__, cls.__name__)
+ return f'{cls.__module__}.{cls.__name__}'
add_ie = getattr(self, self._testMethodName).add_ie
return '%s (%s)%s:' % (self._testMethodName,
@@ -179,7 +174,7 @@ def generator(test_case, tname):
report_warning('%s failed due to network errors, skipping...' % tname)
return
- print('Retrying: {0} failed tries\n\n##########\n\n'.format(try_num))
+ print(f'Retrying: {try_num} failed tries\n\n##########\n\n')
try_num += 1
else:
@@ -245,7 +240,7 @@ def generator(test_case, tname):
self.assertTrue(
os.path.exists(info_json_fn),
'Missing info file %s' % info_json_fn)
- with io.open(info_json_fn, encoding='utf-8') as infof:
+ with open(info_json_fn, encoding='utf-8') as infof:
info_dict = json.load(infof)
expect_info_dict(self, info_dict, tc.get('info_dict', {}))
finally:
diff --git a/test/test_downloader_http.py b/test/test_downloader_http.py
index 03ae8c62a..c33308064 100644
--- a/test/test_downloader_http.py
+++ b/test/test_downloader_http.py
@@ -1,20 +1,19 @@
#!/usr/bin/env python3
-# coding: utf-8
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import re
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import threading
from test.helper import http_server_port, try_rm
+
from yt_dlp import YoutubeDL
from yt_dlp.compat import compat_http_server
from yt_dlp.downloader.http import HttpFD
from yt_dlp.utils import encodeFilename
-import threading
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
@@ -66,7 +65,7 @@ class HTTPTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
assert False
-class FakeLogger(object):
+class FakeLogger:
def debug(self, msg):
pass
diff --git a/test/test_execution.py b/test/test_execution.py
index cf6b6b913..6efd432e9 100644
--- a/test/test_execution.py
+++ b/test/test_execution.py
@@ -1,13 +1,10 @@
#!/usr/bin/env python3
-# coding: utf-8
-
-from __future__ import unicode_literals
-
-import unittest
-
-import sys
+import contextlib
import os
import subprocess
+import sys
+import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from yt_dlp.utils import encodeArgument
@@ -26,15 +23,14 @@ 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', '--ignore-config', '--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)
+ subprocess.check_call([sys.executable, 'yt_dlp/__main__.py', '--ignore-config', '--version'], cwd=rootDir, stdout=_DEV_NULL)
def test_cmdline_umlauts(self):
p = subprocess.Popen(
- [sys.executable, 'yt_dlp/__main__.py', encodeArgument('ä'), '--version'],
+ [sys.executable, 'yt_dlp/__main__.py', '--ignore-config', encodeArgument('ä'), '--version'],
cwd=rootDir, stdout=_DEV_NULL, stderr=subprocess.PIPE)
_, stderr = p.communicate()
self.assertFalse(stderr)
@@ -44,10 +40,8 @@ class TestExecution(unittest.TestCase):
subprocess.check_call([sys.executable, 'devscripts/make_lazy_extractors.py', 'yt_dlp/extractor/lazy_extractors.py'], cwd=rootDir, stdout=_DEV_NULL)
subprocess.check_call([sys.executable, 'test/test_all_urls.py'], cwd=rootDir, stdout=_DEV_NULL)
finally:
- try:
+ with contextlib.suppress(OSError):
os.remove('yt_dlp/extractor/lazy_extractors.py')
- except (IOError, OSError):
- pass
if __name__ == '__main__':
diff --git a/test/test_http.py b/test/test_http.py
index 40df167e0..146df7500 100644
--- a/test/test_http.py
+++ b/test/test_http.py
@@ -1,18 +1,17 @@
#!/usr/bin/env python3
-# coding: utf-8
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+import ssl
+import threading
from test.helper import http_server_port
+
from yt_dlp import YoutubeDL
from yt_dlp.compat import compat_http_server, compat_urllib_request
-import ssl
-import threading
TEST_DIR = os.path.dirname(os.path.abspath(__file__))
@@ -32,17 +31,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')
@@ -52,7 +40,7 @@ class HTTPTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
assert False
-class FakeLogger(object):
+class FakeLogger:
def debug(self, msg):
pass
@@ -72,40 +60,75 @@ 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):
certfn = os.path.join(TEST_DIR, 'testcert.pem')
self.httpd = compat_http_server.HTTPServer(
('127.0.0.1', 0), HTTPTestRequestHandler)
- self.httpd.socket = ssl.wrap_socket(
- self.httpd.socket, certfile=certfn, server_side=True)
+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ sslctx.load_cert_chain(certfn, None)
+ self.httpd.socket = sslctx.wrap_socket(self.httpd.socket, server_side=True)
self.port = http_server_port(self.httpd)
self.server_thread = threading.Thread(target=self.httpd.serve_forever)
self.server_thread.daemon = True
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)
self.assertEqual(r['entries'][0]['url'], 'https://127.0.0.1:%d/vid.mp4' % self.port)
+class TestClientCert(unittest.TestCase):
+ def setUp(self):
+ certfn = os.path.join(TEST_DIR, 'testcert.pem')
+ self.certdir = os.path.join(TEST_DIR, 'testdata', 'certificate')
+ cacertfn = os.path.join(self.certdir, 'ca.crt')
+ self.httpd = compat_http_server.HTTPServer(('127.0.0.1', 0), HTTPTestRequestHandler)
+ sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
+ sslctx.verify_mode = ssl.CERT_REQUIRED
+ sslctx.load_verify_locations(cafile=cacertfn)
+ sslctx.load_cert_chain(certfn, None)
+ self.httpd.socket = sslctx.wrap_socket(self.httpd.socket, server_side=True)
+ self.port = http_server_port(self.httpd)
+ self.server_thread = threading.Thread(target=self.httpd.serve_forever)
+ self.server_thread.daemon = True
+ self.server_thread.start()
+
+ def _run_test(self, **params):
+ ydl = YoutubeDL({
+ 'logger': FakeLogger(),
+ # Disable client-side validation of unacceptable self-signed testcert.pem
+ # The test is of a check on the server side, so unaffected
+ 'nocheckcertificate': True,
+ **params,
+ })
+ r = ydl.extract_info('https://127.0.0.1:%d/video.html' % self.port)
+ self.assertEqual(r['entries'][0]['url'], 'https://127.0.0.1:%d/vid.mp4' % self.port)
+
+ def test_certificate_combined_nopass(self):
+ self._run_test(client_certificate=os.path.join(self.certdir, 'clientwithkey.crt'))
+
+ def test_certificate_nocombined_nopass(self):
+ self._run_test(client_certificate=os.path.join(self.certdir, 'client.crt'),
+ client_certificate_key=os.path.join(self.certdir, 'client.key'))
+
+ def test_certificate_combined_pass(self):
+ self._run_test(client_certificate=os.path.join(self.certdir, 'clientwithencryptedkey.crt'),
+ client_certificate_password='foobar')
+
+ def test_certificate_nocombined_pass(self):
+ self._run_test(client_certificate=os.path.join(self.certdir, 'client.crt'),
+ client_certificate_key=os.path.join(self.certdir, 'clientencrypted.key'),
+ client_certificate_password='foobar')
+
+
def _build_proxy_handler(name):
class HTTPTestRequestHandler(compat_http_server.BaseHTTPRequestHandler):
proxy_name = name
@@ -117,7 +140,7 @@ def _build_proxy_handler(name):
self.send_response(200)
self.send_header('Content-Type', 'text/plain; charset=utf-8')
self.end_headers()
- self.wfile.write('{self.proxy_name}: {self.path}'.format(self=self).encode('utf-8'))
+ self.wfile.write(f'{self.proxy_name}: {self.path}'.encode())
return HTTPTestRequestHandler
@@ -138,26 +161,26 @@ class TestProxy(unittest.TestCase):
self.geo_proxy_thread.start()
def test_proxy(self):
- geo_proxy = '127.0.0.1:{0}'.format(self.geo_port)
+ geo_proxy = f'127.0.0.1:{self.geo_port}'
ydl = YoutubeDL({
- 'proxy': '127.0.0.1:{0}'.format(self.port),
+ 'proxy': f'127.0.0.1:{self.port}',
'geo_verification_proxy': geo_proxy,
})
url = 'http://foo.com/bar'
- response = ydl.urlopen(url).read().decode('utf-8')
- self.assertEqual(response, 'normal: {0}'.format(url))
+ response = ydl.urlopen(url).read().decode()
+ self.assertEqual(response, f'normal: {url}')
req = compat_urllib_request.Request(url)
req.add_header('Ytdl-request-proxy', geo_proxy)
- response = ydl.urlopen(req).read().decode('utf-8')
- self.assertEqual(response, 'geo: {0}'.format(url))
+ response = ydl.urlopen(req).read().decode()
+ self.assertEqual(response, f'geo: {url}')
def test_proxy_with_idn(self):
ydl = YoutubeDL({
- 'proxy': '127.0.0.1:{0}'.format(self.port),
+ 'proxy': f'127.0.0.1:{self.port}',
})
url = 'http://中文.tw/'
- response = ydl.urlopen(url).read().decode('utf-8')
+ response = ydl.urlopen(url).read().decode()
# b'xn--fiq228c' is '中文'.encode('idna')
self.assertEqual(response, 'normal: http://xn--fiq228c.tw/')
diff --git a/test/test_jsinterp.py b/test/test_jsinterp.py
index e230b045f..872c58c8f 100644
--- a/test/test_jsinterp.py
+++ b/test/test_jsinterp.py
@@ -1,11 +1,9 @@
#!/usr/bin/env python3
-
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from yt_dlp.jsinterp import JSInterpreter
diff --git a/test/test_netrc.py b/test/test_netrc.py
index 94a703406..f7a0b33d2 100644
--- a/test/test_netrc.py
+++ b/test/test_netrc.py
@@ -1,9 +1,7 @@
-# coding: utf-8
-from __future__ import unicode_literals
-
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
diff --git a/test/test_overwrites.py b/test/test_overwrites.py
index f5d10a409..a6d5bae40 100644
--- a/test/test_overwrites.py
+++ b/test/test_overwrites.py
@@ -1,18 +1,15 @@
#!/usr/bin/env python3
-from __future__ import unicode_literals
-
import os
-from os.path import join
import subprocess
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from test.helper import is_download_test, try_rm
-
root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-download_file = join(root_dir, 'test.webm')
+download_file = os.path.join(root_dir, 'test.webm')
@is_download_test
@@ -46,7 +43,7 @@ class TestOverwrites(unittest.TestCase):
self.assertTrue(os.path.getsize(download_file) > 1)
def tearDown(self):
- try_rm(join(root_dir, 'test.webm'))
+ try_rm(os.path.join(root_dir, 'test.webm'))
if __name__ == '__main__':
diff --git a/test/test_post_hooks.py b/test/test_post_hooks.py
index 1555a23e0..e84a08f29 100644
--- a/test/test_post_hooks.py
+++ b/test/test_post_hooks.py
@@ -1,20 +1,19 @@
#!/usr/bin/env python3
-
-from __future__ import unicode_literals
-
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from test.helper import get_params, try_rm, is_download_test
+from test.helper import get_params, is_download_test, try_rm
+
import yt_dlp.YoutubeDL
from yt_dlp.utils import DownloadError
class YoutubeDL(yt_dlp.YoutubeDL):
def __init__(self, *args, **kwargs):
- super(YoutubeDL, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
self.to_stderr = self.to_screen
diff --git a/test/test_postprocessors.py b/test/test_postprocessors.py
index bbe998993..9d8a4dcc5 100644
--- a/test/test_postprocessors.py
+++ b/test/test_postprocessors.py
@@ -1,7 +1,4 @@
#!/usr/bin/env python3
-
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
@@ -16,7 +13,7 @@ from yt_dlp.postprocessor import (
FFmpegThumbnailsConvertorPP,
MetadataFromFieldPP,
MetadataParserPP,
- ModifyChaptersPP
+ ModifyChaptersPP,
)
diff --git a/test/test_socks.py b/test/test_socks.py
index cf1f613ab..a8b068cdd 100644
--- a/test/test_socks.py
+++ b/test/test_socks.py
@@ -1,25 +1,16 @@
#!/usr/bin/env python3
-# coding: utf-8
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import random
import subprocess
+from test.helper import FakeYDL, get_params, is_download_test
-from test.helper import (
- FakeYDL,
- get_params,
- is_download_test,
-)
-from yt_dlp.compat import (
- compat_str,
- compat_urllib_request,
-)
+from yt_dlp.compat import compat_str, compat_urllib_request
@is_download_test
@@ -41,7 +32,7 @@ class TestMultipleSocks(unittest.TestCase):
'proxy': params['primary_proxy']
})
self.assertEqual(
- ydl.urlopen('http://yt-dl.org/ip').read().decode('utf-8'),
+ ydl.urlopen('http://yt-dl.org/ip').read().decode(),
params['primary_server_ip'])
def test_proxy_https(self):
@@ -52,7 +43,7 @@ class TestMultipleSocks(unittest.TestCase):
'proxy': params['primary_proxy']
})
self.assertEqual(
- ydl.urlopen('https://yt-dl.org/ip').read().decode('utf-8'),
+ ydl.urlopen('https://yt-dl.org/ip').read().decode(),
params['primary_server_ip'])
def test_secondary_proxy_http(self):
@@ -63,7 +54,7 @@ class TestMultipleSocks(unittest.TestCase):
req = compat_urllib_request.Request('http://yt-dl.org/ip')
req.add_header('Ytdl-request-proxy', params['secondary_proxy'])
self.assertEqual(
- ydl.urlopen(req).read().decode('utf-8'),
+ ydl.urlopen(req).read().decode(),
params['secondary_server_ip'])
def test_secondary_proxy_https(self):
@@ -74,7 +65,7 @@ class TestMultipleSocks(unittest.TestCase):
req = compat_urllib_request.Request('https://yt-dl.org/ip')
req.add_header('Ytdl-request-proxy', params['secondary_proxy'])
self.assertEqual(
- ydl.urlopen(req).read().decode('utf-8'),
+ ydl.urlopen(req).read().decode(),
params['secondary_server_ip'])
@@ -105,7 +96,7 @@ class TestSocks(unittest.TestCase):
ydl = FakeYDL({
'proxy': '%s://127.0.0.1:%d' % (protocol, self.port),
})
- return ydl.urlopen('http://yt-dl.org/ip').read().decode('utf-8')
+ return ydl.urlopen('http://yt-dl.org/ip').read().decode()
def test_socks4(self):
self.assertTrue(isinstance(self._get_ip('socks4'), compat_str))
diff --git a/test/test_subtitles.py b/test/test_subtitles.py
index 95e33e54a..182bd7a4b 100644
--- a/test/test_subtitles.py
+++ b/test/test_subtitles.py
@@ -1,33 +1,31 @@
#!/usr/bin/env python3
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
-sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-from test.helper import FakeYDL, md5, is_download_test
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from test.helper import FakeYDL, is_download_test, md5
from yt_dlp.extractor import (
- YoutubeIE,
- DailymotionIE,
- TedTalkIE,
- VimeoIE,
- WallaIE,
- CeskaTelevizeIE,
- LyndaIE,
NPOIE,
+ NRKTVIE,
PBSIE,
+ CeskaTelevizeIE,
ComedyCentralIE,
- NRKTVIE,
+ DailymotionIE,
+ DemocracynowIE,
+ LyndaIE,
RaiPlayIE,
- VikiIE,
- ThePlatformIE,
- ThePlatformFeedIE,
RTVEALaCartaIE,
- DemocracynowIE,
+ TedTalkIE,
+ ThePlatformFeedIE,
+ ThePlatformIE,
+ VikiIE,
+ VimeoIE,
+ WallaIE,
+ YoutubeIE,
)
@@ -53,8 +51,8 @@ class BaseTestSubtitles(unittest.TestCase):
for sub_info in subtitles.values():
if sub_info.get('data') is None:
uf = self.DL.urlopen(sub_info['url'])
- sub_info['data'] = uf.read().decode('utf-8')
- return dict((l, sub_info['data']) for l, sub_info in subtitles.items())
+ sub_info['data'] = uf.read().decode()
+ return {l: sub_info['data'] for l, sub_info in subtitles.items()}
@is_download_test
@@ -163,7 +161,7 @@ class TestVimeoSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['de', 'en', 'es', 'fr']))
+ self.assertEqual(set(subtitles.keys()), {'de', 'en', 'es', 'fr'})
self.assertEqual(md5(subtitles['en']), '8062383cf4dec168fc40a088aa6d5888')
self.assertEqual(md5(subtitles['fr']), 'b6191146a6c5d3a452244d853fde6dc8')
@@ -186,7 +184,7 @@ class TestWallaSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['heb']))
+ self.assertEqual(set(subtitles.keys()), {'heb'})
self.assertEqual(md5(subtitles['heb']), 'e758c5d7cb982f6bef14f377ec7a3920')
def test_nosubtitles(self):
@@ -208,7 +206,7 @@ class TestCeskaTelevizeSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['cs']))
+ self.assertEqual(set(subtitles.keys()), {'cs'})
self.assertTrue(len(subtitles['cs']) > 20000)
def test_nosubtitles(self):
@@ -229,7 +227,7 @@ class TestLyndaSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
self.assertEqual(md5(subtitles['en']), '09bbe67222259bed60deaa26997d73a7')
@@ -242,7 +240,7 @@ class TestNPOSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['nl']))
+ self.assertEqual(set(subtitles.keys()), {'nl'})
self.assertEqual(md5(subtitles['nl']), 'fc6435027572b63fb4ab143abd5ad3f4')
@@ -252,13 +250,13 @@ class TestMTVSubtitles(BaseTestSubtitles):
IE = ComedyCentralIE
def getInfoDict(self):
- return super(TestMTVSubtitles, self).getInfoDict()['entries'][0]
+ return super().getInfoDict()['entries'][0]
def test_allsubtitles(self):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
self.assertEqual(md5(subtitles['en']), '78206b8d8a0cfa9da64dc026eea48961')
@@ -271,7 +269,7 @@ class TestNRKSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['no']))
+ self.assertEqual(set(subtitles.keys()), {'no'})
self.assertEqual(md5(subtitles['no']), '544fa917d3197fcbee64634559221cc2')
@@ -284,7 +282,7 @@ class TestRaiPlaySubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['it']))
+ self.assertEqual(set(subtitles.keys()), {'it'})
self.assertEqual(md5(subtitles['it']), 'b1d90a98755126b61e667567a1f6680a')
def test_subtitles_array_key(self):
@@ -292,7 +290,7 @@ class TestRaiPlaySubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['it']))
+ self.assertEqual(set(subtitles.keys()), {'it'})
self.assertEqual(md5(subtitles['it']), '4b3264186fbb103508abe5311cfcb9cd')
@@ -305,7 +303,7 @@ class TestVikiSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
self.assertEqual(md5(subtitles['en']), '53cb083a5914b2d84ef1ab67b880d18a')
@@ -320,7 +318,7 @@ class TestThePlatformSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
self.assertEqual(md5(subtitles['en']), '97e7670cbae3c4d26ae8bcc7fdd78d4b')
@@ -333,7 +331,7 @@ class TestThePlatformFeedSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
self.assertEqual(md5(subtitles['en']), '48649a22e82b2da21c9a67a395eedade')
@@ -348,7 +346,7 @@ class TestRtveSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['es']))
+ self.assertEqual(set(subtitles.keys()), {'es'})
self.assertEqual(md5(subtitles['es']), '69e70cae2d40574fb7316f31d6eb7fca')
@@ -361,7 +359,7 @@ class TestDemocracynowSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
self.assertEqual(md5(subtitles['en']), 'acaca989e24a9e45a6719c9b3d60815c')
def test_subtitles_in_page(self):
@@ -369,7 +367,7 @@ class TestDemocracynowSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
self.assertEqual(md5(subtitles['en']), 'acaca989e24a9e45a6719c9b3d60815c')
@@ -382,7 +380,7 @@ class TestPBSSubtitles(BaseTestSubtitles):
self.DL.params['writesubtitles'] = True
self.DL.params['allsubtitles'] = True
subtitles = self.getSubtitles()
- self.assertEqual(set(subtitles.keys()), set(['en']))
+ self.assertEqual(set(subtitles.keys()), {'en'})
def test_subtitles_dfxp_format(self):
self.DL.params['writesubtitles'] = True
diff --git a/test/test_utils.py b/test/test_utils.py
index 1f826c2f2..184c39cff 100644
--- a/test/test_utils.py
+++ b/test/test_utils.py
@@ -1,12 +1,10 @@
#!/usr/bin/env python3
-# coding: utf-8
-
-from __future__ import unicode_literals
-
# Allow direct execution
+import contextlib
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
@@ -16,75 +14,95 @@ import itertools
import json
import xml.etree.ElementTree
+from yt_dlp.compat import (
+ compat_chr,
+ compat_etree_fromstring,
+ compat_getenv,
+ compat_HTMLParseError,
+ compat_os_name,
+ compat_setenv,
+)
from yt_dlp.utils import (
+ Config,
+ DateRange,
+ ExtractorError,
+ InAdvancePagedList,
+ LazyList,
+ OnDemandPagedList,
age_restricted,
args_to_str,
- encode_base_n,
+ base_url,
caesar,
clean_html,
clean_podcast_url,
- Config,
+ cli_bool_option,
+ cli_option,
+ cli_valueless_option,
date_from_str,
datetime_from_str,
- DateRange,
detect_exe_version,
determine_ext,
+ dfxp2srt,
dict_get,
+ encode_base_n,
encode_compat_str,
encodeFilename,
escape_rfc3986,
escape_url,
+ expand_path,
extract_attributes,
- ExtractorError,
find_xpath_attr,
fix_xml_ampersands,
- format_bytes,
float_or_none,
- get_element_by_class,
+ format_bytes,
get_element_by_attribute,
- get_elements_by_class,
- get_elements_by_attribute,
- get_element_html_by_class,
+ get_element_by_class,
get_element_html_by_attribute,
- get_elements_html_by_class,
+ get_element_html_by_class,
+ get_element_text_and_html_by_tag,
+ get_elements_by_attribute,
+ get_elements_by_class,
get_elements_html_by_attribute,
+ get_elements_html_by_class,
get_elements_text_and_html_by_attribute,
- get_element_text_and_html_by_tag,
- InAdvancePagedList,
int_or_none,
intlist_to_bytes,
+ iri_to_uri,
is_html,
js_to_json,
limit_length,
locked_file,
+ lowercase_escape,
+ match_str,
merge_dicts,
mimetype2ext,
month_by_name,
multipart_encode,
ohdave_rsa_encrypt,
- OnDemandPagedList,
orderedSet,
parse_age_limit,
+ parse_bitrate,
+ parse_codecs,
+ parse_count,
+ parse_dfxp_time_expr,
parse_duration,
parse_filesize,
- parse_count,
parse_iso8601,
- parse_resolution,
- parse_bitrate,
parse_qs,
+ parse_resolution,
pkcs1pad,
+ prepend_extension,
read_batch_urls,
+ remove_end,
+ remove_quotes,
+ remove_start,
+ render_table,
+ replace_extension,
+ rot47,
sanitize_filename,
sanitize_path,
sanitize_url,
sanitized_Request,
- expand_path,
- prepend_extension,
- replace_extension,
- remove_start,
- remove_end,
- remove_quotes,
- rot47,
shell_quote,
smuggle_url,
str_to_int,
@@ -96,38 +114,18 @@ from yt_dlp.utils import (
unified_strdate,
unified_timestamp,
unsmuggle_url,
+ update_url_query,
uppercase_escape,
- lowercase_escape,
url_basename,
url_or_none,
- base_url,
- urljoin,
urlencode_postdata,
+ urljoin,
urshift,
- update_url_query,
version_tuple,
- xpath_with_ns,
+ xpath_attr,
xpath_element,
xpath_text,
- xpath_attr,
- render_table,
- match_str,
- parse_dfxp_time_expr,
- dfxp2srt,
- cli_option,
- cli_valueless_option,
- cli_bool_option,
- parse_codecs,
- iri_to_uri,
- LazyList,
-)
-from yt_dlp.compat import (
- compat_chr,
- compat_etree_fromstring,
- compat_getenv,
- compat_HTMLParseError,
- compat_os_name,
- compat_setenv,
+ xpath_with_ns,
)
@@ -266,15 +264,22 @@ class TestUtil(unittest.TestCase):
def test_expand_path(self):
def env(var):
- return '%{0}%'.format(var) if sys.platform == 'win32' else '${0}'.format(var)
+ return f'%{var}%' if sys.platform == 'win32' else f'${var}'
compat_setenv('yt_dlp_EXPATH_PATH', 'expanded')
self.assertEqual(expand_path(env('yt_dlp_EXPATH_PATH')), 'expanded')
- self.assertEqual(expand_path(env('HOME')), compat_getenv('HOME'))
- self.assertEqual(expand_path('~'), compat_getenv('HOME'))
- self.assertEqual(
- expand_path('~/%s' % env('yt_dlp_EXPATH_PATH')),
- '%s/expanded' % compat_getenv('HOME'))
+
+ old_home = os.environ.get('HOME')
+ test_str = R'C:\Documents and Settings\тест\Application Data'
+ try:
+ compat_setenv('HOME', test_str)
+ self.assertEqual(expand_path(env('HOME')), compat_getenv('HOME'))
+ self.assertEqual(expand_path('~'), compat_getenv('HOME'))
+ self.assertEqual(
+ expand_path('~/%s' % env('yt_dlp_EXPATH_PATH')),
+ '%s/expanded' % compat_getenv('HOME'))
+ finally:
+ compat_setenv('HOME', old_home or '')
def test_prepend_extension(self):
self.assertEqual(prepend_extension('abc.ext', 'temp'), 'abc.temp.ext')
@@ -538,9 +543,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)
@@ -669,8 +671,7 @@ class TestUtil(unittest.TestCase):
def get_page(pagenum):
firstid = pagenum * pagesize
upto = min(size, pagenum * pagesize + pagesize)
- for i in range(firstid, upto):
- yield i
+ yield from range(firstid, upto)
pl = OnDemandPagedList(get_page, pagesize)
got = pl.getslice(*sliceargs)
@@ -739,7 +740,7 @@ class TestUtil(unittest.TestCase):
multipart_encode({b'field': b'value'}, boundary='AAAAAA')[0],
b'--AAAAAA\r\nContent-Disposition: form-data; name="field"\r\n\r\nvalue\r\n--AAAAAA--\r\n')
self.assertEqual(
- multipart_encode({'欄位'.encode('utf-8'): '值'.encode('utf-8')}, boundary='AAAAAA')[0],
+ multipart_encode({'欄位'.encode(): '值'.encode()}, boundary='AAAAAA')[0],
b'--AAAAAA\r\nContent-Disposition: form-data; name="\xe6\xac\x84\xe4\xbd\x8d"\r\n\r\n\xe5\x80\xbc\r\n--AAAAAA--\r\n')
self.assertRaises(
ValueError, multipart_encode, {b'field': b'value'}, boundary='value')
@@ -1400,7 +1401,7 @@ ffmpeg version 2.4.4 Copyright (c) 2000-2014 the FFmpeg ...'''), '2.4.4')
<p begin="3" dur="-1">Ignored, three</p>
</div>
</body>
- </tt>'''.encode('utf-8')
+ </tt>'''.encode()
srt_data = '''1
00:00:00,000 --> 00:00:01,000
The following line contains Chinese characters and special symbols
@@ -1418,14 +1419,14 @@ Line
'''
self.assertEqual(dfxp2srt(dfxp_data), srt_data)
- dfxp_data_no_default_namespace = '''<?xml version="1.0" encoding="UTF-8"?>
+ dfxp_data_no_default_namespace = b'''<?xml version="1.0" encoding="UTF-8"?>
<tt xml:lang="en" xmlns:tts="http://www.w3.org/ns/ttml#parameter">
<body>
<div xml:lang="en">
<p begin="0" end="1">The first line</p>
</div>
</body>
- </tt>'''.encode('utf-8')
+ </tt>'''
srt_data = '''1
00:00:00,000 --> 00:00:01,000
The first line
@@ -1433,7 +1434,7 @@ The first line
'''
self.assertEqual(dfxp2srt(dfxp_data_no_default_namespace), srt_data)
- dfxp_data_with_style = '''<?xml version="1.0" encoding="utf-8"?>
+ dfxp_data_with_style = b'''<?xml version="1.0" encoding="utf-8"?>
<tt xmlns="http://www.w3.org/2006/10/ttaf1" xmlns:ttp="http://www.w3.org/2006/10/ttaf1#parameter" ttp:timeBase="media" xmlns:tts="http://www.w3.org/2006/10/ttaf1#style" xml:lang="en" xmlns:ttm="http://www.w3.org/2006/10/ttaf1#metadata">
<head>
<styling>
@@ -1451,7 +1452,7 @@ The first line
<p style="s1" tts:textDecoration="underline" begin="00:00:09.56" id="p2" end="00:00:12.36"><span style="s2" tts:color="lime">inner<br /> </span>style</p>
</div>
</body>
-</tt>'''.encode('utf-8')
+</tt>'''
srt_data = '''1
00:00:02,080 --> 00:00:05,840
<font color="white" face="sansSerif" size="16">default style<font color="red">custom style</font></font>
@@ -1758,7 +1759,7 @@ Line 1
def test(ll, idx, val, cache):
self.assertEqual(ll[idx], val)
- self.assertEqual(getattr(ll, '_LazyList__cache'), list(cache))
+ self.assertEqual(ll._cache, list(cache))
ll = LazyList(range(10))
test(ll, 0, 0, range(1))
@@ -1821,10 +1822,8 @@ Line 1
else:
self.assertFalse(testing_write, f'{test_mode} is not blocked by {lock_mode}')
finally:
- try:
+ with contextlib.suppress(OSError):
os.remove(FILE)
- except Exception:
- pass
if __name__ == '__main__':
diff --git a/test/test_verbose_output.py b/test/test_verbose_output.py
index cc606115f..657994074 100644
--- a/test/test_verbose_output.py
+++ b/test/test_verbose_output.py
@@ -1,13 +1,9 @@
#!/usr/bin/env python3
-# coding: utf-8
-
-from __future__ import unicode_literals
-
-import unittest
-
-import sys
import os
import subprocess
+import sys
+import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
rootDir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -17,7 +13,8 @@ class TestVerboseOutput(unittest.TestCase):
def test_private_info_arg(self):
outp = subprocess.Popen(
[
- sys.executable, 'yt_dlp/__main__.py', '-v',
+ sys.executable, 'yt_dlp/__main__.py',
+ '-v', '--ignore-config',
'--username', 'johnsmith@gmail.com',
'--password', 'my_secret_password',
], cwd=rootDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -30,7 +27,8 @@ class TestVerboseOutput(unittest.TestCase):
def test_private_info_shortarg(self):
outp = subprocess.Popen(
[
- sys.executable, 'yt_dlp/__main__.py', '-v',
+ sys.executable, 'yt_dlp/__main__.py',
+ '-v', '--ignore-config',
'-u', 'johnsmith@gmail.com',
'-p', 'my_secret_password',
], cwd=rootDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -43,7 +41,8 @@ class TestVerboseOutput(unittest.TestCase):
def test_private_info_eq(self):
outp = subprocess.Popen(
[
- sys.executable, 'yt_dlp/__main__.py', '-v',
+ sys.executable, 'yt_dlp/__main__.py',
+ '-v', '--ignore-config',
'--username=johnsmith@gmail.com',
'--password=my_secret_password',
], cwd=rootDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -56,7 +55,8 @@ class TestVerboseOutput(unittest.TestCase):
def test_private_info_shortarg_eq(self):
outp = subprocess.Popen(
[
- sys.executable, 'yt_dlp/__main__.py', '-v',
+ sys.executable, 'yt_dlp/__main__.py',
+ '-v', '--ignore-config',
'-u=johnsmith@gmail.com',
'-p=my_secret_password',
], cwd=rootDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
diff --git a/test/test_youtube_lists.py b/test/test_youtube_lists.py
index 455192b1f..66611e236 100644
--- a/test/test_youtube_lists.py
+++ b/test/test_youtube_lists.py
@@ -1,18 +1,14 @@
#!/usr/bin/env python3
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from test.helper import FakeYDL, is_download_test
-from yt_dlp.extractor import (
- YoutubeIE,
- YoutubeTabIE,
-)
+from yt_dlp.extractor import YoutubeIE, YoutubeTabIE
@is_download_test
diff --git a/test/test_youtube_misc.py b/test/test_youtube_misc.py
index 402681cad..36f8be689 100644
--- a/test/test_youtube_misc.py
+++ b/test/test_youtube_misc.py
@@ -1,10 +1,9 @@
#!/usr/bin/env python3
-from __future__ import unicode_literals
-
# Allow direct execution
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
diff --git a/test/test_youtube_signature.py b/test/test_youtube_signature.py
index bbbba073f..2c2013295 100644
--- a/test/test_youtube_signature.py
+++ b/test/test_youtube_signature.py
@@ -1,21 +1,20 @@
#!/usr/bin/env python3
-
-from __future__ import unicode_literals
-
# Allow direct execution
+import contextlib
import os
import sys
import unittest
+
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-import io
import re
import string
-
+import urllib.request
from test.helper import FakeYDL, is_download_test
+
+from yt_dlp.compat import compat_str
from yt_dlp.extractor import YoutubeIE
from yt_dlp.jsinterp import JSInterpreter
-from yt_dlp.compat import compat_str, compat_urlretrieve
_SIG_TESTS = [
(
@@ -129,11 +128,9 @@ class TestSignature(unittest.TestCase):
os.mkdir(self.TESTDATA_DIR)
def tearDown(self):
- try:
+ with contextlib.suppress(OSError):
for f in os.listdir(self.TESTDATA_DIR):
os.remove(f)
- except OSError:
- pass
def t_factory(name, sig_func, url_pattern):
@@ -147,8 +144,8 @@ def t_factory(name, sig_func, url_pattern):
fn = os.path.join(self.TESTDATA_DIR, basename)
if not os.path.exists(fn):
- compat_urlretrieve(url, fn)
- with io.open(fn, encoding='utf-8') as testf:
+ urllib.request.urlretrieve(url, fn)
+ with open(fn, encoding='utf-8') as testf:
jscode = testf.read()
self.assertEqual(sig_func(jscode, sig_input), expected_sig)
diff --git a/test/testdata/certificate/ca.crt b/test/testdata/certificate/ca.crt
new file mode 100644
index 000000000..ddf7be7ad
--- /dev/null
+++ b/test/testdata/certificate/ca.crt
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBfDCCASOgAwIBAgIUUgngoxFpuWft8gjj3uEFoqJyoJowCgYIKoZIzj0EAwIw
+FDESMBAGA1UEAwwJeXRkbHB0ZXN0MB4XDTIyMDQxNTAzMDEwMVoXDTM4MTAxNTAz
+MDEwMVowFDESMBAGA1UEAwwJeXRkbHB0ZXN0MFkwEwYHKoZIzj0CAQYIKoZIzj0D
+AQcDQgAEcTaKMtIn2/1kgid1zXFpLm87FMT5PP3/bltKVVH3DLO//0kUslCHYxFU
+KpcCfVt9aueRyUFi1TNkkkEZ9D6fbqNTMFEwHQYDVR0OBBYEFBdY2rVNLFGM6r1F
+iuamNDaiq0QoMB8GA1UdIwQYMBaAFBdY2rVNLFGM6r1FiuamNDaiq0QoMA8GA1Ud
+EwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDRwAwRAIgXJg2jio1kow2g/iP54Qq+iI2
+m4EAvZiY0Im/Ni3PHawCIC6KCl6QcHANbeq8ckOXNGusjl6OWhvEM3uPBPhqskq1
+-----END CERTIFICATE-----
diff --git a/test/testdata/certificate/ca.key b/test/testdata/certificate/ca.key
new file mode 100644
index 000000000..38920d571
--- /dev/null
+++ b/test/testdata/certificate/ca.key
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIG2L1bHdl3PnaLiJ7Zm8aAGCj4GiVbSbXQcrJAdL+yqOoAoGCCqGSM49
+AwEHoUQDQgAEcTaKMtIn2/1kgid1zXFpLm87FMT5PP3/bltKVVH3DLO//0kUslCH
+YxFUKpcCfVt9aueRyUFi1TNkkkEZ9D6fbg==
+-----END EC PRIVATE KEY-----
diff --git a/test/testdata/certificate/ca.srl b/test/testdata/certificate/ca.srl
new file mode 100644
index 000000000..de2d1eab3
--- /dev/null
+++ b/test/testdata/certificate/ca.srl
@@ -0,0 +1 @@
+4A260C33C4D34612646E6321E1E767DF1A95EF0B
diff --git a/test/testdata/certificate/client.crt b/test/testdata/certificate/client.crt
new file mode 100644
index 000000000..874622fae
--- /dev/null
+++ b/test/testdata/certificate/client.crt
@@ -0,0 +1,9 @@
+-----BEGIN CERTIFICATE-----
+MIIBIzCBygIUSiYMM8TTRhJkbmMh4edn3xqV7wswCgYIKoZIzj0EAwIwFDESMBAG
+A1UEAwwJeXRkbHB0ZXN0MB4XDTIyMDQxNTAzMDEyN1oXDTM4MTAxNTAzMDEyN1ow
+FTETMBEGA1UEAwwKeXRkbHB0ZXN0MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
+BKREKVDWfLKZknzYg+BUkmTn43f2pl/LNSyKPtXo/UV7hhp6JXIq3ZuZ7rubyuMS
+XNuH+2Cl9msSpJB2LhJs5kcwCgYIKoZIzj0EAwIDSAAwRQIhAMRr46vO25/5nUhD
+aHp4L67AeSvrjvSFHfubyD3Kr5dwAiA8EfOgVxc8Qh6ozTcbXO/WnBfS48ZFRSQY
+D0dB8M1kJw==
+-----END CERTIFICATE-----
diff --git a/test/testdata/certificate/client.csr b/test/testdata/certificate/client.csr
new file mode 100644
index 000000000..2d5d7a5c1
--- /dev/null
+++ b/test/testdata/certificate/client.csr
@@ -0,0 +1,7 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIHQMHcCAQAwFTETMBEGA1UEAwwKeXRkbHB0ZXN0MjBZMBMGByqGSM49AgEGCCqG
+SM49AwEHA0IABKREKVDWfLKZknzYg+BUkmTn43f2pl/LNSyKPtXo/UV7hhp6JXIq
+3ZuZ7rubyuMSXNuH+2Cl9msSpJB2LhJs5kegADAKBggqhkjOPQQDAgNJADBGAiEA
+1LZ72mtPmVxhGtdMvpZ0fyA68H2RC5IMHpLq18T55UcCIQDKpkXXVTvAzS0JioCq
+6kiYq8Oxx6ZMoI+11k75/Kip1g==
+-----END CERTIFICATE REQUEST-----
diff --git a/test/testdata/certificate/client.key b/test/testdata/certificate/client.key
new file mode 100644
index 000000000..e47389b51
--- /dev/null
+++ b/test/testdata/certificate/client.key
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIAW6h9hwT0Aha+JBukgmHnrKRPoqPNWYA86ic0UaKHs8oAoGCCqGSM49
+AwEHoUQDQgAEpEQpUNZ8spmSfNiD4FSSZOfjd/amX8s1LIo+1ej9RXuGGnolcird
+m5nuu5vK4xJc24f7YKX2axKkkHYuEmzmRw==
+-----END EC PRIVATE KEY-----
diff --git a/test/testdata/certificate/clientencrypted.key b/test/testdata/certificate/clientencrypted.key
new file mode 100644
index 000000000..0baee37e9
--- /dev/null
+++ b/test/testdata/certificate/clientencrypted.key
@@ -0,0 +1,8 @@
+-----BEGIN EC PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,4B39160146F15544922E553E08299A35
+
+96A7/iBkIfTVb8r2812ued2pS49FfVY4Ppz/45OGF0uFayMtMl8/GuEBCamuhFXS
+rnOOpco96TTeeKZHqR45wnf4tgHM8IjoQ6H0EX3lVF19OHnArAgrGYtohWUGSyGn
+IgLJFdUewIjdI7XApTJprQFE5E2tETXFA95mCz88u1c=
+-----END EC PRIVATE KEY-----
diff --git a/test/testdata/certificate/clientwithencryptedkey.crt b/test/testdata/certificate/clientwithencryptedkey.crt
new file mode 100644
index 000000000..f357e4c95
--- /dev/null
+++ b/test/testdata/certificate/clientwithencryptedkey.crt
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIIBIzCBygIUSiYMM8TTRhJkbmMh4edn3xqV7wswCgYIKoZIzj0EAwIwFDESMBAG
+A1UEAwwJeXRkbHB0ZXN0MB4XDTIyMDQxNTAzMDEyN1oXDTM4MTAxNTAzMDEyN1ow
+FTETMBEGA1UEAwwKeXRkbHB0ZXN0MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
+BKREKVDWfLKZknzYg+BUkmTn43f2pl/LNSyKPtXo/UV7hhp6JXIq3ZuZ7rubyuMS
+XNuH+2Cl9msSpJB2LhJs5kcwCgYIKoZIzj0EAwIDSAAwRQIhAMRr46vO25/5nUhD
+aHp4L67AeSvrjvSFHfubyD3Kr5dwAiA8EfOgVxc8Qh6ozTcbXO/WnBfS48ZFRSQY
+D0dB8M1kJw==
+-----END CERTIFICATE-----
+-----BEGIN EC PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,4B39160146F15544922E553E08299A35
+
+96A7/iBkIfTVb8r2812ued2pS49FfVY4Ppz/45OGF0uFayMtMl8/GuEBCamuhFXS
+rnOOpco96TTeeKZHqR45wnf4tgHM8IjoQ6H0EX3lVF19OHnArAgrGYtohWUGSyGn
+IgLJFdUewIjdI7XApTJprQFE5E2tETXFA95mCz88u1c=
+-----END EC PRIVATE KEY-----
diff --git a/test/testdata/certificate/clientwithkey.crt b/test/testdata/certificate/clientwithkey.crt
new file mode 100644
index 000000000..942f6e2a4
--- /dev/null
+++ b/test/testdata/certificate/clientwithkey.crt
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIIBIzCBygIUSiYMM8TTRhJkbmMh4edn3xqV7wswCgYIKoZIzj0EAwIwFDESMBAG
+A1UEAwwJeXRkbHB0ZXN0MB4XDTIyMDQxNTAzMDEyN1oXDTM4MTAxNTAzMDEyN1ow
+FTETMBEGA1UEAwwKeXRkbHB0ZXN0MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA
+BKREKVDWfLKZknzYg+BUkmTn43f2pl/LNSyKPtXo/UV7hhp6JXIq3ZuZ7rubyuMS
+XNuH+2Cl9msSpJB2LhJs5kcwCgYIKoZIzj0EAwIDSAAwRQIhAMRr46vO25/5nUhD
+aHp4L67AeSvrjvSFHfubyD3Kr5dwAiA8EfOgVxc8Qh6ozTcbXO/WnBfS48ZFRSQY
+D0dB8M1kJw==
+-----END CERTIFICATE-----
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIAW6h9hwT0Aha+JBukgmHnrKRPoqPNWYA86ic0UaKHs8oAoGCCqGSM49
+AwEHoUQDQgAEpEQpUNZ8spmSfNiD4FSSZOfjd/amX8s1LIo+1ej9RXuGGnolcird
+m5nuu5vK4xJc24f7YKX2axKkkHYuEmzmRw==
+-----END EC PRIVATE KEY-----
diff --git a/test/testdata/certificate/instructions.md b/test/testdata/certificate/instructions.md
new file mode 100644
index 000000000..b0e3fbd48
--- /dev/null
+++ b/test/testdata/certificate/instructions.md
@@ -0,0 +1,19 @@
+# Generate certificates for client cert tests
+
+## CA
+```sh
+openssl ecparam -name prime256v1 -genkey -noout -out ca.key
+openssl req -new -x509 -sha256 -days 6027 -key ca.key -out ca.crt -subj "/CN=ytdlptest"
+```
+
+## Client
+```sh
+openssl ecparam -name prime256v1 -genkey -noout -out client.key
+openssl ec -in client.key -out clientencrypted.key -passout pass:foobar -aes256
+openssl req -new -sha256 -key client.key -out client.csr -subj "/CN=ytdlptest2"
+openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 6027 -sha256
+cp client.crt clientwithkey.crt
+cp client.crt clientwithencryptedkey.crt
+cat client.key >> clientwithkey.crt
+cat clientencrypted.key >> clientwithencryptedkey.crt
+``` \ No newline at end of file