ronantakizawa/codereview-bench huggingface dataset:
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/asobichannel.py (Python)

Code before:
        'playlist_mincount': 16,
    }, {
        'url': 'https://asobichannel.asobistore.jp/tag/hvm5qw3c6od',
        'info_dict': {
            'id': 'hvm5qw3c6od',
            'title': 'アイマスMOIW2023ラジオ',
        },
        'playlist_mincount': 13,
    }]

    def _real_extract(self, url):
        tag_id = self._match_id(url)

        webpage = self._download_webpage(url, tag_id)
        title = traverse_obj(self._search_nextjs_data(webpage, tag_id, fatal=False), ('props', 'pageProps', 'data', 'name'))

        media_list = self._download_json(
            f'https://channel.microcms.io/api/v1/media?limit=999&filters=(tag[contains]{tag_id})', tag_id,
            headers=self._MICROCMS_HEADER)

        entries = [{
            '_type': 'url',
            'url': f'https://asobichannel.asobistore.jp/watch/{metadata["id"]}',
            'ie_key': AsobiChannelIE.ie_key(),
            **self._extract_info(metadata),
        } for metadata in media_list.get('contents', [])]

        return self.playlist_result(entries, tag_id, title)


Review comment (refactor):
```suggestion
        def entries():
            for metadata in traverse_obj(media, ('contents', lambda _, v: v['id'])):
                yield {
                    '_type': 'url',
                    'url': f'https://asobichannel.asobistore.jp/watch/{metadata["id"]}',
                    'ie_key': AsobiChannelIE.ie_key(),
                    **self._extract_info(metadata),
                }
```

Code after:
    _TESTS = [{
        'url': 'https://asobichannel.asobistore.jp/tag/bjhh-nbcja',
        'info_dict': {
            'id': 'bjhh-nbcja',
            'title': 'アイドルマスター ミリオンライブ！ 765プロch 原っぱ通信',
        },
        'playlist_mincount': 16,
    }, {
        'url': 'https://asobichannel.asobistore.jp/tag/hvm5qw3c6od',
        'info_dict': {
            'id': 'hvm5qw3c6od',
            'title': 'アイマスMOIW2023ラジオ',
        },
        'playlist_mincount': 13,
    }]

    def _real_extract(self, url):
        tag_id = self._match_id(url)
        webpage = self._download_webpage(url, tag_id)
        title = traverse_obj(self._search_nextjs_data(
            webpage, tag_id, fatal=False), ('props', 'pageProps', 'data', 'name', {str}))

        media = self._download_json(
            f'https://channel.microcms.io/api/v1/media?limit=999&filters=(tag[contains]{tag_id})',
            tag_id, headers=self._MICROCMS_HEADER)

        def entries():
            for metadata in traverse_obj(media, ('contents', lambda _, v: v['id'])):
                yield {
                    '_type': 'url',
                    'url': f'https://asobichannel.asobistore.jp/watch/{metadata["id"]}',
                    'ie_key': AsobiChannelIE.ie_key(),
                    **self._extract_info(metadata),
                }

        return self.playlist_result(entries(), tag_id, title)
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/trtworld.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import (
    parse_iso8601,
    traverse_obj,
)


class TrtWorldIE(InfoExtractor):
    _VALID_URL = r'https?://www\.trtworld\.com/video/([a-zA-Z0-9-]+)/([a-zA-Z0-9-]+)-(?P<id>[0-9]+)'

    _TESTS = [{
        'url': 'https://www.trtworld.com/video/news/turkiye-switches-to-sustainable-tourism-16067690',
        'info_dict': {
            'id': '16067690',
            'ext': 'mp4',
            'title': 'Türkiye switches to sustainable tourism',
            'release_timestamp': 1701529569,
            'release_date': '20231202'
        }
    }, {
        'url': 'https://www.trtworld.com/video/one-offs/frames-from-anatolia-recreating-a-james-bond-scene-in-istanbuls-grand-bazaar-14541780',
        'info_dict': {
            'id': '14541780',
            'ext': 'mp4',
            'title': 'Frames From Anatolia: Bond in the Bazaar',
            'release_timestamp': 1692440844,
            'release_date': '20230819'
        }
    }]

    def _real_extract(self, url):
        display_id = self._match_id(url)
        webpage = self._download_webpage(url, display_id)
        nuxtjs_data = self._search_nuxt_data(webpage, display_id)

