time.struct_time结构

问题描述:

的不堪不透明为什么IDE中的pylint的和智能感知功能具有难以识别的time.struct_time实例?下面的代码包含了对类的现有/不存在属性的一些简单测试,名为元组和名称元组,如time.struct_time。一切正常的pylint的,和的IntelliJ VSCode - 在每种情况下,除了time.struct_time报告给缺少的属性的访问 - 它产生任何这些工具没有警告或错误。他们为什么不能说出它是什么以及它的属性是什么?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可以看出)

+0

可能是因为'time.struct_time'是C,所以他们不能检查其有效属性源。 – user2357112

+0

当然,它可能与它有关,但我认为它不够。这些工具不会被每个C实现类型所困惑。他们完全满意于列表等。 – pvg

+0

他们需要对'time.struct_time'不适用的列表进行特定的处理。 – user2357112

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 toolflake8-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

+0

我认为这在pylint的情况下实际上是不准确的,因为(有些疏忽)由其中一位评论者提出。 Pylint没有得到这些不是因为结构的C'ness,而是因为它没有(并且不容易)知道很多关于返回类型的信息。它在'len','split'等的返回时失败。它确实知道来自内建对象的对象是什么样的,但它不知道什么(它没有解析自己)会给你一个。由IntelliJ使用的类型化声明,但它不符合'struct_time'的要求,但它是进一步挖掘的好帮手。 – pvg

+0

@pvg:'pylint'没有存根文件。 –

+0

我明白了,但是pylint会得到这个错误,无论返回是否是C结构。它不足以被C中定义​​的东西难倒。当然,它可以在运行时反省内建的,我认为它是(或者至少是前置的)。但是,这并不能解决问题。另一方面,我确实有机会快速浏览一下密码,并且包含这些特定调用和结构的准确存根,因此这是一个高可靠性的查询方向。 – pvg