【发布时间】:2020-06-26 09:54:32
【问题描述】:
从 pylint 得到误报
考虑这段代码:
previous = None
for word in ['you', 'cannot', 'be', 'serious']:
if previous is not None:
print(previous[0], word)
previous = word
这是输出(这里没有惊喜):
$ python3 test.py
y cannot
c be
b serious
使用pylint 检查它会得到以下结果:
$ pylint3 test.py
No config file found, using default configuration
************* Module test
C: 1, 0: Missing module docstring (missing-docstring)
C: 1, 0: Constant name "previous" doesn't conform to UPPER_CASE naming style (invalid-name)
E: 4,14: Value 'previous' is unsubscriptable (unsubscriptable-object)
--------------------------------------------------------------------
Your code has been rated at -4.00/10 (previous run: -4.00/10, +0.00)
如您所见,pylint 抱怨表达式 previous[0] 基于 previous 初始化为 None 的事实,即使当它具有该值时无法访问该语句。此外,尽管在最后一行进行了赋值,但它仍以 previous 是一个常量为基础抱怨命名风格。
问题:是否有任何合适的 pylint 配置可以避免此类误报,而不会引入同样明显的误报,如果有,为什么这不是默认配置?
尝试的解决方案:禁用测试(导致假阴性)
例如,我可以完全抑制unsubscriptable-object 警告,方法是创建一个包含pylint3 --generate-rcfile 输出的$HOME/.pylintrc,并对其进行编辑以将unsubscriptable-object 添加到禁用测试列表中(参见@987654336 @在[MESSAGES CONTROL]部分中)。
但是,如果我简单地以这种方式禁用测试,然后验证以下代码:
"false negative" # silence docstring warning (fair enough)
print(None[0]) # this line will fail
它告诉我:
$ pylint3 test2.py
Using config file /home/<myuser>/.pylintrc
--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)
所以仅仅禁用测试并不是真正的答案。
版本和平台信息
版本信息:
$ pylint3 --version
Using config file /home/<myuser>/.pylintrc
pylint3 1.8.3,
astroid 1.6.0
Python 3.6.9 (default, Apr 18 2020, 01:56:04)
[GCC 8.4.0]
平台:Ubuntu 18.04.4 LTS
【问题讨论】:
-
您使用的是最新版本的 pylint 吗?根据我的经验,新版本不会出现不可订阅对象错误误报。似乎他们定期改进他们的类型干扰逻辑。无效名称错误不是恕我直言误报。您在配置文件中为全局变量选择 UPPER_CASE_NAMING 样式,“previous”实际上是一个全局变量。所以 pylint 正在做它应该做的事情。您始终可以使用 #pylint disable=xxx 来抑制单行中的 xxx 错误。
-
@PaulCornelius 尝试使用 2.5.3(最新版本)并且基本相同。关于大写,错误消息指的是“常量”。它不是一个常数。
-
潜在相关:pylint issue #3328,以及issues labeled
topic-control-flow。我认为类型提示会有所帮助,但似乎并非如此。