Review comment (suggestion):
```suggestion
    _VALID_URL = r'https?://www\.trtworld\.com/video/[\w-]+/[\w-]+-(?P<id>\d+)'
```

Code after:
from .common import InfoExtractor
from ..utils import ExtractorError, determine_ext, parse_iso8601, url_or_none
from ..utils.traversal import traverse_obj


class TrtWorldIE(InfoExtractor):
    _VALID_URL = r'https?://www\.trtworld\.com/video/[\w-]+/[\w-]+-(?P<id>\d+)'

    _TESTS = [{
        'url': 'https://www.trtworld.com/video/news/turkiye-switches-to-sustainable-tourism-16067690',
        'info_dict': {
            'id': '16067690',
            'ext': 'mp4',
            'title': 'Türkiye switches to sustainable tourism',
            'release_timestamp': 1701529569,
            'release_date': '20231202',
            'thumbnail': 'https://cdn-i.pr.trt.com.tr/trtworld/17647563_0-0-1920-1080.jpeg',
            'description': 'md5:0a975c04257fb529c8f99c7b76a2cf12',
        }
    }, {
        'url': 'https://www.trtworld.com/video/one-offs/frames-from-anatolia-recreating-a-james-bond-scene-in-istanbuls-grand-bazaar-14541780',
        'info_dict': {
            'id': '14541780',
            'ext': 'mp4',
            'title': 'Frames From Anatolia: Recreating a ‘James Bond’ Scene in Istanbul’s Grand Bazaar',
            'release_timestamp': 1692440844,
            'release_date': '20230819',
            'thumbnail': 'https://cdn-i.pr.trt.com.tr/trtworld/16939810_0-0-1920-1080.jpeg',
            'description': 'md5:4050e21570cc3c40b6c9badae800a94f',
        }
    }, {
        'url': 'https://www.trtworld.com/video/the-newsmakers/can-sudan-find-peace-amidst-failed-transition-to-democracy-12904760',
        'info_dict': {
            'id': '12904760',
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/adn.py (Python)

Code before:
            'title': 'Tokyo Mew Mew New',
        },
        # 'skip': 'Only available in French end German speaking Europe',
    }]

    def _real_extract(self, url):
        lang, video_show_slug = self._match_valid_url(url).group('lang', 'id')
        show = self._download_json(
            f'{self._API_BASE_URL}show/{video_show_slug}/', video_show_slug,
            'Downloading show JSON metadata', headers=self._HEADERS)['show']
        show_id = str(show['id'])
        episodes = self._download_json(
            f'{self._API_BASE_URL}video/show/{show_id}', video_show_slug,
            'Downloading episode list', headers={
                'X-Target-Distribution': lang,
                **self._HEADERS
            }, query={
                'order': 'asc',
                'limit': '-1',
            })
        entries = []
        for episode_id in traverse_obj(episodes, ('videos', ..., 'id', {str_or_none})):
            entries.append(self.url_result(
                f'https://animationdigitalnetwork.{lang}/video/{video_show_slug}/{episode_id}',
                ADNIE, episode_id))
        return self.playlist_result(entries, show_id, show.get('title'))


Review comment (suggestion):
```suggestion
            })

        def entries():
            for episode_id in traverse_obj(episodes, ('videos', ..., 'id', {str_or_none})):
                yield self.url_result(
                    f'https://animationdigitalnetwork.{lang}/video/{video_show_slug}/{episode_id}',
                    ADNIE, episode_id)

        return self.playlist_result(entries(), show_id, show.get('title'))
```

