mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-12-22 18:17:17 -05:00
Better error handling of syntax errors in -f
This commit is contained in:
parent
4ba001080f
commit
187986a857
@ -461,14 +461,13 @@ class TestFormatSelection(unittest.TestCase):
|
|||||||
|
|
||||||
def test_invalid_format_specs(self):
|
def test_invalid_format_specs(self):
|
||||||
def assert_syntax_error(format_spec):
|
def assert_syntax_error(format_spec):
|
||||||
ydl = YDL({'format': format_spec})
|
self.assertRaises(SyntaxError, YDL, {'format': format_spec})
|
||||||
info_dict = _make_result([{'format_id': 'foo', 'url': TEST_URL}])
|
|
||||||
self.assertRaises(SyntaxError, ydl.process_ie_result, info_dict)
|
|
||||||
|
|
||||||
assert_syntax_error('bestvideo,,best')
|
assert_syntax_error('bestvideo,,best')
|
||||||
assert_syntax_error('+bestaudio')
|
assert_syntax_error('+bestaudio')
|
||||||
assert_syntax_error('bestvideo+')
|
assert_syntax_error('bestvideo+')
|
||||||
assert_syntax_error('/')
|
assert_syntax_error('/')
|
||||||
|
assert_syntax_error('[720<height]')
|
||||||
|
|
||||||
def test_format_filtering(self):
|
def test_format_filtering(self):
|
||||||
formats = [
|
formats = [
|
||||||
|
@ -538,6 +538,11 @@ class YoutubeDL(object):
|
|||||||
|
|
||||||
self.outtmpl_dict = self.parse_outtmpl()
|
self.outtmpl_dict = self.parse_outtmpl()
|
||||||
|
|
||||||
|
# Creating format selector here allows us to catch syntax errors before the extraction
|
||||||
|
self.format_selector = (
|
||||||
|
None if self.params.get('format') is None
|
||||||
|
else self.build_format_selector(self.params['format']))
|
||||||
|
|
||||||
self._setup_opener()
|
self._setup_opener()
|
||||||
|
|
||||||
"""Preload the archive, if any is specified"""
|
"""Preload the archive, if any is specified"""
|
||||||
@ -1487,12 +1492,11 @@ class YoutubeDL(object):
|
|||||||
'!=': operator.ne,
|
'!=': operator.ne,
|
||||||
}
|
}
|
||||||
operator_rex = re.compile(r'''(?x)\s*
|
operator_rex = re.compile(r'''(?x)\s*
|
||||||
(?P<key>width|height|tbr|abr|vbr|asr|filesize|filesize_approx|fps)
|
(?P<key>width|height|tbr|abr|vbr|asr|filesize|filesize_approx|fps)\s*
|
||||||
\s*(?P<op>%s)(?P<none_inclusive>\s*\?)?\s*
|
(?P<op>%s)(?P<none_inclusive>\s*\?)?\s*
|
||||||
(?P<value>[0-9.]+(?:[kKmMgGtTpPeEzZyY]i?[Bb]?)?)
|
(?P<value>[0-9.]+(?:[kKmMgGtTpPeEzZyY]i?[Bb]?)?)\s*
|
||||||
$
|
|
||||||
''' % '|'.join(map(re.escape, OPERATORS.keys())))
|
''' % '|'.join(map(re.escape, OPERATORS.keys())))
|
||||||
m = operator_rex.search(filter_spec)
|
m = operator_rex.fullmatch(filter_spec)
|
||||||
if m:
|
if m:
|
||||||
try:
|
try:
|
||||||
comparison_value = int(m.group('value'))
|
comparison_value = int(m.group('value'))
|
||||||
@ -1513,13 +1517,12 @@ class YoutubeDL(object):
|
|||||||
'$=': lambda attr, value: attr.endswith(value),
|
'$=': lambda attr, value: attr.endswith(value),
|
||||||
'*=': lambda attr, value: value in attr,
|
'*=': lambda attr, value: value in attr,
|
||||||
}
|
}
|
||||||
str_operator_rex = re.compile(r'''(?x)
|
str_operator_rex = re.compile(r'''(?x)\s*
|
||||||
\s*(?P<key>[a-zA-Z0-9._-]+)
|
(?P<key>[a-zA-Z0-9._-]+)\s*
|
||||||
\s*(?P<negation>!\s*)?(?P<op>%s)(?P<none_inclusive>\s*\?)?
|
(?P<negation>!\s*)?(?P<op>%s)(?P<none_inclusive>\s*\?)?\s*
|
||||||
\s*(?P<value>[a-zA-Z0-9._-]+)
|
(?P<value>[a-zA-Z0-9._-]+)\s*
|
||||||
\s*$
|
|
||||||
''' % '|'.join(map(re.escape, STR_OPERATORS.keys())))
|
''' % '|'.join(map(re.escape, STR_OPERATORS.keys())))
|
||||||
m = str_operator_rex.search(filter_spec)
|
m = str_operator_rex.fullmatch(filter_spec)
|
||||||
if m:
|
if m:
|
||||||
comparison_value = m.group('value')
|
comparison_value = m.group('value')
|
||||||
str_op = STR_OPERATORS[m.group('op')]
|
str_op = STR_OPERATORS[m.group('op')]
|
||||||
@ -1529,7 +1532,7 @@ class YoutubeDL(object):
|
|||||||
op = str_op
|
op = str_op
|
||||||
|
|
||||||
if not m:
|
if not m:
|
||||||
raise ValueError('Invalid filter specification %r' % filter_spec)
|
raise SyntaxError('Invalid filter specification %r' % filter_spec)
|
||||||
|
|
||||||
def _filter(f):
|
def _filter(f):
|
||||||
actual_value = f.get(m.group('key'))
|
actual_value = f.get(m.group('key'))
|
||||||
@ -2118,12 +2121,11 @@ class YoutubeDL(object):
|
|||||||
self.list_formats(info_dict)
|
self.list_formats(info_dict)
|
||||||
return
|
return
|
||||||
|
|
||||||
req_format = self.params.get('format')
|
format_selector = self.format_selector
|
||||||
if req_format is None:
|
if format_selector is None:
|
||||||
req_format = self._default_format_spec(info_dict, download=download)
|
req_format = self._default_format_spec(info_dict, download=download)
|
||||||
self.write_debug('Default format spec: %s' % req_format)
|
self.write_debug('Default format spec: %s' % req_format)
|
||||||
|
format_selector = self.build_format_selector(req_format)
|
||||||
format_selector = self.build_format_selector(req_format)
|
|
||||||
|
|
||||||
# While in format selection we may need to have an access to the original
|
# While in format selection we may need to have an access to the original
|
||||||
# format set in order to calculate some metrics or do some processing.
|
# format set in order to calculate some metrics or do some processing.
|
||||||
|
Loading…
Reference in New Issue
Block a user