diff options
author | dirkf <fieldhouse@gmx.net> | 2023-05-03 10:54:52 +0100 |
---|---|---|
committer | dirkf <fieldhouse@gmx.net> | 2023-07-19 22:14:50 +0100 |
commit | cb9366eda584fde2421140adf994eadc5bb6b943 (patch) | |
tree | 20e8c4ea9c491faf37ba944d034e60ee2cd2e2ef | |
parent | d9d07a95815a992bf5f876a62f25c831eb3f32ac (diff) |
[utils] Minor updates (merge_dicts, T)
A couple of mods to ease yt-dlp back-ports:
* add kwargs to merge_dicts:
`unblank=True` (disallow empty string), `rev=False` (reverse the merge list)
* add `T(x)` shortcut for `{x}`, unsupported in Py2.6
-rw-r--r-- | youtube_dl/utils.py | 37 |
1 files changed, 30 insertions, 7 deletions
diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py index b05f65283..0cbbec0f3 100644 --- a/youtube_dl/utils.py +++ b/youtube_dl/utils.py @@ -4269,7 +4269,8 @@ def variadic(x, allowed_types=NO_DEFAULT): def dict_get(d, key_or_keys, default=None, skip_false_values=True): exp = (lambda x: x or None) if skip_false_values else IDENTITY - return traverse_obj(d, *variadic(key_or_keys), expected_type=exp, default=default) + return traverse_obj(d, *variadic(key_or_keys), expected_type=exp, + default=default, get_all=False) def try_call(*funcs, **kwargs): @@ -4302,16 +4303,38 @@ def try_get(src, getter, expected_type=None): return v -def merge_dicts(*dicts): +def merge_dicts(*dicts, **kwargs): + """ + Merge the `dict`s in `dicts` using the first valid value for each key. + Normally valid: not None and not an empty string + + Keyword-only args: + unblank: allow empty string if False (default True) + rev: merge dicts in reverse order (default False) + + merge_dicts(dct1, dct2, ..., unblank=False, rev=True) + matches {**dct1, **dct2, ...} + + However, merge_dicts(dct1, dct2, ..., rev=True) may often be better. + """ + + unblank = kwargs.get('unblank', True) + rev = kwargs.get('rev', False) + + if unblank: + def can_merge_str(k, v, to_dict): + return (isinstance(v, compat_str) and v + and isinstance(to_dict[k], compat_str) + and not to_dict[k]) + else: + can_merge_str = lambda k, v, to_dict: False + merged = {} - for a_dict in dicts: + for a_dict in reversed(dicts) if rev else 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 (k not in merged) or can_merge_str(k, v, merged): merged[k] = v return merged |