2014-02-13 30 views
2

我正在開發一個工具,它必須接受一個文件作爲輸入,檢查語法錯誤,編譯它並在其後執行某些操作。如何在運行之前檢查python代碼的語法錯誤

例如, 我有一個文件run.py:

a=5 
b=c 
print b 

這應該清楚地表明一個語法錯誤,在編譯,因爲「C」是沒有定義

我試圖用

try: 
    py_compile.compile("source_program/run.py", doraise=True) 
    print "Compiled" 
except: 
    print "Error while compiling" 

我得到輸出「編譯」而不是「編譯時出錯」

如果我修改run.py文件:

a=5 
b=c/ #Instead of b=c 
print b 

然後我得到的輸出「錯誤在編譯」

什麼我沒有拿到在第一種情況下的錯誤消息?

+0

'b = c'沒有定義'c'不是一個SyntaxError,而是一個NameError – joaquin

回答

9

這不是語法錯誤。 b=c是完全有效的語法,無論是否存在c。事實上,一些其他的模塊可以做

import __builtin__ 
__builtin__.c = 3 

在這種情況下,會有一個內置的與值3提供給所有的模塊c變量,你的代碼將運行正常。

對於稍差病理例如,如果該文件包含一個*進口如

from numpy import * 

進口將轉儲了一大堆的名字到模塊的全局命名空間,而且也沒有辦法告訴什麼的名字是。但即使沒有import *,Python也無法確定在編譯時對未知名稱的引用是否爲錯誤。

如果你想檢測這樣的語義錯誤,你需要一個更復雜的程序分析。按照NPE的建議,與pylint等現有的linter整合,可能比編寫自己的工具更有效率。如果你真的想自己做,你可以用ast.parse來解析代碼,並檢查AST,逐個聲明地去查看哪些變量存在於哪些點上。你仍然不會捕獲所有的錯誤,但你會發現不少。

+1

謝謝你的回覆。但我不希望它運行良好。我希望它顯示一個錯誤。我的工具應該能夠檢測到錯誤,因爲'c'沒有被定義。 – mea

+1

如果我運行程序運行。py,我在控制檯上得到一個錯誤信息「NameError:name'c'is not defined」 因此,當我運行我的工具時,它應該做類似的工作 – mea

+0

@Melvin:Answer擴展。請注意,儘管NameErrors可以被非常可靠地檢測到,但它並不完美,並且您將很少有運氣檢測到需要更多運行時信息的事物,如IndexErrors。 – user2357112

4

這是一個棘手的問題,原因很多。

嘗試與pylint整合,而不是嘗試自己想出來,這可能不是一個壞主意。

2

c未被定義實際上不是編譯時錯誤。運行時,Python只會在運行時遇到未定義變量的問題。這不會被任何Python編譯器捕獲。

相關問題