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

use*_*028 47 python pylint python-extensions

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

之前通过pylint1.3 运行完全清洁的项目现在抱怨几乎每个使用E1101的C扩展成员.我们被迫禁用E1101错误,但这实际上减损了它的用处pylint.

例如,这完全有效地使用了lxml

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

运行此过程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)
Run Code Online (Sandbox Code Playgroud)

但它完全有效:

$ python valid.py
<Element mydoc at 7fddf67b1ba8>
Run Code Online (Sandbox Code Playgroud)

这里真的很奇怪.一小部分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
Run Code Online (Sandbox Code Playgroud)

我的问题是,还有其他人目睹过这个吗?如果是这样,您愿意分享您的解决方法/解决方案吗?

我们已经尝试过尝试创建插件来抑制这些警告(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)]
Run Code Online (Sandbox Code Playgroud)

use*_*028 63

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

这是在Astroid 1.3.1发布时完成的 https://mail.python.org/pipermail/code-quality/2014-November/000394.html

只有来自可信源(标准库)的C扩展才会加载到检查Python进程中,以便从live模块构建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使用extension-pkg-whitelist=选项列出您信任由pylint在文件中加载的包或模块名称.

4)创建一个操作AST的插件(我不知道如何实现这个 - 但它经常在pylint邮件列表上讨论).

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

extension-pkg-whitelist=lxml
Run Code Online (Sandbox Code Playgroud)

  • 现在称为“extension-pkg-allow-list” (3认同)

twa*_*lig 7

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

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

pylint --extension-pkg-whitelist=win32api,win32evtlog,win32file,win32gui,win32process myfile.py
Run Code Online (Sandbox Code Playgroud)

  • 我只是想确保人们知道你也可以将它作为命令行参数传递给pylint. (2认同)

小智 5

对于那些使用 VS Code 的人来说,找到放置命令的位置有点棘手,因为我找不到我的可执行文件。

在 VS 代码中;

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

我不得不这样做,因为 PyLint 不能从我的 Windows 命令行执行...