time.struct_time难以忍受的不透明

时间:2017-10-05 21:05:17

标签: python-3.x visual-studio-code pycharm pylint

为什么IDE的pylint和intellisense功能无法识别time.struct_time的实例?以下代码包含对类的现有/不存在属性的一些简单测试,名为元组和类似于元组的time.struct_time。一切都按照预期在pylint,IntelliJ和VSCode中运行 - 除了time.struct_time之外,每种情况都会报告对缺失属性的访问 - 它不会在任何这些工具中生成任何警告或错误。为什么他们不能分辨它是什么以及它的属性是什么?

import time
from collections import namedtuple

t = time.localtime()
e = t.tm_mday
e = t.bad # this is not reported by linters or IDEs. 

class Clz:
    cvar = 'whee'

    def __init__(self):
        self.ivar = 'whaa'

o = Clz()
e = Clz.cvar
e = o.ivar
e = Clz.bad
e = o.bad

Ntup = namedtuple('Ntup', 'thing')
n = Ntup(thing=3)
e = n.thing
e = n.bad

问题的背景是pipenv -

中最近的错误
# Halloween easter-egg.          
if ((now.tm_mon == 10) and (now.tm_day == 30)) 

显然,传递路径从未经过测试,但似乎典型的静态分析工具在这里也没有帮助。对于标准库中的类型,这是奇怪的。

(可以在https://github.com/kennethreitz/pipenv/commit/033b969d094ba2d80f8ae217c8c604bc40160b03完整地看到修复)

1 个答案:

答案 0 :(得分:3)

time.struct_time是在C中定义的对象,这意味着它无法静态地进行内省。自动完成软件可以解析Python代码并合理猜测哪些类和命名元组支持,但是它们不能为C定义的对象执行此操作。

大多数系统使用的解决方法是生成存根文件;通常通过在运行时内省对象(导入模块并记录找到的属性)。例如,CodeIntel(Komodo IDE的一部分)使用XML file format called CIX。但是,这更容易出错,因此这样的系统会小心谨慎,并且不会明确地将未知属性标记为错误。

如果您使用Python 3进行编码,则可以考虑使用type hinting。对于C扩展,您仍然需要存根文件,但社区现在非常擅长维护它们。标准库存根文件保存在project called typeshed

您必须在项目中添加类型提示:

#!/usr/bin/env python3
import time
from collections import namedtuple


t: time.struct_time = time.localtime()
e: int = t.tm_mday
e = t.bad  # this is not reported by linters or IDEs.


class Clz:
    cvar: str = 'whee'
    ivar: str

    def __init__(self) -> None:
        self.ivar = 'whaa'


o = Clz()
s = Clz.cvar
s = o.ivar
s = Clz.bad
s = o.bad

Ntup = namedtuple('Ntup', 'thing')
n = Ntup(thing=3)
e = n.thing
e = n.bad

但是flake8 tool结合flake8-mypy plugin会检测到不良属性:

$ flake8 test.py
test.py:8:5: T484 "struct_time" has no attribute "bad"
test.py:22:5: T484 "Clz" has no attribute "bad"
test.py:23:5: T484 "Clz" has no attribute "bad"
test.py:28:5: T484 "Ntup" has no attribute "bad"

PyCharm也是基于这项工作,也许可以检测到相同的无效使用。当然directly supports pyi files