python / python/cpython

Traceback leaks global code when `exec`:ed code raises

未關閉
#122,071 11 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

Bug report

Bug description:

Details

The traceback module's various functions for inspecting an exception leaks surrounding code when used to inspect an exception originating from an exec or eval call. I discovered this using traceback.format_exception but it applies to traceback.print_exc and the other ones that call or are called by those as well.
Specifically when compiled for "exec" mode using compile, and the exec:ed code inherits the context from which exec was called.

In this example, the comment on the first line is included in the printed traceback.

# Hi, I'm in the error message
import traceback
try:
    exec(compile("tuple()[0]", "s", "exec"))
except:
    traceback.print_exc()

This prints:

Traceback (most recent call last):
  File "<filename>", line 4, in <module>
    exec(compile("tuple()[0]", "s", "exec"))
  File "s", line 1, in <module>
    # Hi, I'm in the error message
IndexError: tuple index out of range

It seems that whatever line number the error is on in the exec:ed code is applied to the calling file instead of the exec:ed code.
Changing line 4 in the example above to exec("tuple()[0]") avoids the issue, and no info regarding the line is printed by traceback. This behavior is in line with what python outputs when the exception is not caught:

# Hi, I'm not in the error message
exec(compile("tuple()[0]", "s", "exec"))

results in:

Traceback (most recent call last):
  File "<filename>", line 2, in <module>
    exec(compile("tuple()[0]", "s", "exec"))
  File "s", line 1, in <module>
IndexError: tuple index out of range

Summary

Example code

# Hi, I'm in the error message
import traceback
try:
    exec(compile("tuple()[0]", "s", "exec"))
except:
    traceback.print_exc()
Expected behaviour

Should print the following:

Traceback (most recent call last):
  File "<filename>", line 4, in <module>
    exec(compile("tuple()[0]", "s", "exec"))
  File "s", line 1, in <module>
IndexError: tuple index out of range
Actual behaviour

Prints this:

Traceback (most recent call last):
  File "<filename>", line 4, in <module>
    exec(compile("tuple()[0]", "s", "exec"))
  File "s", line 1, in <module>
    # Hi, I'm in the error message
IndexError: tuple index out of range
CPython versions tested on:

3.8, 3.10, 3.11, 3.12

Operating systems tested on:

Linux, Windows

Linked PRs
  • gh-122126

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

首先使用 traceback.format_exception 和 traceback.print_exc 重現範例,比較編譯後的 exec 程式碼與直接 exec,以及未捕捉的例外。追蹤 traceback 渲染如何為 exec frame 使用檔案名稱和行號;當預期輸出省略呼叫者的原始碼行時即表示完成,包括所描述的其他 traceback 函式。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
backend
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
描述清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。