python / python/cpython

Exceptions raised while tracing certain statements cannot be caught

Abierto
#148,278 4 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

3.13 3.14 3.15 interpreter-core type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
35.9k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Bug report

So I found a really odd bug today. except blocks don't catch exceptions raised when tracing certain statements that themselves "cannot raise". For example:

def f():
    breakpoint()
    try:
        pass  # If you raise while tracing this line, the exception isn't caught.
    except:
        ...
    try:
        42  # Ditto.
    except:
        ...
    try:
        return  # Ditto.
    except:
        ...

A couple of observations:

  • Exceptions raised while tracing other "normal" statements are handled the normal way.
  • The code for the exception handling is still present in these examples, even though it's statically unreachable.
  • If two or more of these "non-raising" statements occur together in the same block (like several pass statements in a row), only the last one will have the bug:
def f():
    breakpoint()
    try:
        pass  # No bug
        pass  # No bug
        pass  # Bug
    except:
        ...

I haven't invested any time into figuring out what the root cause is, I've just been poking at it with code examples. It's definitely a bug in the bytecode compiler though, not the interpreter (dis shows missing exception table entries). Probably something to do with how we emit exception tables for NOP or anything that unwinds the block stack, if I had to guess?

(This also affects 3.12, and maybe even earlier versions, but only tagging for 3.13 and newer since I don't think this is a "security" issue.)

Linked PRs
  • gh-148333

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Reproduce los ejemplos del issue e inspecciona su salida de dis, centrándote en las entradas faltantes de la tabla de excepciones para pass, 42 y return. Compara estos casos con el trazado de instrucciones normales y examina cómo gestiona el compilador NOP y el desenrollado de la pila de bloques. Se considera terminado cuando los bloques except capturan las excepciones producidas al trazar estas instrucciones, con cobertura de regresión para los casos descritos.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
compilers
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.