Perché pylint restituisce `unsubscriptable-object` per numpy.ndarray.shape?


9

Ho appena messo insieme il seguente caso di repro "minimo" (minimo tra virgolette perché volevo assicurarmi di pylintnon aver lanciato altri errori, avvertenze, suggerimenti o suggerimenti - il che significa che c'è un po 'di boilerplate):

pylint_error.py :

"""
Docstring
"""

import numpy as np


def main():
    """
    Main entrypoint
    """
    test = np.array([1])
    print(test.shape[0])


if __name__ == "__main__":
    main()

Quando eseguo pylintquesto codice ( pylint pylint_error.py) ottengo il seguente output:

$> pylint pylint_error.py
************* Module pylint_error
pylint_error.py:13:10: E1136: Value 'test.shape' is unsubscriptable (unsubscriptable-object)

------------------------------------------------------------------
Your code has been rated at 1.67/10 (previous run: 1.67/10, +0.00)

Afferma che test.shapenon è sottoscrivibile, anche se lo è chiaramente. Quando eseguo il codice funziona perfettamente:

$> python pylint_error.py
1

Quindi cosa sta causando pylintconfusione e come posso risolverlo?

Alcune note aggiuntive:

  • Se dichiaro il test poiché np.arange(1)l'errore scompare
  • Se io dichiaro di prova come np.zeros(1), np.zeros((1)), np.ones(1), o np.ones((1))l'errore non non va via
  • Se dichiaro il test poiché np.full((1), 1)l'errore scompare
  • Specificando il tipo ( test: np.ndarray = np.array([1])) non si corregge l'errore
  • Specificando a dtype( np.array([1], dtype=np.uint8)) non si corregge l'errore
  • Prendendo una fetta di test ( test[:].shape), l'errore scompare

Il mio primo istinto afferma che il comportamento incoerente con vari NumPYmetodi ( arangevs zerosvs full, ecc.) Suggerisce che si tratti solo di un bug NumPY. Tuttavia è possibile che ci sia un concetto alla base del fatto NumPYche sono frainteso. Mi piacerebbe essere sicuro di non scrivere codice con un comportamento indefinito che funziona solo in caso di incidente.


1
pylintPrima numpy
darei la

Risposte:


5

Non ho abbastanza reputazione per commentare, ma sembra che questo sia un problema aperto: https://github.com/PyCQA/pylint/issues/3139

Fino a quando il problema non verrà risolto, cambierei semplicemente la linea

    print(test.shape[0])  # pylint: disable=E1136  # pylint/issues/3139

al mio pylintrcfile.


1
Grazie per aver collegato il problema. Purtroppo pylint anche lamenta linee di essere troppo lungo, quindi credo di poter attaccare con print(test[:].shape[0])sopra la soluzione dal momento che rende le mie linee più corte e mi salva dalla pylints incessanti fastidioso
stevendesu

2
NOTA: le versioni recenti di pylint avvisano della disabilitazione tramite ID, quindi consiglio qualcosa di più simile a questo nella riga precedente:# pylint: disable=unsubscriptable-object # pylint/issues/3139
Bryce Schober

2

A partire da novembre 2019:

Come menzionato da uno degli utenti nella discussione su GitHub, è possibile risolvere il problema declassando sia il pilastro che l' astroid , ad esempio inrequirements.txt

astroid>=2.0, <2.3
pylint>=2.3, <2.4

o

pip install astroid==2.2.5 & pip install pylint==2.3.1
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.