diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 434bef65fb..6c2b94f3cb 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -65,6 +65,7 @@ ExistingVideoReached, expand_path, ExtractorError, + filter_dict, float_or_none, format_bytes, format_field, @@ -1574,13 +1575,9 @@ def process_ie_result(self, ie_result, download=True, extra_info=None): if not info: return info - force_properties = dict( - (k, v) for k, v in ie_result.items() if v is not None) - for f in ('_type', 'url', 'id', 'extractor', 'extractor_key', 'ie_key'): - if f in force_properties: - del force_properties[f] new_result = info.copy() - new_result.update(force_properties) + new_result.update(filter_dict(ie_result, lambda k, v: ( + v is not None and k not in {'_type', 'url', 'id', 'extractor', 'extractor_key', 'ie_key'}))) # Extracted info may not be a video result (i.e. # info.get('_type', 'video') != video) but rather an url or diff --git a/yt_dlp/extractor/common.py b/yt_dlp/extractor/common.py index d3d13c40ce..d0e57da23d 100644 --- a/yt_dlp/extractor/common.py +++ b/yt_dlp/extractor/common.py @@ -49,6 +49,7 @@ error_to_compat_str, extract_attributes, ExtractorError, + filter_dict, fix_xml_ampersands, float_or_none, format_field, @@ -1588,7 +1589,7 @@ def traverse_json_ld(json_ld, at_top_level=True): break traverse_json_ld(json_ld) - return dict((k, v) for k, v in info.items() if v is not None) + return filter_dict(info) def _search_nextjs_data(self, webpage, video_id, *, transform_source=None, fatal=True, **kw): return self._parse_json( diff --git a/yt_dlp/extractor/rai.py b/yt_dlp/extractor/rai.py index 34f1272852..9d243b2be6 100644 --- a/yt_dlp/extractor/rai.py +++ b/yt_dlp/extractor/rai.py @@ -11,6 +11,7 @@ from ..utils import ( determine_ext, ExtractorError, + filter_dict, find_xpath_attr, fix_xml_ampersands, GeoRestrictedError, @@ -110,11 +111,11 @@ def _extract_relinker_info(self, relinker_url, video_id, audio_only=False): if not audio_only: formats.extend(self._create_http_urls(relinker_url, formats)) - return dict((k, v) for k, v in { + return filter_dict({ 'is_live': is_live, 'duration': duration, 'formats': formats, - }.items() if v is not None) + }) def _create_http_urls(self, relinker_url, fmts): _RELINKER_REG = r'https?://(?P[^/]+?)/(?:i/)?(?P[^/]+?)/(?P.+?)/(?P\d+)(?:_(?P[\d\,]+))?(?:\.mp4|/playlist\.m3u8).+?' diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py index 72f11691f4..08e30d18f4 100644 --- a/yt_dlp/utils.py +++ b/yt_dlp/utils.py @@ -3105,16 +3105,16 @@ def try_get(src, getter, expected_type=None): return v +def filter_dict(dct, cndn=lambda _, v: v is not None): + return {k: v for k, v in dct.items() if cndn(k, v)} + + def merge_dicts(*dicts): merged = {} for a_dict in dicts: for k, v in a_dict.items(): - if v is None: - continue - if (k not in merged - or (isinstance(v, compat_str) and v - and isinstance(merged[k], compat_str) - and not merged[k])): + if (v is not None and k not in merged + or isinstance(v, str) and merged[k] == ''): merged[k] = v return merged