项目作者: mr-mixas

项目描述 :
Recursive diff and patch for nested structures
高级语言: Python
项目地址: git://github.com/mr-mixas/Nested-Diff.py.git
创建时间: 2017-12-23T12:27:31Z
项目社区:https://github.com/mr-mixas/Nested-Diff.py

开源协议:Apache License 2.0

下载


Nested-Diff.py

Recursive diff and patch for nested structures.

PyPi
Tests
Coverage
Supported Python versions
License

Main features

  • Machine readable diff structure.
  • Human friendly diff visualization, collapsible html diffs.
  • All ops (added/removed/changed/unchanged) are optional and may be disabled.
  • Any data types support may be added by external handlers.

See Live Demo!

Install

pip install nested_diff

For extra formats support (YAML, TOML) in cli tools, use

pip install nested_diff[cli]

Command line tools

  1. $ cat a.json b.json
  2. [0, [1], 3]
  3. [0, [1, 2], 3]
  1. $ nested_diff a.json b.json
  2. [1]
  3. + [1]
  4. + 2
  1. nested_diff a.json b.json --ofmt json > patch.json
  2. nested_patch a.json patch.json

Library usage

  1. >>> from nested_diff import diff, patch
  2. >>> from nested_diff.formatters import TextFormatter
  3. >>>
  4. >>> a = {'one': 1, 'two': 2, 'three': 3}
  5. >>> b = {'one': 1, 'two': 42}
  6. >>>
  7. >>>
  8. >>> full_diff = diff(a, b)
  9. >>> full_diff
  10. {'D': {'three': {'R': 3}, 'two': {'N': 42, 'O': 2}, 'one': {'U': 1}}}
  11. >>>
  12. >>> short_diff = diff(a, b, O=False, U=False) # omit old and unchanged items
  13. >>> short_diff
  14. {'D': {'three': {'R': 3}, 'two': {'N': 42}}}
  15. >>>
  16. >>>
  17. >>> a = patch(a, short_diff)
  18. >>> assert a == b
  19. >>>
  20. >>>
  21. >>> human_readable = TextFormatter().format(full_diff)
  22. >>> print(human_readable)
  23. {'one'}
  24. 1
  25. - {'three'}
  26. - 3
  27. {'two'}
  28. - 2
  29. + 42
  30. <BLANKLINE>
  31. >>>

HTML and ANSI colored terminal formatters also available out of the box.
See Live Demo,
HOWTO and
nested_diff.formatters.

Diff structure

Diff is a dict and may contain status keys:

  • A stands for ‘added’, it’s value - added item.
  • D means ‘different’ and contains subdiff.
  • N is a new value for changed item.
  • O is a changed item’s old value.
  • R key used for removed item.
  • U represent unchanged item.

and auxiliary keys:

  • C comment; optional, value - arbitrary string.
  • E extension ID (optional).
  • I index for sequence item, used only when prior item was omitted.

Diff metadata alternates with actual data; simple types specified as is, dicts,
lists and tuples contain subdiffs for their items with native for such types
addressing: indexes for lists and tuples, keys for dictionaries. Any status
key, except D may be omitted during diff computation. E key is used with
D when entity unable to contain diff by itself (set, frozenset for example);
D contain a list of subdiffs in this case.

Annotated example

  1. a: {"one": [5,7]}
  2. b: {"one": [5], "two": 2}
  3. opts: U=False # omit unchanged items
  4. diff:
  5. {"D": {"one": {"D": [{"I": 1, "R": 7}]}, "two": {"A": 2}}}
  6. | | | | | | || | | | | | | | |
  7. | | | | | | || | | | | | | | +- with value 2
  8. | | | | | | || | | | | | | +- key 'two' was added
  9. | | | | | | || | | | | | +- subdiff for it
  10. | | | | | | || | | | | +- another key from top-level
  11. | | | | | | || | | | +- what it was (item's value: 7)
  12. | | | | | | || | | +- what happened to item (removed)
  13. | | | | | | || | +- list item's actual index
  14. | | | | | | || +- prior item was omitted
  15. | | | | | | |+- subdiff for list item
  16. | | | | | | +- it's value - list
  17. | | | | | +- it is deeply changed
  18. | | | | +- subdiff for key 'one'
  19. | | | +- it has key 'one'
  20. | | +- top-level thing is a dict
  21. | +- changes somewhere deeply inside
  22. +- diff is always a dict

License

Licensed under the terms of the Apache License, Version 2.0.

See Also

HOWTO

deepdiff,
jsondiff,
jsonpatch,
json-delta