Dlaczego pylint zwraca `unsubscriptable-object` dla numpy.ndarray.shape?

9

Właśnie stworzyłem następujący przypadek „minimalnego” repro (minimum w cudzysłowie, ponieważ chciałem mieć pewność, że pylintnie rzucę żadnych innych błędów, ostrzeżeń, podpowiedzi ani sugestii - co oznacza, że ​​jest trochę płyty kotłowej):

pylint_error.py :

"""
Docstring
"""

import numpy as np


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


if __name__ == "__main__":
    main()

Po uruchomieniu pylinttego kodu ( pylint pylint_error.py) otrzymuję następujące dane wyjściowe:

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

Twierdzi, że test.shapenie można go subskrybować, nawet jeśli jest to całkiem jasne. Po uruchomieniu kodu działa dobrze:

$> python pylint_error.py
1

Co powoduje pylintdezorientację i jak mogę to naprawić?

Kilka dodatkowych uwag:

  • Jeśli zadeklaruję test, ponieważ np.arange(1)błąd zniknie
  • Jeśli oświadczam testu jako np.zeros(1), np.zeros((1)), np.ones(1), czy np.ones((1))błąd ma nie odejdzie
  • Jeśli zadeklaruję test, ponieważ np.full((1), 1)błąd zniknie
  • Podanie type ( test: np.ndarray = np.array([1])) nie naprawia błędu
  • Określanie dtype(np.array([1], dtype=np.uint8) ) nie naprawia błędu
  • Wykonanie testu ( test[:].shape) powoduje, że błąd zniknie

Mój pierwszy instynkt mówi, że niespójne zachowanie z różnymi NumPYmetodami ( arangevs zerosvs fullitp.) Sugeruje, że to tylko błąd NumPY. Jednak możliwe jest, że istnieje pewne podstawowe pojęcie, NumPYże nie rozumiem. Chciałbym mieć pewność, że nie piszę kodu o nieokreślonym zachowaniu, które działa tylko na wypadek.

stevendesu
źródło
1
Ja winię pylintprzednumpy
hpaulj

Odpowiedzi:

5

Nie mam wystarczającej reputacji, by móc komentować, ale wygląda na to, że jest to otwarty problem: https://github.com/PyCQA/pylint/issues/3139

Dopóki problem nie zostanie rozwiązany na ich końcu, po prostu zmienię linię na

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

do mojego pylintrcpliku.

ignorowanie grawitacji
źródło
1
Dziękujemy za połączenie problemu. Niestety narzeka pylint również na zbyt długie linie, więc myślę, że mogę się trzymać print(test[:].shape[0])twojego rozwiązania, ponieważ sprawia, że ​​moje linie są krótsze i ratują mnie od pylint
ciągłego
2
UWAGA: Najnowsze wersje pylinta ostrzegają przed wyłączeniem przez ID, więc polecam coś takiego w poprzedniej linii:# pylint: disable=unsubscriptable-object # pylint/issues/3139
Bryce Schober
2

Od listopada 2019 r .:

Jak wspomniał jeden z użytkowników w dyskusji na GitHubie, możesz rozwiązać problem, obniżając zarówno pylint, jak i astroid , np.requirements.txt

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

lub

pip install astroid==2.2.5 & pip install pylint==2.3.1
Tomasz Bartkowiak
źródło