Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 36 additions & 11 deletions Doc/library/difflib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ Diff generation
.. method:: make_file(fromlines, tolines, fromdesc='', todesc='', context=False, \
numlines=5, *, charset='utf-8')

Compares *fromlines* and *tolines* (lists of strings) and returns a string which
Compares *fromlines* and *tolines* (sequences of strings) and returns a string which
is a complete HTML file containing a table showing line by line differences with
inter-line and intra-line changes highlighted.

Expand All @@ -222,7 +222,7 @@ Diff generation

.. method:: make_table(fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5)

Compares *fromlines* and *tolines* (lists of strings) and returns a string which
Compares *fromlines* and *tolines* (sequences of strings) and returns a string which
is a complete HTML table showing line by line differences with inter-line and
intra-line changes highlighted.

Expand All @@ -233,7 +233,7 @@ Diff generation

.. function:: context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n')

Compare *a* and *b* (lists of strings); return a delta (a :term:`generator`
Compare *a* and *b* (sequences of strings); return a delta (a :term:`generator`
generating the delta lines) in context diff format.

Context diffs are a compact way of showing just the lines that have changed plus
Expand Down Expand Up @@ -306,7 +306,7 @@ Diff generation

.. function:: ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK)

Compare *a* and *b* (lists of strings); return a :class:`Differ`\ -style
Compare *a* and *b* (sequences of strings); return a :class:`Differ`\ -style
delta (a :term:`generator` generating the delta lines).

Optional keyword parameters *linejunk* and *charjunk* are filtering functions
Expand Down Expand Up @@ -364,7 +364,7 @@ Diff generation

.. function:: unified_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n', *, color=False)

Compare *a* and *b* (lists of strings); return a delta (a :term:`generator`
Compare *a* and *b* (sequences of strings); return a delta (a :term:`generator`
generating the delta lines) in unified diff format.

Unified diffs are a compact way of showing just the lines that have changed plus
Expand Down Expand Up @@ -449,6 +449,32 @@ Junk definition functions

.. _sequence-matcher:

.. class:: Match

The type of the objects returned by :meth:`SequenceMatcher.find_longest_match`
and :meth:`SequenceMatcher.get_matching_blocks`. It is an object with a
:term:`named tuple` interface: values can be accessed by index and by
attribute name. It has the following fields:

.. list-table::

* - Index
- Attribute
- Value

* - 0
- .. attribute:: a
- The index in the first sequence of the matching block.

* - 1
- .. attribute:: b
- The index in the second sequence of the matching block.

* - 2
- .. attribute:: size
- The number of elements in the matching block.


SequenceMatcher objects
-----------------------

Expand Down Expand Up @@ -513,7 +539,8 @@ SequenceMatcher objects
Find longest matching block in ``a[alo:ahi]`` and ``b[blo:bhi]``.

If *isjunk* was omitted or ``None``, :meth:`find_longest_match` returns
``(i, j, k)`` such that ``a[i:i+k]`` is equal to ``b[j:j+k]``, where ``alo
a :class:`Match` named tuple ``(i, j, k)`` such that ``a[i:i+k]`` is
equal to ``b[j:j+k]``, where ``alo
<= i <= i+k <= ahi`` and ``blo <= j <= j+k <= bhi``. For all ``(i', j',
k')`` meeting those conditions, the additional conditions ``k >= k'``, ``i
<= i'``, and if ``i == i'``, ``j <= j'`` are also met. In other words, of
Expand Down Expand Up @@ -541,18 +568,16 @@ SequenceMatcher objects
>>> s.find_longest_match(0, 5, 0, 9)
Match(a=1, b=0, size=4)

If no blocks match, this returns ``(alo, blo, 0)``.

This method returns a :term:`named tuple` ``Match(a, b, size)``.
If no blocks match, this returns ``Match(alo, blo, 0)``.

.. versionchanged:: 3.9
Added default arguments.


.. method:: get_matching_blocks()

Return list of triples describing non-overlapping matching subsequences.
Each triple is of the form ``(i, j, n)``,
Return list of :class:`Match` triples describing non-overlapping matching
subsequences. Each triple is of the form ``(i, j, n)``,
and means that ``a[i:i+n] == b[j:j+n]``. The
triples are monotonically increasing in *i* and *j*.

Expand Down
15 changes: 8 additions & 7 deletions Lib/difflib.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
Use SequenceMatcher to return list of the best "good enough" matches.

Function context_diff(a, b):
For two lists of strings, return a delta in context diff format.
For two sequences of strings, return a delta in context diff format.

Function ndiff(a, b):
Return a delta: the difference between `a` and `b` (lists of strings).
Return a delta: the difference between `a` and `b` (sequences of strings).

Function restore(delta, which):
Return one of the two sequences that generated an ndiff delta.

Function unified_diff(a, b):
For two lists of strings, return a delta in unified diff format.
For two sequences of strings, return a delta in unified diff format.

Class SequenceMatcher:
A flexible class for comparing pairs of sequences of any type.
Expand Down Expand Up @@ -310,7 +310,8 @@ def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):

If isjunk is not defined:

Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
Return a Match named tuple (i, j, k) such that a[i:i+k] is equal to
b[j:j+k], where
alo <= i <= i+k <= ahi
blo <= j <= j+k <= bhi
and for all (i',j',k') meeting those conditions,
Expand Down Expand Up @@ -342,7 +343,7 @@ def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
>>> s.find_longest_match(0, 5, 0, 9)
Match(a=1, b=0, size=4)

If no blocks match, return (alo, blo, 0).
If no blocks match, return Match(alo, blo, 0).

>>> s = SequenceMatcher(None, "ab", "c")
>>> s.find_longest_match(0, 2, 0, 1)
Expand Down Expand Up @@ -420,7 +421,7 @@ def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None):
return Match(besti, bestj, bestsize)

def get_matching_blocks(self):
"""Return list of triples describing matching subsequences.
"""Return list of Match triples describing matching subsequences.

Each triple is of the form (i, j, n), and means that
a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in
Expand Down Expand Up @@ -1323,7 +1324,7 @@ def decode(s):

def ndiff(a, b, linejunk=None, charjunk=IS_CHARACTER_JUNK):
r"""
Compare `a` and `b` (lists of strings); return a `Differ`-style delta.
Compare `a` and `b` (sequences of strings); return a `Differ`-style delta.

Optional keyword parameters `linejunk` and `charjunk` are for filter
functions, or can be None:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Improve the :mod:`difflib` documentation: describe the :class:`difflib.Match`
named tuple and state that :meth:`~difflib.SequenceMatcher.find_longest_match`
and :meth:`~difflib.SequenceMatcher.get_matching_blocks` return ``Match``
objects. Clarify that the diff functions accept sequences of strings, not
just lists.
Loading