Krikri::Difflib
Python's difflib.SequenceMatcher and difflib.unified_diff, ported so
that krikri's --diff bodies are byte-identical with ansible-playbook's.
Ansible does NOT shell out to diff: its callback builds each diff body
with difflib.unified_diff(before.splitlines(True), after.splitlines(True), ..., n=3) and prints every yielded line
(ansible/plugins/callback/__init__.py, _get_diff). The two
algorithms can pick different maximal matching blocks, so the same
before/after pair renders the same lines in a different -/+/
context arrangement: martin-micimo.haproxy's /etc/haproxy/haproxy.cfg
(34 lines -> 35) gave a GNU-diff body of 2400 B against ansible's
2394 B, and that was the last difference in the role's cold phase
(issues #566, #736). The port below keeps difflib's own names and
structure so it can be checked against the Python source line by line.
Constants
difflib.SequenceMatcher's autojunk heuristic only kicks in for sequences at least this long, and then drops elements that appear more than len(b)//100 + 1 times (ansible passes no isjunk, and the default autojunk=True).
Python's str.splitlines(True): the line terminators it recognises,
kept on each line.
Class methods
The line lists ansible's callback diffs: splitlines(True) plus that
module's "no newline at end of file" note folded into the last line
(_get_diff in ansible/plugins/callback/init.py), so the note
renders as a normal -/+/context line rather than GNU diff's own
trailing marker.
difflib.unified_diff's full output, headers included, each line still carrying its trailing newline exactly like Python's generator yields. ansible's callback prints every yielded line verbatim after colouring it by its first character.