Code after:
            'title': 'Tokyo Mew Mew New',
        },
        # 'skip': 'Only available in French end German speaking Europe',
    }]

    def _real_extract(self, url):
        lang, video_show_slug = self._match_valid_url(url).group('lang', 'id')
        show = self._download_json(
            f'{self._API_BASE_URL}show/{video_show_slug}/', video_show_slug,
            'Downloading show JSON metadata', headers=self._HEADERS)['show']
        show_id = str(show['id'])
        episodes = self._download_json(
            f'{self._API_BASE_URL}video/show/{show_id}', video_show_slug,
            'Downloading episode list', headers={
                'X-Target-Distribution': lang,
                **self._HEADERS
            }, query={
                'order': 'asc',
                'limit': '-1',
            })

        def entries():
            for episode_id in traverse_obj(episodes, ('videos', ..., 'id', {str_or_none})):
                yield self.url_result(
                    f'https://animationdigitalnetwork.{lang}/video/{video_show_slug}/{episode_id}',
                    ADNIE, episode_id)

        return self.playlist_result(entries(), show_id, show.get('title'))
Repository: yt-dlp/yt-dlp
File: devscripts/run_tests.py (Python)

Code before:
import argparse
import os
import re
import subprocess
import sys
from pathlib import Path


IE_TEST_PATTERN = re.compile(r'IE(_all|_\d+)?$')


def parse_args():
    parser = argparse.ArgumentParser(description='Run selected yt-dlp tests')
    parser.add_argument(
        'test', help='An extractor test, or one of "test", "core" or "download"', nargs='*')
    parser.add_argument(
        '-k', help='Run a test matching the expression. Same as "pytest -k"', metavar='EXPRESSION')
    return parser.parse_args()


def run_tests(*tests, pattern=None):
    command = ['pytest', '--tb', 'short']

    if pattern:
        command.extend(['-k', pattern])

    for test in tests:
        if test == 'core':
            command.extend(['-m', 'not download'])
        elif test == 'download':
            command.extend(['-m', 'download'])
        else:
            test = IE_TEST_PATTERN.sub(r'\1', test)
            command.append(f'test/test_download.py::TestDownload::test_{test}')

    if not command:
        command.extend(['-m', 'not download'])

    print(f'Running {command}')
    os.chdir(Path(__file__).parent.parent)

Review comment (refactor):
```suggestion
        'test', help='An extractor test, or one "core" or "download"', nargs='*')
```

Code after:
#!/usr/bin/env python3

import argparse
import functools
import os
import re
import subprocess
import sys
from pathlib import Path


fix_test_name = functools.partial(re.compile(r'IE(_all|_\d+)?$').sub, r'\1')


def parse_args():
    parser = argparse.ArgumentParser(description='Run selected yt-dlp tests')
    parser.add_argument(
        'test', help='a extractor tests, or one of "core" or "download"', nargs='*')
    parser.add_argument(
        '-k', help='run a test matching EXPRESSION. Same as "pytest -k"', metavar='EXPRESSION')
    return parser.parse_args()


def run_tests(*tests, pattern=None):
    run_core = 'core' in tests or (not pattern and not tests)
    run_download = 'download' in tests
    tests = list(map(fix_test_name, tests))

    arguments = ['pytest', '-Werror', '--tb', 'short']
    if run_core:
        arguments.extend(['-m', 'not download'])
    elif run_download:
        arguments.extend(['-m', 'download'])
    elif pattern:
        arguments.extend(['-k', pattern])
    else:
        arguments.extend(
            f'test/test_download.py::TestDownload::test_{test}' for test in tests)

    print(f'Running {arguments}')
Repository: yt-dlp/yt-dlp
File: devscripts/run_tests.py (Python)

Code before:
import argparse
import os
import re
import subprocess
import sys
from pathlib import Path


IE_TEST_PATTERN = re.compile(r'IE(_all|_\d+)?$')


def parse_args():
    parser = argparse.ArgumentParser(description='Run selected yt-dlp tests')
    parser.add_argument(
        'test', help='An extractor test, or one "core" or "download"', nargs='*')
    parser.add_argument(
        '-k', help='Run a test matching the expression. Same as "pytest -k"', metavar='EXPRESSION')
    return parser.parse_args()


