diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 374af16b2b6f98..0aa01297d6d9dc 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -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. @@ -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. @@ -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 @@ -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 @@ -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 @@ -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 ----------------------- @@ -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 @@ -541,9 +568,7 @@ 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. @@ -551,8 +576,8 @@ SequenceMatcher objects .. 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*. diff --git a/Lib/difflib.py b/Lib/difflib.py index 95ba8fd782c6c3..62f40ce1c20a29 100644 --- a/Lib/difflib.py +++ b/Lib/difflib.py @@ -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. @@ -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, @@ -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) @@ -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 @@ -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: diff --git a/Misc/NEWS.d/next/Documentation/2026-08-12-00-00-00.gh-issue-56593.V1fKc3.rst b/Misc/NEWS.d/next/Documentation/2026-08-12-00-00-00.gh-issue-56593.V1fKc3.rst new file mode 100644 index 00000000000000..4115f0f1d5fbc9 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2026-08-12-00-00-00.gh-issue-56593.V1fKc3.rst @@ -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.