pylint 1.4报告所有C扩展上的E1101(无成员)

时间:2015-02-10 16:44:19

标签: python pylint python-extensions

我们是pylint的长期粉丝。它的静态分析已成为我们所有python项目的关键部分,并且节省了大量时间来追逐晦涩的错误。但从1.3升级后 - > 1.4,几乎所有编译的c扩展都会导致E1101(无成员)错误。

以前通过pylint 1.3完全清理的项目现在抱怨几乎每个使用E1101的C扩展成员。我们被迫禁用E1101错误,但这实际上减损了pylint的用处。

例如,lxml包的完全有效使用

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

通过pylint运行,并报告:

$ 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中发生的变化。我们很乐意修复满足pylint的代码(或者至少发布C扩展作者的最佳实践文档)。

平台详情

$ 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)]

4 个答案:

答案 0 :(得分:61)

在发布我的问题后不久,我找到了答案。事实上,这种改变是作为一种安全措施而有目的地进行的。 Pylint导入模块以有效识别有效的方法和属性。决定导入不属于python stdlib的c扩展是一种安全风险,可能会引入恶意代码。

这是在Astroid 1.3.1 https://mail.python.org/pipermail/code-quality/2014-November/000394.html

的发布中完成的
  

仅受信任来源(标准库)的C扩展名   加载到检查Python进程中以从实时构建AST   模块。

如果要在导入非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)使用pylint.rc选项列出您信任由pylint在extension-pkg-whitelist=文件中加载的包名称或模块名称。

4)创建一个操作AST的插件(我不知道如何实现这一点 - 但它会在pylint邮件列表中定期讨论)。

我们选择了选项3.我们在项目pylint.rc文件中添加了以下行:

extension-pkg-whitelist=lxml

答案 1 :(得分:7)

@ user590028,非常感谢您的回答!我刚刚遇到了与win32api,win32evtlog,win32file,win32gui和win32process库相同的问题,你的解决方案也运行了。

我使用了另一种我认为值得发布的方法,即调用pylint并将列入白名单的包作为参数传递:

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

答案 2 :(得分:4)

对于那些使用VS Code的人来说,由于找不到可执行文件,所以很难找到命令的存放位置。

在VS Code中;

  1. 单击文件>首选项>设置。
  2. 在左侧窗口中向下滚动到“ Python配置”
  3. 在右侧窗口中向下滚动至“ Python Linting:Mypy Args”
  4. 点击“在settings.json中编辑”链接
  5. 编辑json以包括:     “ --extension-pkg-whitelist =”

我必须做所有这一切,因为无法从Windows命令行执行PyLint ...

答案 3 :(得分:0)

如果您使用的是Mac的VS Code,则需要执行以下操作才能编辑settings.json文件:

  1. 单击代码(即“文件”标签左侧的Visual Studio“代码”标签)->“首选项”->“设置”
  2. 向下滚动到扩展,然后在列表中单击Python。
  3. 单击任何Edit in settings.json链接。这将打开settings.json进行编辑。
  4. 添加行"python.linting.pylintArgs": ["----extension-pkg-whitelist=1xml"]