2015-02-10 46 views
31

我們一直是pylint的長期粉絲。它的靜態分析已經成爲我們所有python項目的重要組成部分,並且節省了大量的時間來追逐晦澀的bug。但從1.3 - > 1.4升級後,幾乎所有編譯的c擴展都會導致E1101(無成員)錯誤。pylint 1.4對所有C分機報告E1101(非會員)

以前完全通過pylint 1.3運行完全清潔的項目現在幾乎所有的C擴展成員都抱怨E1101。我們被迫停用E1101錯誤,但這實質上會減損pylint的用處。

例如,通過pylint這一完全合法的使用lxml

r"""valid.py: demonstrate pylint 1.4 error""" 
from lxml import etree 
print etree.Element('mydoc') 

運行這一點,並報告:

$ pylint -rn valid.py 
No config file found, using default configuration 
************* Module valid 
E: 3, 6: Module 'lxml.etree' has no 'Element' member (no-member) 

但它是完全合法的:

$ python valid.py 
<Element mydoc at 7fddf67b1ba8> 

這是它變得非常奇怪的地方。 C擴展的一個非常小的一小撮似乎通過pylint工作得很好,例如:

r"""valid2.py: this one works fine""" 
import sqlite3 
print sqlite3.version 

$ pylint -rn valid2.py 
No config file found, using default configuration 

我的問題是,有其他人見證了這一點?如果是這樣,你願意分享你的解決方法嗎?

我們已經嘗試,試圖創建插件來抑制這些警告 (http://docs.pylint.org/plugins.html#enter-plugin),但我們遇到的困難做頭或文檔的尾巴 - 和astroid基類是超級複雜和蔑視我們試圖饒舌它。

對於真正的獎勵積分(以及我們永恆的感激之情),我們很樂意瞭解pylint中發生了哪些變化。我們很樂意修復代碼(或者至少爲C擴展作者發佈最佳實踐文檔),以滿足pylint

平臺細節

$ pylint --version 
No config file found, using default configuration 
pylint 1.4.0, 
astroid 1.3.2, common 0.63.2 
Python 2.7.5 (default, Jul 1 2013, 18:09:11) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] 

回答

38

不久發佈我的問題後,我找到了答案。事實上,這一變化是作爲安全措施而進行的。 Pylint導入模塊以有效識別有效的方法和屬性。決定導入不屬於python stdlib的c擴展是一種安全風險,可能會引入惡意代碼。

這在兒童睡前故事的版本做了1.3.1 https://mail.python.org/pipermail/code-quality/2014-November/000394.html

只從信任的來源(標準庫)是 裝入檢查Python進程從現場 模塊構建AST C擴展。

如果您想在導入非stdlib c擴展名的項目上使用pylint,有四種解決方案。

1)使用--unsafe-load-any-extension=y命令行選項禁用安全功能。此功能未被記錄並歸類爲隱藏選項(https://mail.python.org/pipermail/code-quality/2014-November/000439.html)。

2)使用pylint.rc設置unsafe-load-any-extensions=yes來禁用安全性。建議使用選項1,並在默認pylint.rc文件中包含完整文檔(使用--generate-rcfile創建)。

3)使用extension-pkg-whitelist=選項,明確列出您信任的pylint將在pylint.rc文件中加載的軟件包或模塊名稱。

4)創建一個插件來操縱AST(我不知道如何實現這個效果 - 但它定期在pylint郵件列表上討論)。

我們選擇了選項3.添加了下面的一行到我們的項目pylint.rc文件:

extension-pkg-whitelist=lxml 
+0

非常感謝你。不過,我必須注意到,選項3不幸似乎不適用於某些STL包,例如'multiprocessing'。 – 4ae1e1 2015-06-10 07:59:27

+0

對於#4,這個文檔似乎直接解決了如何修正假陽性'no-member's - http://docs.pylint.org/plugins.html – 2015-07-22 02:34:43

+0

@SpainTrain鏈接已經死亡。 – ppperry 2016-07-07 19:40:49

5

@ user590028,非常感謝您的回答!我剛剛遇到了庫win32api,win32evtlog,win32file,win32gui和win32process的相同問題,並且解決方案正常運行。

我用另一種方法,我認爲是值得在這裏發帖,這是調用pylint的和通過白名單包作爲一個參數:

pylint --extension-pkg-whitelist=win32api,win32evtlog,win32file,win32gui,win32process myfile.py 
+1

非常歡迎。 fyi - 「extension-pkg-whitelist」是選項3,與我們選擇的是同一個選項。 – user590028 2015-02-18 00:56:57

+2

我只是想確保人們知道你可以將它作爲命令行參數傳遞給pylint。 – twasbrillig 2015-02-18 05:31:52