[英]Why does Python read from the current directory when printing a traceback?
$ echo "Your code is bad and you should feel bad" > "<stdin>"
$ python
Python 3.6.0 (default, Dec 28 2016, 19:53:26)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 2 + '2'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Your code is bad and you should feel bad
TypeError: unsupported operand type(s) for +: 'int' and 'str'
為什么 Python 會將字符串"<stdin>"
與匹配該文件名的文件混淆? 如果遇到未處理的異常,我不希望 Python 嘗試從我的磁盤讀取任何文件。
您還可以使用"<string>"
文件名獲取它:
$ echo "pining for the fjords" > "<string>"
$ python -c 'wat'
Traceback (most recent call last):
File "<string>", line 1, in <module>
pining for the fjords
NameError: name 'wat' is not defined
有什么辦法可以防止這種行為,還是硬編碼到 REPL 中?
Python 不會跟蹤哪些源代碼對應於任何已編譯的字節碼。 在需要打印回溯之前,它甚至可能不會讀取該源代碼,例如,如果從.pyc
文件加載模塊。
當 Python 需要打印回溯時,它會嘗試查找與所涉及的所有堆棧幀對應的源代碼。 您在堆棧跟蹤中看到的文件名和行號都是 Python 必須繼續的。 如果它正在使用traceback
模塊,則代碼路徑將通過linecache
中排除以<
和>
開頭和結尾的文件名的部分,但默認的sys.excepthook
不會通過該路徑。
默認的sys.excepthook
通過本機調用PyErr_Display
,最終使用_Py_DisplaySourceLine
顯示單個源代碼行。 _Py_DisplaySourceLine
無條件地嘗試在當前工作目錄中查找文件(出於某種原因 - 誤導優化?),然后調用_Py_FindSourceFile
以在sys.path
中搜索與該名稱匹配的文件,如果工作目錄沒有它。 通常,它不會找到<stdin>
或<string>
文件,並且當它找不到文件時它只會跳過打印源代碼,但如果找到一個,它會從該文件打印。
我最初認為你可以通過使用-I
標志運行 Python 來防止這種情況,將其置於隔離模式。 隔離模式的影響之一是從sys.path
刪除腳本的目錄。 實驗證明這並沒有改變事情,這就是當我意識到_Py_DisplaySourceLine
嘗試工作目錄的時候。
通過在本機代碼路徑中排除<>
文件名來解決這個問題是相當簡單的,就像linecache
一樣。 無條件在當前目錄中搜索文件的代碼也應該更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.