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

Code before:
    def fetch_po_token(self, client='web', visitor_data=None, data_sync_id=None, player_url=None, **kwargs):
        # PO Token is bound to visitor_data / Visitor ID when logged out. Must have visitor_data for it to function.
        if not visitor_data and not self.is_authenticated and player_url:
            self.report_warning(
                f'Unable to fetch PO Token for {client} client: Missing required Visitor Data. '
                f'You may need to pass Visitor Data with --extractor-args "youtube:visitor_data=XXX"')
            return

        config_po_token = self._get_config_po_token(client)
        if config_po_token:
            # PO token is bound to data_sync_id / account Session ID when logged in. However, for the config po_token,
            # if using first channel in an account then we don't need the data_sync_id anymore...
            if not data_sync_id and self.is_authenticated and player_url:
                self.report_warning(
                    f'Got a PO Token for {client} client, but missing Data Sync ID for account. Formats may not work.'
                    f'You may need to pass a Data Sync ID with --extractor-args youtube:data_sync_id=XXX',
                )

            return config_po_token

        # Require PO Token if logged in for external fetching
        if not data_sync_id and self.is_authenticated and player_url:
            self.report_warning(
                f'Unable to fetch PO Token for {client} client: Missing required Data Sync ID for account. '
                f'You may need to pass a Data Sync ID with --extractor-args youtube:data_sync_id=XXX',
            )
            return

        return self._fetch_po_token(
            client=client,
            visitor_data=visitor_data,
            data_sync_id=data_sync_id,
            player_url=player_url,
            **kwargs,
        )

    def _fetch_po_token(self, client, visitor_data=None, data_sync_id=None, player_url=None, **kwargs):
        """External PO Token fetch stub"""

    @staticmethod
    def _is_agegated(player_response):
        if traverse_obj(player_response, ('playabilityStatus', 'desktopLegacyAgeGateReason')):
            return True

        reasons = traverse_obj(player_response, ('playabilityStatus', ('status', 'reason')))
        AGE_GATE_REASONS = (
            'confirm your age', 'age-restricted', 'inappropriate',  # reason
            'age_verification_required', 'age_check_required',  # status
        )
        return any(expected in reason for expected in AGE_GATE_REASONS for reason in reasons)


Review comment (refactor):
```suggestion
                f'You may need to pass a Data Sync ID with --extractor-args "youtube:data_sync_id=XXX"')
```

Code after:

    def fetch_po_token(self, client='web', visitor_data=None, data_sync_id=None, player_url=None, **kwargs):
        # PO Token is bound to visitor_data / Visitor ID when logged out. Must have visitor_data for it to function.
        if not visitor_data and not self.is_authenticated and player_url:
            self.report_warning(
                f'Unable to fetch PO Token for {client} client: Missing required Visitor Data. '
                f'You may need to pass Visitor Data with --extractor-args "youtube:visitor_data=XXX"')
            return

        config_po_token = self._get_config_po_token(client)
        if config_po_token:
            # PO token is bound to data_sync_id / account Session ID when logged in. However, for the config po_token,
            # if using first channel in an account then we don't need the data_sync_id anymore...
            if not data_sync_id and self.is_authenticated and player_url:
                self.report_warning(
                    f'Got a PO Token for {client} client, but missing Data Sync ID for account. Formats may not work.'
                    f'You may need to pass a Data Sync ID with --extractor-args "youtube:data_sync_id=XXX"')

            return config_po_token

        # Require PO Token if logged in for external fetching
        if not data_sync_id and self.is_authenticated and player_url:
            self.report_warning(
                f'Unable to fetch PO Token for {client} client: Missing required Data Sync ID for account. '
                f'You may need to pass a Data Sync ID with --extractor-args "youtube:data_sync_id=XXX"')
            return

        return self._fetch_po_token(
            client=client,
            visitor_data=visitor_data,
            data_sync_id=data_sync_id,
            player_url=player_url,
            **kwargs,
        )

    def _fetch_po_token(self, client, visitor_data=None, data_sync_id=None, player_url=None, **kwargs):
        """External PO Token fetch stub"""

    @staticmethod
    def _is_agegated(player_response):
        if traverse_obj(player_response, ('playabilityStatus', 'desktopLegacyAgeGateReason')):
            return True

        reasons = traverse_obj(player_response, ('playabilityStatus', ('status', 'reason')))
        AGE_GATE_REASONS = (
            'confirm your age', 'age-restricted', 'inappropriate',  # reason
            'age_verification_required', 'age_check_required',  # status
        )
        return any(expected in reason for expected in AGE_GATE_REASONS for reason in reasons)

    @staticmethod