Skip to content

Commit

Permalink
Merge pull request #492 from AaronDMarasco/dev
Browse files Browse the repository at this point in the history
Add print() option
  • Loading branch information
seperman authored Oct 13, 2024
2 parents 111a2eb + 5f22bd2 commit cdc4b30
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ Authors in order of the timeline of their contributions:
- [dtorres-sf](https://github.com/dtorres-sf) for fixing iterable moved items when iterable_compare_func is used.
- [Florian Finkernagel](https://github.com/TyberiusPrime) for pandas and polars support.
- Mathis Chenuet [artemisart](https://github.com/artemisart) for fixing slots classes comparison.
- [Aaron D. Marasco](https://github.com/AaronDMarasco) added `prefix` option to `pretty()`
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

- v8-0-1
- Bugfix. Numpy should be optional.
- Added `prefix` option to `pretty()`

- v8-0-0

Expand Down
8 changes: 6 additions & 2 deletions deepdiff/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ def _to_delta_dict(self, directed=True, report_repetition_required=True, always_

return deepcopy(dict(result))

def pretty(self):
def pretty(self, prefix=None):
"""
The pretty human readable string output for the diff object
regardless of what view was used to generate the diff.
Expand All @@ -310,12 +310,16 @@ def pretty(self):
Item root[1] removed from set.
"""
result = []
if prefix is None:
prefix = ''
keys = sorted(self.tree.keys()) # sorting keys to guarantee constant order across python versions.
for key in keys:
for item_key in self.tree[key]:
result += [pretty_print_diff(item_key)]

return '\n'.join(result)
if callable(prefix):
return "\n".join(f"{prefix(diff=self)}{r}" for r in result)
return "\n".join(f"{prefix}{r}" for r in result)


class _RestrictedUnpickler(pickle.Unpickler):
Expand Down
23 changes: 23 additions & 0 deletions docs/view.rst
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,29 @@ Use the pretty method for human readable output. This is regardless of what view
Item root[4] removed from set.
Item root[1] removed from set.

The pretty method has an optional parameter ``prefix`` that allows a prefix string before every output line (*e.g.* for logging):
>>> from deepdiff import DeepDiff
>>> t1={1,2,4}
>>> t2={2,3}
>>> print(DeepDiff(t1, t2).pretty(prefix='Diff: '))
Diff: Item root[3] added to set.
Diff: Item root[4] removed from set.
Diff: Item root[1] removed from set.

The ``prefix`` may also be a callable function. This function must accept ``**kwargs``; as of this version, the only parameter is ``diff`` but the signature allows for future expansion.
The ``diff`` given will be the ``DeepDiff`` that ``pretty`` was called on; this allows interesting capabilities such as:
>>> from deepdiff import DeepDiff
>>> t1={1,2,4}
>>> t2={2,3}
>>> def callback(**kwargs):
... """Helper function using a hidden variable on the diff that tracks which count prints next"""
... kwargs['diff']._diff_count = 1 + getattr(kwargs['diff'], '_diff_count', 0)
... return f"Diff #{kwargs['diff']._diff_count}: "
...
>>> print(DeepDiff(t1, t2).pretty(prefix=callback))
Diff #1: Item root[3] added to set.
Diff #2: Item root[4] removed from set.
Diff #3: Item root[1] removed from set.


Text view vs. Tree view vs. vs. pretty() method
Expand Down
43 changes: 43 additions & 0 deletions tests/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,49 @@ def test_pretty_form_method(self, expected, verbose_level):
result = ddiff.pretty()
assert result == expected

@pytest.mark.parametrize("expected, verbose_level",
(
('\t\tItem root[5] added to dictionary.'
'\n\t\tItem root[3] removed from dictionary.'
'\n\t\tType of root[2] changed from int to str and value changed from 2 to "b".'
'\n\t\tValue of root[4] changed from 4 to 5.', 0),
('\t\tItem root[5] (5) added to dictionary.'
'\n\t\tItem root[3] (3) removed from dictionary.'
'\n\t\tType of root[2] changed from int to str and value changed from 2 to "b".'
'\n\t\tValue of root[4] changed from 4 to 5.', 2),
), ids=("verbose=0", "verbose=2")
)
def test_pretty_form_method_prefixed_simple(self, expected, verbose_level):
t1 = {2: 2, 3: 3, 4: 4}
t2 = {2: 'b', 4: 5, 5: 5}
ddiff = DeepDiff(t1, t2, verbose_level=verbose_level)
result = ddiff.pretty(prefix="\t\t")
assert result == expected

@pytest.mark.parametrize("expected, verbose_level",
(
('Diff #1: Item root[5] added to dictionary.'
'\nDiff #2: Item root[3] removed from dictionary.'
'\nDiff #3: Type of root[2] changed from int to str and value changed from 2 to "b".'
'\nDiff #4: Value of root[4] changed from 4 to 5.', 0),
('Diff #1: Item root[5] (5) added to dictionary.'
'\nDiff #2: Item root[3] (3) removed from dictionary.'
'\nDiff #3: Type of root[2] changed from int to str and value changed from 2 to "b".'
'\nDiff #4: Value of root[4] changed from 4 to 5.', 2),
), ids=("verbose=0", "verbose=2")
)
def test_pretty_form_method_prefixed_callback(self, expected, verbose_level):
def prefix_callback(**kwargs):
"""Helper function using a hidden variable on the diff that tracks which count prints next"""
kwargs['diff']._diff_count = 1 + getattr(kwargs['diff'], '_diff_count', 0)
return f"Diff #{kwargs['diff']._diff_count}: "

t1 = {2: 2, 3: 3, 4: 4}
t2 = {2: 'b', 4: 5, 5: 5}
ddiff = DeepDiff(t1, t2, verbose_level=verbose_level)
result = ddiff.pretty(prefix=prefix_callback)
assert result == expected

@pytest.mark.parametrize('test_num, value, func_to_convert_back', [
(1, {'10': None}, None),
(2, {"type_changes": {"root": {"old_type": None, "new_type": list, "new_value": ["你好", 2, 3, 5]}}}, None),
Expand Down

0 comments on commit cdc4b30

Please sign in to comment.