3 from __future__ import unicode_literals
5 # Allow direct execution
9 sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13 from test.helper import FakeYDL, assertRegexpMatches
14 from youtube_dl import YoutubeDL
15 from youtube_dl.compat import compat_str, compat_urllib_error
16 from youtube_dl.extractor import YoutubeIE
17 from youtube_dl.extractor.common import InfoExtractor
18 from youtube_dl.postprocessor.common import PostProcessor
19 from youtube_dl.utils import ExtractorError, match_filter_func
21 TEST_URL = 'http://localhost/sample.mp4'
25 def __init__(self, *args, **kwargs):
26 super(YDL, self).__init__(*args, **kwargs)
27 self.downloaded_info_dicts = []
30 def process_info(self, info_dict):
31 self.downloaded_info_dicts.append(info_dict)
33 def to_screen(self, msg):
37 def _make_result(formats, **kwargs):
41 'title': 'testttitle',
42 'extractor': 'testex',
48 class TestFormatSelection(unittest.TestCase):
49 def test_prefer_free_formats(self):
50 # Same resolution => download webm
52 ydl.params['prefer_free_formats'] = True
54 {'ext': 'webm', 'height': 460, 'url': TEST_URL},
55 {'ext': 'mp4', 'height': 460, 'url': TEST_URL},
57 info_dict = _make_result(formats)
59 yie._sort_formats(info_dict['formats'])
60 ydl.process_ie_result(info_dict)
61 downloaded = ydl.downloaded_info_dicts[0]
62 self.assertEqual(downloaded['ext'], 'webm')
64 # Different resolution => download best quality (mp4)
66 ydl.params['prefer_free_formats'] = True
68 {'ext': 'webm', 'height': 720, 'url': TEST_URL},
69 {'ext': 'mp4', 'height': 1080, 'url': TEST_URL},
71 info_dict['formats'] = formats
73 yie._sort_formats(info_dict['formats'])
74 ydl.process_ie_result(info_dict)
75 downloaded = ydl.downloaded_info_dicts[0]
76 self.assertEqual(downloaded['ext'], 'mp4')
78 # No prefer_free_formats => prefer mp4 and flv for greater compatibility
80 ydl.params['prefer_free_formats'] = False
82 {'ext': 'webm', 'height': 720, 'url': TEST_URL},
83 {'ext': 'mp4', 'height': 720, 'url': TEST_URL},
84 {'ext': 'flv', 'height': 720, 'url': TEST_URL},
86 info_dict['formats'] = formats
88 yie._sort_formats(info_dict['formats'])
89 ydl.process_ie_result(info_dict)
90 downloaded = ydl.downloaded_info_dicts[0]
91 self.assertEqual(downloaded['ext'], 'mp4')
94 ydl.params['prefer_free_formats'] = False
96 {'ext': 'flv', 'height': 720, 'url': TEST_URL},
97 {'ext': 'webm', 'height': 720, 'url': TEST_URL},
99 info_dict['formats'] = formats
101 yie._sort_formats(info_dict['formats'])
102 ydl.process_ie_result(info_dict)
103 downloaded = ydl.downloaded_info_dicts[0]
104 self.assertEqual(downloaded['ext'], 'flv')
106 def test_format_selection(self):
108 {'format_id': '35', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL},
109 {'format_id': 'example-with-dashes', 'ext': 'webm', 'preference': 1, 'url': TEST_URL},
110 {'format_id': '45', 'ext': 'webm', 'preference': 2, 'url': TEST_URL},
111 {'format_id': '47', 'ext': 'webm', 'preference': 3, 'url': TEST_URL},
112 {'format_id': '2', 'ext': 'flv', 'preference': 4, 'url': TEST_URL},
114 info_dict = _make_result(formats)
116 ydl = YDL({'format': '20/47'})
117 ydl.process_ie_result(info_dict.copy())
118 downloaded = ydl.downloaded_info_dicts[0]
119 self.assertEqual(downloaded['format_id'], '47')
121 ydl = YDL({'format': '20/71/worst'})
122 ydl.process_ie_result(info_dict.copy())
123 downloaded = ydl.downloaded_info_dicts[0]
124 self.assertEqual(downloaded['format_id'], '35')
127 ydl.process_ie_result(info_dict.copy())
128 downloaded = ydl.downloaded_info_dicts[0]
129 self.assertEqual(downloaded['format_id'], '2')
131 ydl = YDL({'format': 'webm/mp4'})
132 ydl.process_ie_result(info_dict.copy())
133 downloaded = ydl.downloaded_info_dicts[0]
134 self.assertEqual(downloaded['format_id'], '47')
136 ydl = YDL({'format': '3gp/40/mp4'})
137 ydl.process_ie_result(info_dict.copy())
138 downloaded = ydl.downloaded_info_dicts[0]
139 self.assertEqual(downloaded['format_id'], '35')
141 ydl = YDL({'format': 'example-with-dashes'})
142 ydl.process_ie_result(info_dict.copy())
143 downloaded = ydl.downloaded_info_dicts[0]
144 self.assertEqual(downloaded['format_id'], 'example-with-dashes')
146 def test_format_selection_audio(self):
148 {'format_id': 'audio-low', 'ext': 'webm', 'preference': 1, 'vcodec': 'none', 'url': TEST_URL},
149 {'format_id': 'audio-mid', 'ext': 'webm', 'preference': 2, 'vcodec': 'none', 'url': TEST_URL},
150 {'format_id': 'audio-high', 'ext': 'flv', 'preference': 3, 'vcodec': 'none', 'url': TEST_URL},
151 {'format_id': 'vid', 'ext': 'mp4', 'preference': 4, 'url': TEST_URL},
153 info_dict = _make_result(formats)
155 ydl = YDL({'format': 'bestaudio'})
156 ydl.process_ie_result(info_dict.copy())
157 downloaded = ydl.downloaded_info_dicts[0]
158 self.assertEqual(downloaded['format_id'], 'audio-high')
160 ydl = YDL({'format': 'worstaudio'})
161 ydl.process_ie_result(info_dict.copy())
162 downloaded = ydl.downloaded_info_dicts[0]
163 self.assertEqual(downloaded['format_id'], 'audio-low')
166 {'format_id': 'vid-low', 'ext': 'mp4', 'preference': 1, 'url': TEST_URL},
167 {'format_id': 'vid-high', 'ext': 'mp4', 'preference': 2, 'url': TEST_URL},
169 info_dict = _make_result(formats)
171 ydl = YDL({'format': 'bestaudio/worstaudio/best'})
172 ydl.process_ie_result(info_dict.copy())
173 downloaded = ydl.downloaded_info_dicts[0]
174 self.assertEqual(downloaded['format_id'], 'vid-high')
176 def test_format_selection_audio_exts(self):
178 {'format_id': 'mp3-64', 'ext': 'mp3', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
179 {'format_id': 'ogg-64', 'ext': 'ogg', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
180 {'format_id': 'aac-64', 'ext': 'aac', 'abr': 64, 'url': 'http://_', 'vcodec': 'none'},
181 {'format_id': 'mp3-32', 'ext': 'mp3', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
182 {'format_id': 'aac-32', 'ext': 'aac', 'abr': 32, 'url': 'http://_', 'vcodec': 'none'},
185 info_dict = _make_result(formats)
186 ydl = YDL({'format': 'best'})
188 ie._sort_formats(info_dict['formats'])
189 ydl.process_ie_result(copy.deepcopy(info_dict))
190 downloaded = ydl.downloaded_info_dicts[0]
191 self.assertEqual(downloaded['format_id'], 'aac-64')
193 ydl = YDL({'format': 'mp3'})
195 ie._sort_formats(info_dict['formats'])
196 ydl.process_ie_result(copy.deepcopy(info_dict))
197 downloaded = ydl.downloaded_info_dicts[0]
198 self.assertEqual(downloaded['format_id'], 'mp3-64')
200 ydl = YDL({'prefer_free_formats': True})
202 ie._sort_formats(info_dict['formats'])
203 ydl.process_ie_result(copy.deepcopy(info_dict))
204 downloaded = ydl.downloaded_info_dicts[0]
205 self.assertEqual(downloaded['format_id'], 'ogg-64')
207 def test_format_selection_video(self):
209 {'format_id': 'dash-video-low', 'ext': 'mp4', 'preference': 1, 'acodec': 'none', 'url': TEST_URL},
210 {'format_id': 'dash-video-high', 'ext': 'mp4', 'preference': 2, 'acodec': 'none', 'url': TEST_URL},
211 {'format_id': 'vid', 'ext': 'mp4', 'preference': 3, 'url': TEST_URL},
213 info_dict = _make_result(formats)
215 ydl = YDL({'format': 'bestvideo'})
216 ydl.process_ie_result(info_dict.copy())
217 downloaded = ydl.downloaded_info_dicts[0]
218 self.assertEqual(downloaded['format_id'], 'dash-video-high')
220 ydl = YDL({'format': 'worstvideo'})
221 ydl.process_ie_result(info_dict.copy())
222 downloaded = ydl.downloaded_info_dicts[0]
223 self.assertEqual(downloaded['format_id'], 'dash-video-low')
226 {'format_id': 'vid-vcodec-dot', 'ext': 'mp4', 'preference': 1, 'vcodec': 'avc1.123456', 'acodec': 'none', 'url': TEST_URL},
228 info_dict = _make_result(formats)
230 ydl = YDL({'format': 'bestvideo[vcodec=avc1.123456]'})
231 ydl.process_ie_result(info_dict.copy())
232 downloaded = ydl.downloaded_info_dicts[0]
233 self.assertEqual(downloaded['format_id'], 'vid-vcodec-dot')
235 def test_youtube_format_selection(self):
237 '38', '37', '46', '22', '45', '35', '44', '18', '34', '43', '6', '5', '17', '36', '13',
238 # Apple HTTP Live Streaming
239 '96', '95', '94', '93', '92', '132', '151',
241 '85', '84', '102', '83', '101', '82', '100',
243 '137', '248', '136', '247', '135', '246',
244 '245', '244', '134', '243', '133', '242', '160',
246 '141', '172', '140', '171', '139',
249 def format_info(f_id):
250 info = YoutubeIE._formats[f_id].copy()
252 # XXX: In real cases InfoExtractor._parse_mpd_formats() fills up 'acodec'
253 # and 'vcodec', while in tests such information is incomplete since
254 # commit a6c2c24479e5f4827ceb06f64d855329c0a6f593
255 # test_YoutubeDL.test_youtube_format_selection is broken without
257 if 'acodec' in info and 'vcodec' not in info:
258 info['vcodec'] = 'none'
259 elif 'vcodec' in info and 'acodec' not in info:
260 info['acodec'] = 'none'
262 info['format_id'] = f_id
263 info['url'] = 'url:' + f_id
265 formats_order = [format_info(f_id) for f_id in order]
267 info_dict = _make_result(list(formats_order), extractor='youtube')
268 ydl = YDL({'format': 'bestvideo+bestaudio'})
270 yie._sort_formats(info_dict['formats'])
271 ydl.process_ie_result(info_dict)
272 downloaded = ydl.downloaded_info_dicts[0]
273 self.assertEqual(downloaded['format_id'], '137+141')
274 self.assertEqual(downloaded['ext'], 'mp4')
276 info_dict = _make_result(list(formats_order), extractor='youtube')
277 ydl = YDL({'format': 'bestvideo[height>=999999]+bestaudio/best'})
279 yie._sort_formats(info_dict['formats'])
280 ydl.process_ie_result(info_dict)
281 downloaded = ydl.downloaded_info_dicts[0]
282 self.assertEqual(downloaded['format_id'], '38')
284 info_dict = _make_result(list(formats_order), extractor='youtube')
285 ydl = YDL({'format': 'bestvideo/best,bestaudio'})
287 yie._sort_formats(info_dict['formats'])
288 ydl.process_ie_result(info_dict)
289 downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts]
290 self.assertEqual(downloaded_ids, ['137', '141'])
292 info_dict = _make_result(list(formats_order), extractor='youtube')
293 ydl = YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])+bestaudio'})
295 yie._sort_formats(info_dict['formats'])
296 ydl.process_ie_result(info_dict)
297 downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts]
298 self.assertEqual(downloaded_ids, ['137+141', '248+141'])
300 info_dict = _make_result(list(formats_order), extractor='youtube')
301 ydl = YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])[height<=720]+bestaudio'})
303 yie._sort_formats(info_dict['formats'])
304 ydl.process_ie_result(info_dict)
305 downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts]
306 self.assertEqual(downloaded_ids, ['136+141', '247+141'])
308 info_dict = _make_result(list(formats_order), extractor='youtube')
309 ydl = YDL({'format': '(bestvideo[ext=none]/bestvideo[ext=webm])+bestaudio'})
311 yie._sort_formats(info_dict['formats'])
312 ydl.process_ie_result(info_dict)
313 downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts]
314 self.assertEqual(downloaded_ids, ['248+141'])
316 for f1, f2 in zip(formats_order, formats_order[1:]):
317 info_dict = _make_result([f1, f2], extractor='youtube')
318 ydl = YDL({'format': 'best/bestvideo'})
320 yie._sort_formats(info_dict['formats'])
321 ydl.process_ie_result(info_dict)
322 downloaded = ydl.downloaded_info_dicts[0]
323 self.assertEqual(downloaded['format_id'], f1['format_id'])
325 info_dict = _make_result([f2, f1], extractor='youtube')
326 ydl = YDL({'format': 'best/bestvideo'})
328 yie._sort_formats(info_dict['formats'])
329 ydl.process_ie_result(info_dict)
330 downloaded = ydl.downloaded_info_dicts[0]
331 self.assertEqual(downloaded['format_id'], f1['format_id'])
333 def test_invalid_format_specs(self):
334 def assert_syntax_error(format_spec):
335 ydl = YDL({'format': format_spec})
336 info_dict = _make_result([{'format_id': 'foo', 'url': TEST_URL}])
337 self.assertRaises(SyntaxError, ydl.process_ie_result, info_dict)
339 assert_syntax_error('bestvideo,,best')
340 assert_syntax_error('+bestaudio')
341 assert_syntax_error('bestvideo+')
342 assert_syntax_error('/')
344 def test_format_filtering(self):
346 {'format_id': 'A', 'filesize': 500, 'width': 1000},
347 {'format_id': 'B', 'filesize': 1000, 'width': 500},
348 {'format_id': 'C', 'filesize': 1000, 'width': 400},
349 {'format_id': 'D', 'filesize': 2000, 'width': 600},
350 {'format_id': 'E', 'filesize': 3000},
352 {'format_id': 'G', 'filesize': 1000000},
355 f['url'] = 'http://_/'
357 info_dict = _make_result(formats)
359 ydl = YDL({'format': 'best[filesize<3000]'})
360 ydl.process_ie_result(info_dict)
361 downloaded = ydl.downloaded_info_dicts[0]
362 self.assertEqual(downloaded['format_id'], 'D')
364 ydl = YDL({'format': 'best[filesize<=3000]'})
365 ydl.process_ie_result(info_dict)
366 downloaded = ydl.downloaded_info_dicts[0]
367 self.assertEqual(downloaded['format_id'], 'E')
369 ydl = YDL({'format': 'best[filesize <= ? 3000]'})
370 ydl.process_ie_result(info_dict)
371 downloaded = ydl.downloaded_info_dicts[0]
372 self.assertEqual(downloaded['format_id'], 'F')
374 ydl = YDL({'format': 'best [filesize = 1000] [width>450]'})
375 ydl.process_ie_result(info_dict)
376 downloaded = ydl.downloaded_info_dicts[0]
377 self.assertEqual(downloaded['format_id'], 'B')
379 ydl = YDL({'format': 'best [filesize = 1000] [width!=450]'})
380 ydl.process_ie_result(info_dict)
381 downloaded = ydl.downloaded_info_dicts[0]
382 self.assertEqual(downloaded['format_id'], 'C')
384 ydl = YDL({'format': '[filesize>?1]'})
385 ydl.process_ie_result(info_dict)
386 downloaded = ydl.downloaded_info_dicts[0]
387 self.assertEqual(downloaded['format_id'], 'G')
389 ydl = YDL({'format': '[filesize<1M]'})
390 ydl.process_ie_result(info_dict)
391 downloaded = ydl.downloaded_info_dicts[0]
392 self.assertEqual(downloaded['format_id'], 'E')
394 ydl = YDL({'format': '[filesize<1MiB]'})
395 ydl.process_ie_result(info_dict)
396 downloaded = ydl.downloaded_info_dicts[0]
397 self.assertEqual(downloaded['format_id'], 'G')
399 ydl = YDL({'format': 'all[width>=400][width<=600]'})
400 ydl.process_ie_result(info_dict)
401 downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts]
402 self.assertEqual(downloaded_ids, ['B', 'C', 'D'])
404 ydl = YDL({'format': 'best[height<40]'})
406 ydl.process_ie_result(info_dict)
407 except ExtractorError:
409 self.assertEqual(ydl.downloaded_info_dicts, [])
412 class TestYoutubeDL(unittest.TestCase):
413 def test_subtitles(self):
414 def s_formats(lang, autocaption=False):
417 'url': 'http://localhost/video.%s.%s' % (lang, ext),
418 '_auto': autocaption,
419 } for ext in ['vtt', 'srt', 'ass']]
420 subtitles = dict((l, s_formats(l)) for l in ['en', 'fr', 'es'])
421 auto_captions = dict((l, s_formats(l, True)) for l in ['it', 'pt', 'es'])
425 'url': 'http://localhost/video.mp4',
426 'subtitles': subtitles,
427 'automatic_captions': auto_captions,
431 def get_info(params={}):
432 params.setdefault('simulate', True)
434 ydl.report_warning = lambda *args, **kargs: None
435 return ydl.process_video_result(info_dict, download=False)
438 self.assertFalse(result.get('requested_subtitles'))
439 self.assertEqual(result['subtitles'], subtitles)
440 self.assertEqual(result['automatic_captions'], auto_captions)
442 result = get_info({'writesubtitles': True})
443 subs = result['requested_subtitles']
444 self.assertTrue(subs)
445 self.assertEqual(set(subs.keys()), set(['en']))
446 self.assertTrue(subs['en'].get('data') is None)
447 self.assertEqual(subs['en']['ext'], 'ass')
449 result = get_info({'writesubtitles': True, 'subtitlesformat': 'foo/srt'})
450 subs = result['requested_subtitles']
451 self.assertEqual(subs['en']['ext'], 'srt')
453 result = get_info({'writesubtitles': True, 'subtitleslangs': ['es', 'fr', 'it']})
454 subs = result['requested_subtitles']
455 self.assertTrue(subs)
456 self.assertEqual(set(subs.keys()), set(['es', 'fr']))
458 result = get_info({'writesubtitles': True, 'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
459 subs = result['requested_subtitles']
460 self.assertTrue(subs)
461 self.assertEqual(set(subs.keys()), set(['es', 'pt']))
462 self.assertFalse(subs['es']['_auto'])
463 self.assertTrue(subs['pt']['_auto'])
465 result = get_info({'writeautomaticsub': True, 'subtitleslangs': ['es', 'pt']})
466 subs = result['requested_subtitles']
467 self.assertTrue(subs)
468 self.assertEqual(set(subs.keys()), set(['es', 'pt']))
469 self.assertTrue(subs['es']['_auto'])
470 self.assertTrue(subs['pt']['_auto'])
472 def test_add_extra_info(self):
478 'playlist': 'funny videos',
480 YDL.add_extra_info(test_dict, extra_info)
481 self.assertEqual(test_dict['extractor'], 'Foo')
482 self.assertEqual(test_dict['playlist'], 'funny videos')
484 def test_prepare_filename(self):
492 ydl = YoutubeDL({'outtmpl': templ})
493 return ydl.prepare_filename(info)
494 self.assertEqual(fname('%(id)s.%(ext)s'), '1234.mp4')
495 self.assertEqual(fname('%(id)s-%(width)s.%(ext)s'), '1234-NA.mp4')
496 # Replace missing fields with 'NA'
497 self.assertEqual(fname('%(uploader_date)s-%(id)s.%(ext)s'), 'NA-1234.mp4')
499 def test_format_note(self):
501 self.assertEqual(ydl._format_note({}), '')
502 assertRegexpMatches(self, ydl._format_note({
505 assertRegexpMatches(self, ydl._format_note({
509 def test_postprocessors(self):
510 filename = 'post-processor-testfile.mp4'
511 audiofile = filename + '.mp3'
513 class SimplePP(PostProcessor):
515 with open(audiofile, 'wt') as f:
517 return [info['filepath']], info
519 def run_pp(params, PP):
520 with open(filename, 'wt') as f:
522 ydl = YoutubeDL(params)
523 ydl.add_post_processor(PP())
524 ydl.post_process(filename, {'filepath': filename})
526 run_pp({'keepvideo': True}, SimplePP)
527 self.assertTrue(os.path.exists(filename), '%s doesn\'t exist' % filename)
528 self.assertTrue(os.path.exists(audiofile), '%s doesn\'t exist' % audiofile)
532 run_pp({'keepvideo': False}, SimplePP)
533 self.assertFalse(os.path.exists(filename), '%s exists' % filename)
534 self.assertTrue(os.path.exists(audiofile), '%s doesn\'t exist' % audiofile)
537 class ModifierPP(PostProcessor):
539 with open(info['filepath'], 'wt') as f:
543 run_pp({'keepvideo': False}, ModifierPP)
544 self.assertTrue(os.path.exists(filename), '%s doesn\'t exist' % filename)
547 def test_match_filter(self):
548 class FilterYDL(YDL):
549 def __init__(self, *args, **kwargs):
550 super(FilterYDL, self).__init__(*args, **kwargs)
551 self.params['simulate'] = True
553 def process_info(self, info_dict):
554 super(YDL, self).process_info(info_dict)
556 def _match_entry(self, info_dict, incomplete):
557 res = super(FilterYDL, self)._match_entry(info_dict, incomplete)
559 self.downloaded_info_dicts.append(info_dict)
568 'filesize': 10 * 1024,
576 'description': 'foo',
577 'filesize': 5 * 1024,
579 videos = [first, second]
581 def get_videos(filter_=None):
582 ydl = FilterYDL({'match_filter': filter_})
584 ydl.process_ie_result(v, download=True)
585 return [v['id'] for v in ydl.downloaded_info_dicts]
588 self.assertEqual(res, ['1', '2'])
594 return 'Video id is not 1'
596 self.assertEqual(res, ['1'])
598 f = match_filter_func('duration < 30')
600 self.assertEqual(res, ['2'])
602 f = match_filter_func('description = foo')
604 self.assertEqual(res, ['2'])
606 f = match_filter_func('description =? foo')
608 self.assertEqual(res, ['1', '2'])
610 f = match_filter_func('filesize > 5KiB')
612 self.assertEqual(res, ['1'])
614 def test_playlist_items_selection(self):
617 'title': compat_str(i),
619 } for i in range(1, 5)]
624 'extractor': 'test:playlist',
625 'extractor_key': 'test:playlist',
626 'webpage_url': 'http://example.com',
631 # make a copy because the dictionary can be modified
632 ydl.process_ie_result(playlist.copy())
633 return [int(v['id']) for v in ydl.downloaded_info_dicts]
636 self.assertEqual(result, [1, 2, 3, 4])
638 result = get_ids({'playlistend': 10})
639 self.assertEqual(result, [1, 2, 3, 4])
641 result = get_ids({'playlistend': 2})
642 self.assertEqual(result, [1, 2])
644 result = get_ids({'playliststart': 10})
645 self.assertEqual(result, [])
647 result = get_ids({'playliststart': 2})
648 self.assertEqual(result, [2, 3, 4])
650 result = get_ids({'playlist_items': '2-4'})
651 self.assertEqual(result, [2, 3, 4])
653 result = get_ids({'playlist_items': '2,4'})
654 self.assertEqual(result, [2, 4])
656 result = get_ids({'playlist_items': '10'})
657 self.assertEqual(result, [])
659 def test_urlopen_no_file_protocol(self):
660 # see https://github.com/rg3/youtube-dl/issues/8227
662 self.assertRaises(compat_urllib_error.URLError, ydl.urlopen, 'file:///etc/passwd')
664 def test_do_not_override_ie_key_in_url_transparent(self):
667 class Foo1IE(InfoExtractor):
668 _VALID_URL = r'foo1:'
670 def _real_extract(self, url):
672 '_type': 'url_transparent',
677 class Foo2IE(InfoExtractor):
678 _VALID_URL = r'foo2:'
680 def _real_extract(self, url):
687 class Foo3IE(InfoExtractor):
688 _VALID_URL = r'foo3:'
690 def _real_extract(self, url):
691 return _make_result([{'url': TEST_URL}])
693 ydl.add_info_extractor(Foo1IE(ydl))
694 ydl.add_info_extractor(Foo2IE(ydl))
695 ydl.add_info_extractor(Foo3IE(ydl))
696 ydl.extract_info('foo1:')
697 downloaded = ydl.downloaded_info_dicts[0]
698 self.assertEqual(downloaded['url'], TEST_URL)
701 if __name__ == '__main__':