aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordirkf <fieldhouse@gmx.net>2023-05-03 10:54:52 +0100
committerdirkf <fieldhouse@gmx.net>2023-07-19 22:14:50 +0100
commitcb9366eda584fde2421140adf994eadc5bb6b943 (patch)
tree20e8c4ea9c491faf37ba944d034e60ee2cd2e2ef
parentd9d07a95815a992bf5f876a62f25c831eb3f32ac (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.py37
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