SequenceMatcher.get_grouped_opcodes() changes the result of later get_opcodes() calls

Aperta Adatta ai principianti
#161,973 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
tooling

Direzione di ricerca

Inizia dal comportamento segnalato di SequenceMatcher.get_opcodes() e get_grouped_opcodes(), usando il reproducer dell’issue per confrontare i risultati prima e dopo il raggruppamento. Il lavoro è completo quando una chiamata a get_grouped_opcodes() non modifica più gli opcode completi restituiti in seguito e il raggruppamento con un n più grande mantiene il contesto previsto.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Bug report

SequenceMatcher.get_opcodes() caches its result and returns the same list on every call. get_grouped_opcodes() takes that list and overwrites its first and last entries to trim the context, so after one call the matcher's opcodes no longer cover the whole input, and a later get_grouped_opcodes() with a larger n shows less context than it should.

This was mentioned in gh-54194 back in 2010, but that issue was closed after only the get_matching_blocks() part was fixed (gh-65834); the get_grouped_opcodes() part is still there.

import difflib

old = ["line %d\n" % i for i in range(10)]
new = old[:]
new[5] = "changed\n"

sm = difflib.SequenceMatcher(None, old, new)
for group in sm.get_grouped_opcodes(1):
    pass  # show the hunks with one line of context
print(sm.get_opcodes())

Actual:

[('equal', 4, 5, 4, 5), ('replace', 5, 6, 5, 6), ('equal', 6, 7, 6, 7)]

Expected (what get_opcodes() returns before the get_grouped_opcodes() call):

[('equal', 0, 5, 0, 5), ('replace', 5, 6, 5, 6), ('equal', 6, 10, 6, 10)]

unified_diff() and context_diff() are not affected because they make a new matcher each time.

CPython versions tested on:

3.15, CPython main branch

Operating systems tested on:

Linux


Found while building a Lean 4 model of CPython (https://broyojo.com/python-formalization/). AI tools (Claude) helped investigate the findings and prepare this report. The examples were rerun on CPython 3.15.2 and main, and the report received technical review. Record: textlibs-difflib-grouped-opcodes-mutates-cache

Lingua principale
Python
Stelle
78.2k
Fork
36.6k
Merge medio
19h 57m
PR unite (30g)
630

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di python/cpython

Tutte le issue di python/cpython

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.