GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — difflib.SequenceMatcher and Match: code and doc bugs · Issue #56593 · python/cpython

difflib.SequenceMatcher and Match: code and doc bugs #56593

New issue
Copy link
New issue
Copy link
Open
Open
difflib.SequenceMatcher and Match: code and doc bugs#56593
Copy link
Assignees
terryjreedy
Labels
docsDocumentation in the Doc dirDocumentation in the Doc dirstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory

Description

@terryjreedy
terryjreedy
opened on Jun 21, 2011
Issue body actions
BPO 12384
Nosy @tim-one, @rhettinger, @terryjreedy
Files
  • 12384-patch.txt
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = 'https://github.com/terryjreedy'
    closed_at = None
    created_at = <Date 2011-06-21.20:00:41.301>
    labels = ['type-bug', '3.9', '3.10', '3.11', 'library', 'docs']
    title = 'difflib.SequenceMatcher and Match: code and doc bugs'
    updated_at = <Date 2021-12-03.21:27:55.626>
    user = 'https://github.com/terryjreedy'

    bugs.python.org fields:

    activity = <Date 2021-12-03.21:27:55.626>
    actor = 'iritkatriel'
    assignee = 'terry.reedy'
    closed = False
    closed_date = None
    closer = None
    components = ['Documentation', 'Library (Lib)']
    creation = <Date 2011-06-21.20:00:41.301>
    creator = 'terry.reedy'
    dependencies = []
    files = ['34501']
    hgrepos = []
    issue_num = 12384
    keywords = []
    message_count = 5.0
    messages = ['138799', '138804', '139179', '184616', '214035']
    nosy_count = 3.0
    nosy_names = ['tim.peters', 'rhettinger', 'terry.reedy']
    pr_nums = []
    priority = 'normal'
    resolution = None
    stage = 'patch review'
    status = 'open'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue12384'
    versions = ['Python 3.9', 'Python 3.10', 'Python 3.11']

    Linked PRs

    • gh-56593: Document the difflib Match named tuple #155598

    Activity

    1. terryjreedy commented on Jun 21, 2011

      @terryjreedy
      terryjreedy
      on Jun 21, 2011
      MemberAuthor
      More actions

      The basic problem: in 2.6, a namedtuple was introduced to difflib

      from collections import namedtuple as _namedtuple
      Match = _namedtuple('Match', 'a b size')

      and used for the return values of SeqeunceMatcher.get_longest_match and .get_matching_blocks. Code, docstrings, and docs were only partially updated to match.

      Code:

          def get_matching_blocks(self):
              """Return list of triples describing matching subsequences.
              Each triple is of the form (i, j, n), and means that
              ...'''
              if self.matching_blocks is not None:
                  return self.matching_blocks
              ...
              self.matching_blocks = non_adjacent
              return map(Match._make, self.matching_blocks)

      The two returns are different because only the second was changed.
      The obvious fix is to change the first to match. Or perhaps self.matching_blocks (an undocumented cache) should be the map object.

      Docstring and doc for .find_longest_match():

      Both start
      "Find longest matching block ... returns (i, j, k) such that ... "
      Doc (bug not docstring) explicitly says at the *bottom* of the entry "This method returns a named tuple Match(a, b, size)."
      which is different from (i,j,n). For 2.7, the note is preceded by "Changed in version 2.6:"
      The examples show the change before it is described.

      I think that the current return should be accurately described at the *top* of the entry, not the bottom. 2.7 would then end with "Changed in version 2.6: return Match instead of tuple."

      Docstring and doc for .get_matching_blocks():

      See code snippet above for beginning of text. Unlike .find_longest_match, there is no mention of the changed return.

      In 2.7, it is a list of Match triples.
      In 3.x, it is an iterable (Map) of Match triples, because of the change in map() return.

      For the latter reason, the example in the 3.x doc must be changed to
      >>> list(s.get_matching_blocks())

      The docstring was already changed to pass doctest. The untested doc was not.

      I am not sure how to properly document the use of a namedtuple in the stdlib. Raymond, what do you think?

    2. terryjreedy
      assigned
      rhettinger
      on Jun 21, 2011
    3. terryjreedy
      added
      docsDocumentation in the Doc dirDocumentation in the Doc dir
      stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      on Jun 21, 2011
    4. rhettinger commented on Jun 21, 2011

      @rhettinger
      rhettinger
      on Jun 21, 2011
      Contributor
      More actions

      I'll take a look at this when I get a chance (est. two weeks).

    5. rhettinger commented on Jun 26, 2011

      @rhettinger
      rhettinger
      on Jun 26, 2011
      Contributor
      More actions

      Go head an patch the first self.matching_blocks to also return a named tuple. Also, correct any doctests or examples using these.

      The docs could also mention that list of namedtuples with fields a, b, and size is returned by get_matching_blocks().

    6. rhettinger
      assigned
      terryjreedy
      and unassigned
      rhettinger
      on Jun 26, 2011
    7. terryjreedy commented on Mar 19, 2013

      @terryjreedy
      terryjreedy
      on Mar 19, 2013
      MemberAuthor
      More actions

      More doc bugs: unified_diff and context_diff say 'lists of strings' when 'sequences of strings' is correct. Docstrings do say 'sequences'.

      In 3.x, SequenceMatcher.get_matching_blocks return a map objects rather than a list. In spite of my original post, the items are tuples in 3.3, as least in one test. Named tuples in 3.4 would be good. I might call it an iterable of (names) triples instead of 'map object' as that is more relevant for the user. I think I should check all arg and return types in code, docstring, and doc for consistency and separately check on and as necessary upgrade namedtuple usage.

    8. akuchling commented on Mar 18, 2014

      @akuchling
      akuchling
      on Mar 18, 2014
      Contributor
      More actions

      Here's a patch fixing the first return in get_matching_blocks() and updating the docs.

      I didn't change get_matching_blocks() to return a list again, assuming that we didn't want to do that. (Raymond doesn't say to do so, at least.)

    9. iritkatriel
      added
      3.9 (EOL)end of lifeend of life
      3.10 (EOL)end of lifeend of life
      3.11only security fixesonly security fixes
      on Dec 3, 2021
    10. ezio-melotti
      transferred this issue fromon Apr 10, 2022
    11. Lenormju commented on Jul 18, 2026

      @Lenormju
      Lenormju
      on Jul 18, 2026
      Contributor
      More actions

      This issue is 15 years old.
      Match = _namedtuple('Match', 'a b size') is still there. But the original claim:

      Code, docstrings, and docs were only partially updated to match.

      is now obsolete:

      • for the code of get_matching_blocks, its (still) 2 return instructions are now:
        • if self.matching_blocks is not None:
            return self.matching_blocks
        • self.matching_blocks = list(map(Match._make, non_adjacent))
            return self.matching_blocks
        The second one is the terminal-recursive case, apart from that it is only assigned to None or read. The code was fixed by difflib.SequenceMatcher stores matching blocks as tuples, not Match named tuples #65834
      • for get_matching_blocks actually returning maps instead of sequences (list), that's solved now (same commit than before)
      • and for the documentation of find_longest_match and get_matching_blocks, the 2.6 parts can be ignored now, but it remains that the return type is not stated explicitly (no modern ->, no Sphinx-standard :rtype: Match). This information is missing both on the code docstring side, and the .rst doc side. Also Match is currently not described in the rst docs.
        I'm unsure if it is worth a pull request though. I did not find other tickets about this documentation need.
    12. devdanzin
      removed
      type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
      3.11only security fixesonly security fixes
      3.10 (EOL)end of lifeend of life
      3.9 (EOL)end of lifeend of life
      on Aug 10, 2026
    13. github-project-automation
      added this to docs issueson Aug 10, 2026
    14. github-project-automation
      moved this to Todo in docs issueson Aug 10, 2026
    15. Khan3K
      added 3 commits that reference this issue on Aug 12, 2026

      Add news entry for pythongh-56593 docs improvement

      5c6dc38

      pythongh-56593: Document the difflib Match named tuple

      b9204a4

      Add news entry for pythongh-56593 docs improvement

      a34e08c
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    • @terryjreedy
      terryjreedy

    Labels

    docsDocumentation in the Doc dirDocumentation in the Doc dirstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory

    Projects

    • docs issues
      Status
      Todo
      Show more project fields

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.