Skip to content

Commit 320d3f4

Browse files
committed
add initial (diff only) support for YAML streams
1 parent 9eebf62 commit 320d3f4

File tree

7 files changed

+98
-1
lines changed

7 files changed

+98
-1
lines changed

nested_diff/cli.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,57 @@ def _default_constructor(loader, tag_suffix, node): # noqa: ARG001
621621

622622
def decode(self, data):
623623
"""Parse YAML string."""
624-
return self.yaml.load(data, Loader=self.yaml_loader, **self.opts)
624+
items = list(
625+
self.yaml.load_all(data, Loader=self.yaml_loader, **self.opts),
626+
)
627+
628+
if len(items) == 1:
629+
return items[0]
630+
631+
return ListOfDocuments(items)
632+
633+
634+
class ListOfDocuments:
635+
"""Wrapper to represent bunch of documents like YAML stream."""
636+
637+
def __init__(self, items):
638+
"""Initialize wrapper.
639+
640+
Args:
641+
items: list of documents.
642+
643+
"""
644+
self.items = items
645+
646+
def __repr__(self):
647+
"""Repr for wrapper."""
648+
return f'ListOfDocuments({self.items})'
649+
650+
651+
class ListOfDocumentsHandler(nested_diff.handlers.ListHandler):
652+
"""ListOfDocuments handler."""
653+
654+
extension_id = 'nested_diff.ListOfDocuments'
655+
handled_type = ListOfDocuments
656+
657+
def diff(self, differ, a, b):
658+
"""Calculate diff for two ListOfDocuments objects.
659+
660+
Args:
661+
differ: nested_diff.Differ object.
662+
a: First object to diff.
663+
b: Second object to diff.
664+
665+
Returns:
666+
Tuple: equality flag and nested diff.
667+
668+
"""
669+
equal, diff = differ.diff(a.items, b.items)
670+
671+
if diff:
672+
diff['E'] = self.extension_id
673+
674+
return equal, diff
625675

626676

627677
class YamlNode:

nested_diff/diff_tool.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def diff(self, a, b, **kwargs):
5858
diff_opts['R'] = int(diff_opts['R'])
5959

6060
differ = nested_diff.Differ(**diff_opts)
61+
differ.set_handler(nested_diff.cli.ListOfDocumentsHandler())
6162
differ.set_handler(nested_diff.cli.YamlNodeHandler())
6263

6364
if self.args.text_ctx >= 0:
@@ -289,6 +290,7 @@ def __init__( # noqa: PLR0913
289290

290291
fmt_class = self.get_formatter_class(base_class, values=values)
291292
self.encoder = fmt_class(**self.get_opts(kwargs))
293+
self.encoder.set_handler(nested_diff.cli.ListOfDocumentsHandler())
292294
self.encoder.set_handler(nested_diff.cli.YamlNodeHandler())
293295

294296
if header is None:

tests/cli/shared.stream.a.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
one: 1
3+
---
4+
two: 2

tests/cli/shared.stream.b.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
one: uno
3+
---
4+
two: 2

tests/cli/test_diff_tool.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -786,3 +786,33 @@ def test_yaml_custom_tags(capsys, expected, rpath):
786786
assert exit_code == 1
787787

788788
assert captured.out == expected
789+
790+
791+
def test_yaml_streams(capsys, expected, rpath):
792+
exit_code = nested_diff.diff_tool.App(
793+
args=(
794+
rpath('shared.stream.a.yaml'),
795+
rpath('shared.stream.b.yaml'),
796+
),
797+
).run()
798+
799+
captured = capsys.readouterr()
800+
assert captured.err == ''
801+
assert exit_code == 1
802+
803+
assert captured.out == expected
804+
805+
806+
def test_yaml_stream_vs_single(capsys, expected, rpath):
807+
exit_code = nested_diff.diff_tool.App(
808+
args=(
809+
rpath('shared.stream.a.yaml'),
810+
rpath('shared.lists.b.yaml'),
811+
),
812+
).run()
813+
814+
captured = capsys.readouterr()
815+
assert captured.err == ''
816+
assert exit_code == 1
817+
818+
assert captured.out == expected
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- ListOfDocuments([{'one': 1}, {'two': 2}])
2+
+ [0, [1, 2], 3]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# <ListOfDocuments>
2+
[0]
3+
{'one'}
4+
- 1
5+
+ 'uno'

0 commit comments

Comments
 (0)