2015-02-10 47 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