def run_tests(*tests, pattern=None):
    command = ['pytest', '--tb', 'short']

    if pattern:
        command.extend(['-k', pattern])

    for test in tests:
        if test == 'core':
            command.extend(['-m', 'not download'])
        elif test == 'download':
            command.extend(['-m', 'download'])
        else:
            test = IE_TEST_PATTERN.sub(r'\1', test)
            command.append(f'test/test_download.py::TestDownload::test_{test}')

    if not command:
        command.extend(['-m', 'not download'])

    print(f'Running {command}')
    os.chdir(Path(__file__).parent.parent)

Review comment (refactor):
```suggestion
        'test', help='An extractor test, or one of "core" or "download"', nargs='*')
```

Code after:
#!/usr/bin/env python3

import argparse
import functools
import os
import re
import subprocess
import sys
from pathlib import Path


fix_test_name = functools.partial(re.compile(r'IE(_all|_\d+)?$').sub, r'\1')


def parse_args():
    parser = argparse.ArgumentParser(description='Run selected yt-dlp tests')
    parser.add_argument(
        'test', help='a extractor tests, or one of "core" or "download"', nargs='*')
    parser.add_argument(
        '-k', help='run a test matching EXPRESSION. Same as "pytest -k"', metavar='EXPRESSION')
    return parser.parse_args()


def run_tests(*tests, pattern=None):
    run_core = 'core' in tests or (not pattern and not tests)
    run_download = 'download' in tests
    tests = list(map(fix_test_name, tests))

    arguments = ['pytest', '-Werror', '--tb', 'short']
    if run_core:
        arguments.extend(['-m', 'not download'])
    elif run_download:
        arguments.extend(['-m', 'download'])
    elif pattern:
        arguments.extend(['-k', pattern])
    else:
        arguments.extend(
            f'test/test_download.py::TestDownload::test_{test}' for test in tests)

    print(f'Running {arguments}')
Repository: yt-dlp/yt-dlp
File: devscripts/run_tests.py (Python)

Code before:
#!/usr/bin/env python3

import argparse
import functools
import os
import re
import subprocess
import sys
from pathlib import Path


IE_TEST_PATTERN = re.compile(r'IE(_all|_\d+)?$')
fix_test_name = functools.partial(IE_TEST_PATTERN.sub, r'\1')


def parse_args():
    parser = argparse.ArgumentParser(description='Run selected yt-dlp tests')
    parser.add_argument(
        'test', help='An extractor test, or one of "core" or "download"', nargs='*')
    parser.add_argument(
        '-k', help='Run a test matching the expression. Same as "pytest -k"', metavar='EXPRESSION')
    return parser.parse_args()


def run_tests(*tests, pattern=None):
    unittest_supported = True
    arguments = []

    for test in tests:
        if test == 'core':
            arguments += ['-m', 'not download']
            unittest_supported = False
        elif test == 'download':
            arguments += ['-m', 'download']
            unittest_supported = False
        else:
            arguments.append(f'test/test_download.py::TestDownload::test_{fix_test_name(test)}')


Review comment (suggestion):
```suggestion
fix_test_name = functools.partial(re.compile(r'IE(_all|_\d+)?$').sub, r'\1')
```
nitpick

Code after:
#!/usr/bin/env python3

import argparse
import functools
import os
import re
import subprocess
import sys
from pathlib import Path


fix_test_name = functools.partial(re.compile(r'IE(_all|_\d+)?$').sub, r'\1')


def parse_args():
    parser = argparse.ArgumentParser(description='Run selected yt-dlp tests')
    parser.add_argument(
        'test', help='a extractor tests, or one of "core" or "download"', nargs='*')
    parser.add_argument(
        '-k', help='run a test matching EXPRESSION. Same as "pytest -k"', metavar='EXPRESSION')
    return parser.parse_args()


def run_tests(*tests, pattern=None):
    run_core = 'core' in tests or (not pattern and not tests)
    run_download = 'download' in tests
    tests = list(map(fix_test_name, tests))

    arguments = ['pytest', '-Werror', '--tb', 'short']
    if run_core:
        arguments.extend(['-m', 'not download'])
    elif run_download:
        arguments.extend(['-m', 'download'])
    elif pattern:
        arguments.extend(['-k', pattern])
    else:
        arguments.extend(
            f'test/test_download.py::TestDownload::test_{test}' for test in tests)
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/asobistage.py (Python)

