Repository: yt-dlp/yt-dlp
File: yt_dlp/extractor/youtube.py (Python)

Code before:
                content, (lambda x: x['continuationItemRenderer']['continuationEndpoint'],
                          lambda x: x['continuationItemRenderer']['button']['buttonRenderer']['command']),
                dict)
            continuation = cls._extract_continuation_ep_data(continuation_ep)
            if continuation:
                return continuation

    @classmethod
    def _extract_alerts(cls, data):
        for alert_dict in try_get(data, lambda x: x['alerts'], list) or []:
            if not isinstance(alert_dict, dict):
                continue
            for alert in alert_dict.values():
                alert_type = alert.get('type')
                if not alert_type:
                    continue
                message = cls._get_text(alert.get('text'))
                if message:
                    yield alert_type, message

    def _report_alerts(self, alerts, expected=True):
        errors = []
        warnings = []
        for alert_type, alert_message in alerts:
            if alert_type.lower() == 'error':
                errors.append([alert_type, alert_message])
            else:
                warnings.append([alert_type, alert_message])

        for alert_type, alert_message in (warnings + errors[:-1]):
            self.report_warning('YouTube said: %s - %s' % (alert_type, alert_message))
        if errors:
            raise ExtractorError('YouTube said: %s' % errors[-1][1], expected=expected)

    def _extract_and_report_alerts(self, data, *args, **kwargs):
        return self._report_alerts(self._extract_alerts(data), *args, **kwargs)

    def _extract_badges(self, renderer: dict):
        badges = set()
        for badge in try_get(renderer, lambda x: x['badges'], list) or []:
            label = try_get(badge, lambda x: x['metadataBadgeRenderer']['label'], compat_str)
            if label:
                badges.add(label.lower())
        return badges

    @staticmethod
    def _get_text(data, getter=None, max_runs=None):
        for get in variadic(getter):
            d = try_get(data, get) or data
            text = try_get(d, lambda x: x['simpleText'], compat_str)
            if text:

Review comment (bug):
potential future bug: if we fail to extract a message this will not return a two item tuple. it is assumed it will in other functions

Code after:
        for key in ('contents', 'items'):
            contents.extend(try_get(renderer, lambda x: x[key], list) or [])

        for content in contents:
            if not isinstance(content, dict):
                continue
            continuation_ep = try_get(
                content, (lambda x: x['continuationItemRenderer']['continuationEndpoint'],
                          lambda x: x['continuationItemRenderer']['button']['buttonRenderer']['command']),
                dict)
            continuation = cls._extract_continuation_ep_data(continuation_ep)
            if continuation:
                return continuation

    @classmethod
    def _extract_alerts(cls, data):
        for alert_dict in try_get(data, lambda x: x['alerts'], list) or []:
            if not isinstance(alert_dict, dict):
                continue
            for alert in alert_dict.values():
                alert_type = alert.get('type')
                if not alert_type:
                    continue
                message = cls._get_text(alert.get('text'))
                if message:
                    yield alert_type, message

    def _report_alerts(self, alerts, expected=True):
        errors = []
        warnings = []
        for alert_type, alert_message in alerts:
            if alert_type.lower() == 'error':
                errors.append([alert_type, alert_message])
            else:
                warnings.append([alert_type, alert_message])

        for alert_type, alert_message in (warnings + errors[:-1]):
            self.report_warning('YouTube said: %s - %s' % (alert_type, alert_message))
        if errors:
            raise ExtractorError('YouTube said: %s' % errors[-1][1], expected=expected)

    def _extract_and_report_alerts(self, data, *args, **kwargs):
        return self._report_alerts(self._extract_alerts(data), *args, **kwargs)

    def _extract_badges(self, renderer: dict):
        badges = set()
        for badge in try_get(renderer, lambda x: x['badges'], list) or []:
            label = try_get(badge, lambda x: x['metadataBadgeRenderer']['label'], compat_str)
            if label:
                badges.add(label.lower())
        return badges