Pourquoi pylint renvoie `unsubscriptable-object` pour numpy.ndarray.shape?

9

Je viens de rassembler le cas de repro "minimum" suivant (minimum entre guillemets parce que je voulais m'assurer qu'il pylintn'y avait pas d'autres erreurs, avertissements, conseils ou suggestions - ce qui signifie qu'il y a un peu de passe-partout):

pylint_error.py :

"""
Docstring
"""

import numpy as np


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


if __name__ == "__main__":
    main()

Lorsque je lance pylintsur ce code ( pylint pylint_error.py), j'obtiens la sortie suivante:

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

Il prétend que ce test.shapen'est pas indicable, même s'il l'est très clairement. Lorsque j'exécute le code, cela fonctionne très bien:

$> python pylint_error.py
1

Alors, qu'est-ce qui cause la pylintconfusion et comment puis-je y remédier?

Quelques notes supplémentaires:

  • Si je déclare le test alors que np.arange(1)l'erreur disparaît
  • Si je déclare test np.zeros(1), np.zeros((1)), np.ones(1)ou np.ones((1))l'erreur ne pas disparaître
  • Si je déclare le test alors que np.full((1), 1)l'erreur disparaît
  • La spécification du type ( test: np.ndarray = np.array([1])) ne résout pas l'erreur
  • La spécification d'un dtype( np.array([1], dtype=np.uint8)) ne résout pas l'erreur
  • Prendre une tranche de test ( test[:].shape) fait disparaître l'erreur

Mon premier instinct dit que le comportement incohérent avec diverses NumPYméthodes ( arangevs zerosvs full, etc.) suggère que ce n'est qu'un bug NumPY. Cependant, il est possible qu'il y ait un concept sous-jacent à ce NumPYque je comprends mal. Je voudrais être sûr que je n'écris pas du code avec un comportement indéfini qui ne fonctionne que par accident.

stevendesu
la source
1
Je blâmerais pylintavantnumpy
hpaulj

Réponses:

5

Je n'ai pas assez de réputation pour commenter, mais il semble que ce soit un problème ouvert: https://github.com/PyCQA/pylint/issues/3139

Jusqu'à ce que le problème soit résolu de leur côté, je changerais simplement la ligne en

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

à mon pylintrcdossier.

ignorer_la gravité
la source
1
Merci d'avoir lié le problème. Malheureusement, il pylint se plaint également que les lignes sont trop longues, donc je pense que je peux m'en tenir à print(test[:].shape[0])votre solution car elle raccourcit mes lignes et pylint
m'évite
2
REMARQUE: Les versions récentes de pylint avertissent de la désactivation par ID, donc je recommande quelque chose de plus comme ceci sur la ligne précédente:# pylint: disable=unsubscriptable-object # pylint/issues/3139
Bryce Schober
2

En novembre 2019:

Comme l'a mentionné l' un des utilisateurs dans la discussion sur GitHub , vous pouvez résoudre le problème en rétrogradant à la fois pylint et astroïde , par exemple dansrequirements.txt

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

ou

pip install astroid==2.2.5 & pip install pylint==2.3.1
Tomasz Bartkowiak
la source