symtable: a name read only inside an inlined comprehension is not marked as referenced (3.12+)
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 35/100
Direção de pesquisa
Start with the symtable handling of inlined comprehensions and the related changes in gh-109292 and gh-124697. Run the reproduction across Python 3.12 and 3.14, then compare the symbol table output with the expected reference for k in f. Done means the enclosing function reports the read or symtable exposes it another way, with tests covering the behavior.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Bug report
Bug description
Since PEP 709 (3.12), symtable no longer creates a child table for a list, set or dict comprehension. The 3.12
What's New says the comprehension's locals now appear in the enclosing function's table (gh-109292).
However, a name from the enclosing scope that is read only inside the inlined comprehension is no longer marked
as referenced in the enclosing function's table, and no child table records the read either. The read becomes
invisible to symtable users. On 3.9 (and, as far as I know, up to 3.11), the read appears in the comprehension's own
listcomp table. Generator expressions, which are still separate scopes, are unaffected.
Reproduction:
"""Minimal reproduction: since PEP 709 (Python 3.12), a name read only inside an inlined list comprehension is not
marked as referenced in the enclosing function's symbol table, and no child table holds it either.
Run with several interpreters: python3.9 shows the read (in a 'listcomp' child table); 3.12 and 3.14 lose it."""
import symtable, sys
SRC = '''
def f(xs, k):
return [x + k for x in xs] # list comprehension: inlined since 3.12
def g(xs, k):
return list(x + k for x in xs) # generator expression: still its own scope
'''
def report():
top = symtable.symtable(SRC, "<repro>", "exec")
for fn in top.get_children():
if fn.get_name() not in ("f", "g"):
continue # skip implicit scopes such as __annotate__ (3.14)
k = fn.lookup("k")
children = {c.get_name(): sorted(s.get_name() for s in c.get_symbols() if s.is_referenced())
for c in fn.get_children()}
print(f"{sys.version.split()[0]} {fn.get_name()}: k.is_referenced() = {k.is_referenced()}; "
f"child tables (referenced names) = {children}")
if __name__ == "__main__":
report()
Output (macOS; CPython 3.9.6, 3.12.12, 3.14.7):
3.9.6 f: k.is_referenced() = False; child tables (referenced names) = {'listcomp': ['k', 'x']}
3.9.6 g: k.is_referenced() = False; child tables (referenced names) = {'genexpr': ['k', 'x']}
3.12.12 f: k.is_referenced() = False; child tables (referenced names) = {}
3.12.12 g: k.is_referenced() = False; child tables (referenced names) = {'genexpr': ['k', 'x']}
3.14.7 f: k.is_referenced() = False; child tables (referenced names) = {}
3.14.7 g: k.is_referenced() = False; child tables (referenced names) = {'genexpr': ['k', 'x']}
Expected: in f, k.is_referenced() should be True, since k is read in f's body now that the comprehension
is part of f's scope. Alternatively, symtable should expose the inlined comprehension's references some other way.
Impact: tools that use symtable to find unused parameters or variables, or dead code, get false "unused"
results. In a scan of 35,562 function scopes, this caused 1,885 false disagreements against the compiled bytecode.
Related: gh-109292 (the documentation of the PEP 709 change to symtable); gh-124697 (refactoring of inlined
comprehensions), which may already fix this on main. I have not tested 3.15 / main.
CPython versions tested on:
3.12, 3.14
Operating systems tested on:
macOS
Linked PRs
- gh-160413
- gh-160457
- Linguagem predominante
- Python
- Estrelas
- 77.7k
- Forks
- 38.3k
- Merge médio
- 14h 29min
- PRs com merge (30d)
- 699
Preparar o ambiente
Inicia o contêiner de desenvolvimento do projeto no navegador, com a sua própria conta do GitHub.
- Sem Dockerfile nem arquivo Docker Compose
- Tem um modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de python/cpython
-
topic-socket type-bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
python/cpython#160561 · 7 comentários ·
Mantenedores costumam responder em até 1 dia
-
tests topic-profiling type-bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
python/cpython#160334 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
extension-modules type-bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
Mantenedores costumam responder em até 1 dia
-
Remove unused FVS_* macrosAbertainterpreter-core type-feature
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 78/100
python/cpython#160109 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
extension-modules type-bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
python/cpython#160001 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
Todas as issues de python/cpython
Issues semelhantes
-
README.zh-CN/ja/es still hard-code 501 test counts after README.md went count-freeTalvez já em andamento @Aaqibhafeezkhan assumiu hoje. Abertabeginner documentation good first issue
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
BistaDinesh03/critique#164 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
bug IO
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 65/100
MrNeRF/LichtFeld-Studio#3824 ·
Mantenedores costumam responder em até 1 dia
-
bug confirmed issue
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
open-webui/open-webui#33200 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Lychee link check failedAberta
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 72/100
-
The changelog workflow excludes otelbot but not dependabot, so every Dependabot pull request fails the changelog checkTalvez já em andamento @ocelotl assumiu hoje. Aberta
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 82/100
open-telemetry/opentelemetry-python#5825 ·
Mantenedores costumam responder em até 2 dias