2017-10-05 60 views
4

的不堪不透明爲什麼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

回答

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