mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-27 10:31:29 +00:00
[utils] traverse_obj
: Allow unbranching using all
and any
(#9571)
Authored by: Grub4K
This commit is contained in:
parent
979ce2e786
commit
3699eeb67c
|
@ -377,3 +377,35 @@ def test_traversal_xml_etree(self):
|
||||||
'special transformations should act on current element'
|
'special transformations should act on current element'
|
||||||
assert traverse_obj(etree, ('country', 0, ..., 'text()', {int_or_none})) == [1, 2008, 141100], \
|
assert traverse_obj(etree, ('country', 0, ..., 'text()', {int_or_none})) == [1, 2008, 141100], \
|
||||||
'special transformations should act on current element'
|
'special transformations should act on current element'
|
||||||
|
|
||||||
|
def test_traversal_unbranching(self):
|
||||||
|
assert traverse_obj(_TEST_DATA, [(100, 1.2), all]) == [100, 1.2], \
|
||||||
|
'`all` should give all results as list'
|
||||||
|
assert traverse_obj(_TEST_DATA, [(100, 1.2), any]) == 100, \
|
||||||
|
'`any` should give the first result'
|
||||||
|
assert traverse_obj(_TEST_DATA, [100, all]) == [100], \
|
||||||
|
'`all` should give list if non branching'
|
||||||
|
assert traverse_obj(_TEST_DATA, [100, any]) == 100, \
|
||||||
|
'`any` should give single item if non branching'
|
||||||
|
assert traverse_obj(_TEST_DATA, [('dict', 'None', 100), all]) == [100], \
|
||||||
|
'`all` should filter `None` and empty dict'
|
||||||
|
assert traverse_obj(_TEST_DATA, [('dict', 'None', 100), any]) == 100, \
|
||||||
|
'`any` should filter `None` and empty dict'
|
||||||
|
assert traverse_obj(_TEST_DATA, [{
|
||||||
|
'all': [('dict', 'None', 100, 1.2), all],
|
||||||
|
'any': [('dict', 'None', 100, 1.2), any],
|
||||||
|
}]) == {'all': [100, 1.2], 'any': 100}, \
|
||||||
|
'`all`/`any` should apply to each dict path separately'
|
||||||
|
assert traverse_obj(_TEST_DATA, [{
|
||||||
|
'all': [('dict', 'None', 100, 1.2), all],
|
||||||
|
'any': [('dict', 'None', 100, 1.2), any],
|
||||||
|
}], get_all=False) == {'all': [100, 1.2], 'any': 100}, \
|
||||||
|
'`all`/`any` should apply to dict regardless of `get_all`'
|
||||||
|
assert traverse_obj(_TEST_DATA, [('dict', 'None', 100, 1.2), all, {float}]) is None, \
|
||||||
|
'`all` should reset branching status'
|
||||||
|
assert traverse_obj(_TEST_DATA, [('dict', 'None', 100, 1.2), any, {float}]) is None, \
|
||||||
|
'`any` should reset branching status'
|
||||||
|
assert traverse_obj(_TEST_DATA, [('dict', 'None', 100, 1.2), all, ..., {float}]) == [1.2], \
|
||||||
|
'`all` should allow further branching'
|
||||||
|
assert traverse_obj(_TEST_DATA, [('dict', 'None', 'urls', 'data'), any, ..., 'index']) == [0, 1], \
|
||||||
|
'`any` should allow further branching'
|
||||||
|
|
|
@ -228,6 +228,15 @@ def apply_path(start_obj, path, test_type):
|
||||||
if not casesense and isinstance(key, str):
|
if not casesense and isinstance(key, str):
|
||||||
key = key.casefold()
|
key = key.casefold()
|
||||||
|
|
||||||
|
if key in (any, all):
|
||||||
|
has_branched = False
|
||||||
|
filtered_objs = (obj for obj in objs if obj not in (None, {}))
|
||||||
|
if key is any:
|
||||||
|
objs = (next(filtered_objs, None),)
|
||||||
|
else:
|
||||||
|
objs = (list(filtered_objs),)
|
||||||
|
continue
|
||||||
|
|
||||||
if __debug__ and callable(key):
|
if __debug__ and callable(key):
|
||||||
# Verify function signature
|
# Verify function signature
|
||||||
inspect.signature(key).bind(None, None)
|
inspect.signature(key).bind(None, None)
|
||||||
|
|
Loading…
Reference in a new issue