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

Code before:
        return info

    def _extract_single(self, media_data):
        thumbnails = traverse_obj(media_data, lambda k, _: k.startswith('thumbnail'))

        formats, subtitles = [], {}
        for media in traverse_obj(media_data, 'medias', default=[]):
            if not media.get('url') or media.get('type') != 'HLS':
                continue
            f, subs = self._extract_m3u8_formats_and_subtitles(
                update_url_query(media['url'], {'id_token': self._ID_TOKEN}),
                media_data['id'], 'mp4', m3u8_id='HLS', fatal=False)
            formats.extend(f)
            self._merge_subtitles(subs, target=subtitles)

        return {
            'thumbnails': thumbnails,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(media_data, {
                'id': ('id', {str}),
                'title': ('name', {str}),
                'description': (('descriptionLong', 'description'), {str}, any),
                'genres': ('contentTypes', ..., {str}, all, {unpack(join_nonempty, delim='; ')}, filter),
                'creators': ('directors', ..., {str}, all, {unpack(join_nonempty, delim='; ')}, filter),
                'cast': ('mainCast', ..., {str}, all, {unpack(join_nonempty, delim='; ')}, filter),
                'location': ('productionCountries', ..., {str}, all, {unpack(join_nonempty, delim='; ')}, filter),
                'release_year': ('year', {str}, {lambda x: x[:4]}, {int_or_none}),
                'duration': ('duration', {int_or_none}),
                'series': ('seriesName', {str}),
                'season_number': ('seasonNumber', {int_or_none}),
                'episode': ('name', {str}, {lambda x: x if media_data['episodeNumber'] is not None else None}),
                'episode_number': ('episodeNumber', {int_or_none}),
            }),
        }


Review comment (suggestion):
No, these 3 fields need to be a `list`, not `str`. `location` needs to be `str`, which is why I suggested the `join_nonempty` transformation there but not here. Revert and please re-run tests and update them again
```suggestion
                'genres': ('contentTypes', ..., {str}),
                'creators': ('directors', ..., {str}),
                'cast': ('mainCast', ..., {str}),
```

Code after:
        return info

    def _extract_single(self, media_data):
        thumbnails = traverse_obj(media_data, lambda k, _: k.startswith('thumbnail'))

        formats, subtitles = [], {}
        for media in traverse_obj(media_data, 'medias', default=[]):
            if not media.get('url') or media.get('type') != 'HLS':
                continue
            f, subs = self._extract_m3u8_formats_and_subtitles(
                update_url_query(media['url'], {'id_token': self._ID_TOKEN}),
                media_data['id'], 'mp4', m3u8_id='HLS', fatal=False)
            formats.extend(f)
            self._merge_subtitles(subs, target=subtitles)

        return {
            'thumbnails': thumbnails,
            'formats': formats,
            'subtitles': subtitles,
            **traverse_obj(media_data, {
                'id': ('id', {str}),
                'title': ('name', {str}),
                'description': (('descriptionLong', 'description'), {str}, any),
                'genres': ('contentTypes', ..., {str}),
                'creators': ('directors', ..., {str}),
                'cast': ('mainCast', ..., {str}),
                'location': ('productionCountries', ..., {str}, all, {unpack(join_nonempty, delim='; ')}, filter),
                'release_year': ('year', {str}, {lambda x: x[:4]}, {int_or_none}),
                'duration': ('duration', {int_or_none}),
                'series': ('seriesName', {str}),
                'season_number': ('seasonNumber', {int_or_none}),
                'episode': ('name', {str}, {lambda x: x if media_data['episodeNumber'] is not None else None}),
                'episode_number': ('episodeNumber', {int_or_none}),
            }),
        }