Skip to content

Commit

Permalink
[utils] Minor updates (merge_dicts, T)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
dirkf committed Jul 19, 2023
1 parent d9d07a9 commit cb9366e
Showing 1 changed file with 30 additions and 7 deletions.
37 changes: 30 additions & 7 deletions youtube_dl/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit cb9366e

Please sign in to comment.