Code before:
import functools

from .common import InfoExtractor
from ..utils import (
    ExtractorError,
    str_or_none,
    traverse_obj,
    url_or_none,
    urljoin,
)


class AsobiStageIE(InfoExtractor):
    IE_DESC = 'ASOBISTAGE (アソビステージ)'
    _VALID_URL = r'https://asobistage\.asobistore\.jp/event/(?P<id>\w+/(?P<type>\w+)/\w+)(?:[?#]|$)'
    _TESTS = [{
        'url': 'https://asobistage.asobistore.jp/event/315passionhour_2022summer/archive/frame',
        'info_dict': {
            'id': '315passionhour_2022summer/archive/frame/edff52f2',
            'title': '315passion_FRAME_only',
            'live_status': 'was_live',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },
        'params': {
            'skip_download': True,
            'ignore_no_formats_error': True,
        },
    }, {
        'url': 'https://asobistage.asobistore.jp/event/idolmaster_idolworld2023_goods/archive/live',
        'info_dict': {
            'id': 'idolmaster_idolworld2023_goods/archive/live/3aef7110',
            'title': 'asobistore_station_1020_serverREC',
            'live_status': 'was_live',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },

Review comment (refactor):
nitpick
```suggestion
from ..utils import ExtractorError, str_or_none, url_or_none, urljoin
from ..utils.traversal import traverse_obj
```

Code after:
import functools

from .common import InfoExtractor
from ..utils import str_or_none, url_or_none
from ..utils.traversal import traverse_obj


class AsobiStageIE(InfoExtractor):
    IE_DESC = 'ASOBISTAGE (アソビステージ)'
    _VALID_URL = r'https?://asobistage\.asobistore\.jp/event/(?P<id>(?P<event>\w+)/(?P<type>archive|player)/(?P<slug>\w+))(?:[?#]|$)'
    _TESTS = [{
        'url': 'https://asobistage.asobistore.jp/event/315passionhour_2022summer/archive/frame',
        'info_dict': {
            'id': '315passionhour_2022summer/archive/frame',
            'title': '315プロダクションプレゼンツ 315パッションアワー!!!',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },
        'playlist_count': 1,
        'playlist': [{
            'info_dict': {
                'id': 'edff52f2',
                'ext': 'mp4',
                'title': '315passion_FRAME_only',
                'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
            },
        }],
    }, {
        'url': 'https://asobistage.asobistore.jp/event/idolmaster_idolworld2023_goods/archive/live',
        'info_dict': {
            'id': 'idolmaster_idolworld2023_goods/archive/live',
            'title': 'md5:378510b6e830129d505885908bd6c576',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },
        'playlist_count': 1,
        'playlist': [{
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/asobistage.py (Python)

Code before:
from .common import InfoExtractor
from ..utils import ExtractorError, str_or_none, url_or_none
from ..utils.traversal import traverse_obj


class AsobiStageIE(InfoExtractor):
    IE_DESC = 'ASOBISTAGE (アソビステージ)'
    _VALID_URL = r'https://asobistage\.asobistore\.jp/event/(?P<id>\w+/(?P<type>\w+)/\w+)(?:[?#]|$)'
    _TESTS = [{
        'url': 'https://asobistage.asobistore.jp/event/315passionhour_2022summer/archive/frame',
        'info_dict': {
            'id': '315passionhour_2022summer/archive/frame/edff52f2',
            'title': '315passion_FRAME_only',
            'live_status': 'was_live',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },
        'params': {
            'skip_download': True,
            'ignore_no_formats_error': True,
        },
    }, {
        'url': 'https://asobistage.asobistore.jp/event/idolmaster_idolworld2023_goods/archive/live',
        'info_dict': {
            'id': 'idolmaster_idolworld2023_goods/archive/live/3aef7110',
            'title': 'asobistore_station_1020_serverREC',
            'live_status': 'was_live',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },
        'params': {
            'skip_download': True,
            'ignore_no_formats_error': True,
        },
    }, {

Review comment (suggestion):
```suggestion
    _VALID_URL = r'https?://asobistage\.asobistore\.jp/event/(?P<id>\w+/(?P<type>\w+)/\w+)(?:[?#]|$)'
```

Code after:
import functools

from .common import InfoExtractor
from ..utils import str_or_none, url_or_none
from ..utils.traversal import traverse_obj


class AsobiStageIE(InfoExtractor):
    IE_DESC = 'ASOBISTAGE (アソビステージ)'
    _VALID_URL = r'https?://asobistage\.asobistore\.jp/event/(?P<id>(?P<event>\w+)/(?P<type>archive|player)/(?P<slug>\w+))(?:[?#]|$)'
    _TESTS = [{
        'url': 'https://asobistage.asobistore.jp/event/315passionhour_2022summer/archive/frame',
        'info_dict': {
            'id': '315passionhour_2022summer/archive/frame',
            'title': '315プロダクションプレゼンツ 315パッションアワー!!!',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },
        'playlist_count': 1,
        'playlist': [{
            'info_dict': {
                'id': 'edff52f2',
                'ext': 'mp4',
                'title': '315passion_FRAME_only',
                'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
            },
        }],
    }, {
        'url': 'https://asobistage.asobistore.jp/event/idolmaster_idolworld2023_goods/archive/live',
        'info_dict': {
            'id': 'idolmaster_idolworld2023_goods/archive/live',
            'title': 'md5:378510b6e830129d505885908bd6c576',
            'thumbnail': r're:^https?://[\w.-]+/\w+/\w+',
        },
Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/mx3.py (Python)

Code before:
import re

from .common import InfoExtractor
from ..utils.traversal import traverse_obj
from ..utils import (
    urlhandle_detect_ext,
    url_or_none,
    int_or_none,
    unified_timestamp,
)
from ..networking import HEADRequest


class Mx3BaseIE(InfoExtractor):
    _MX3_DOMAIN = None

    def _real_extract(self, url):
        track_id = self._match_id(url)
        webpage = self._download_webpage(url, track_id)
        json = self._download_json(f'https://{self._MX3_DOMAIN}/t/{track_id}.json', track_id)

        artists = []
        if json.get('artist'):
            artists.append(json['artist'])
        performer = json.get('performer_name')
        if performer and performer not in artists:
            artists.append(performer)

        genre = self._html_search_regex(r'<div\b[^>]+class="single-band-genre"[^>]*>([^<]+)</div>',
                                        webpage, 'genre', fatal=False, flags=re.DOTALL)

        formats = []

        def add_format(fmt, fatal):
            if fatal:
                urlh = self._request_webpage(HEADRequest(fmt['url']), track_id, note='Fetching default media headers')

Review comment (refactor):
```suggestion
import re

from .common import InfoExtractor
from ..networking import HEADRequest
from ..utils import (
    get_element_by_class,
    int_or_none,
    try_call,
    url_or_none,
    urlhandle_detect_ext,
)
from ..utils.traversal import traverse_obj
```

Code after:
import re

from .common import InfoExtractor
from ..networking import HEADRequest
from ..utils import (
    get_element_by_class,
    int_or_none,
    try_call,
    url_or_none,
    urlhandle_detect_ext,
)
from ..utils.traversal import traverse_obj


class Mx3BaseIE(InfoExtractor):
    _VALID_URL_TMPL = r'https?://(?:www\.)?%s/t/(?P<id>\w+)'
    _FORMATS = [{
        'url': 'player_asset',
        'format_id': 'default',
        'quality': 0,
    }, {
        'url': 'player_asset?quality=hd',
        'format_id': 'hd',
        'quality': 1,
    }, {
        'url': 'download',
        'format_id': 'download',
        'quality': 2,
    }, {
        'url': 'player_asset?quality=source',
        'format_id': 'source',
        'quality': 2,
    }]

    def _extract_formats(self, track_id):
        formats = []