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

Aberta Para iniciantes
#161,973 0 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
78/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
python
Domínio
tooling

Direção de pesquisa

Comece pelo comportamento relatado de SequenceMatcher.get_opcodes() e get_grouped_opcodes(), usando o reproducer da issue para comparar os resultados antes e depois do agrupamento. O trabalho estará concluído quando chamar get_grouped_opcodes() não alterar mais os opcodes completos retornados posteriormente e o agrupamento com um n maior mantiver o contexto esperado.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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

Linguagem predominante
Python
Estrelas
78.2k
Forks
36.6k
Merge médio
19h 57min
PRs com merge (30d)
630

Preparar o ambiente

Abrir no Codespaces

Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de python/cpython

Todas as issues de python/cpython

Issues semelhantes

Mais issues de Python

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.