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

Code before:

    def _select_api_hostname(self, req_api_hostname, default_client=None):
        return (self._configuration_arg('innertube_host', [''], ie_key=YoutubeIE.ie_key())[0]
                or req_api_hostname or self._get_innertube_host(default_client or 'web'))

    def _extract_context(self, ytcfg=None, default_client='web'):
        context = get_first(
            (ytcfg, self._get_default_ytcfg(default_client)), 'INNERTUBE_CONTEXT', expected_type=dict)
        # Enforce language and tz for extraction
        client_context = traverse_obj(context, 'client', expected_type=dict, default={})
        client_context.update({'hl': self._preferred_lang or 'en', 'timeZone': 'UTC', 'utcOffsetMinutes': 0})
        return context

    @staticmethod
    def _make_sid_authorization(scheme, sid, origin, additional_parts):
        timestamp = str(round(time.time()))

        hash_parts = []
        if additional_parts:
            hash_parts.append(':'.join(additional_parts.values()))
        hash_parts.extend([timestamp, sid, origin])
        sidhash = hashlib.sha1(' '.join(hash_parts).encode()).hexdigest()

        parts = [timestamp, sidhash]
        if additional_parts:
            parts.append(''.join(additional_parts.keys()))

        return f'{scheme} {"_".join(parts)}'

    _SAPISID = _3PSAPISID = _1PSAPISID = None

    def _load_sid_cookies(self):

        yt_cookies = self._get_cookies('https://www.youtube.com')
        if self._SAPISID is None:
            # Sometimes SAPISID cookie isn't present but __Secure-3PAPISID is.
            # YouTube also falls back to __Secure-3PAPISID if SAPISID is missing.
            # See: https://github.com/yt-dlp/yt-dlp/issues/393

            sapisid_cookie = dict_get(
                yt_cookies, ('SAPISID', '__Secure-3PAPISID'))
            if sapisid_cookie and sapisid_cookie.value:
                self._SAPISID = sapisid_cookie.value

        if self._1PSAPISID is None:
            _1papisid_cookie = yt_cookies.get('__Secure-1PAPISID')
            if _1papisid_cookie and _1papisid_cookie.value:
                self._1PSAPISID = _1papisid_cookie.value

        if self._3PSAPISID is None:
            _3papisid_cookie = yt_cookies.get('__Secure-3PAPISID')

Review comment (suggestion):
```suggestion
            parts.append(''.join(additional_parts))
```

Code after:
    def _select_api_hostname(self, req_api_hostname, default_client=None):
        return (self._configuration_arg('innertube_host', [''], ie_key=YoutubeIE.ie_key())[0]
                or req_api_hostname or self._get_innertube_host(default_client or 'web'))

    def _extract_context(self, ytcfg=None, default_client='web'):
        context = get_first(
            (ytcfg, self._get_default_ytcfg(default_client)), 'INNERTUBE_CONTEXT', expected_type=dict)
        # Enforce language and tz for extraction
        client_context = traverse_obj(context, 'client', expected_type=dict, default={})
        client_context.update({'hl': self._preferred_lang or 'en', 'timeZone': 'UTC', 'utcOffsetMinutes': 0})
        return context

    @staticmethod
    def _make_sid_authorization(scheme, sid, origin, additional_parts):
        timestamp = str(round(time.time()))

        hash_parts = []
        if additional_parts:
            hash_parts.append(':'.join(additional_parts.values()))
        hash_parts.extend([timestamp, sid, origin])
        sidhash = hashlib.sha1(' '.join(hash_parts).encode()).hexdigest()

        parts = [timestamp, sidhash]
        if additional_parts:
            parts.append(''.join(additional_parts))

        return f'{scheme} {"_".join(parts)}'

    def _get_sid_cookies(self):
        """
        Get SAPISID, 1PSAPISID, 3PSAPISID cookie values
        @returns sapisid, 1psapisid, 3psapisid
        """
        yt_cookies = self._get_cookies('https://www.youtube.com')
        yt_sapisid = try_call(lambda: yt_cookies['SAPISID'].value)
        yt_3papisid = try_call(lambda: yt_cookies['__Secure-3PAPISID'].value)
        yt_1papisid = try_call(lambda: yt_cookies['__Secure-1PAPISID'].value)

        # Sometimes SAPISID cookie isn't present but __Secure-3PAPISID is.
        # YouTube also falls back to __Secure-3PAPISID if SAPISID is missing.
        # See: https://github.com/yt-dlp/yt-dlp/issues/393

        return yt_sapisid or yt_3papisid, yt_1papisid, yt_3papisid

    def _get_sid_authorization_header(self, origin='https://www.youtube.com', user_session_id=None):
        """
        Generate API Session ID Authorization for Innertube requests. Assumes all requests are secure (https).
        @param origin: Origin URL
        @param user_session_id: Optional User Session ID
        @return: Authorization header value
        """