Почему pylint возвращает `unsubscriptable-object` для numpy.ndarray.shape?

9

Я просто собрал следующий «минимальный» случай воспроизведения (минимум в кавычках, потому что я хотел, чтобы pylintне было никаких других ошибок, предупреждений, подсказок или предложений - это значит, что есть небольшой пример):

pylint_error.py :

"""
Docstring
"""

import numpy as np


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


if __name__ == "__main__":
    main()

Когда я запускаю pylintэтот код ( pylint pylint_error.py), я получаю следующий вывод:

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

Он утверждает, что test.shapeэто не подлежит подписке, хотя это вполне очевидно. Когда я запускаю код, он работает просто отлично:

$> python pylint_error.py
1

Так что вызывает pylintзамешательство, и как я могу это исправить?

Некоторые дополнительные заметки:

  • Если я объявляю тест, как np.arange(1)ошибка исчезает
  • Если я объявляю испытание , как np.zeros(1), np.zeros((1)), np.ones(1)или np.ones((1))ошибка никак не уходит
  • Если я объявляю тест, как np.full((1), 1)ошибка исчезает
  • Указание типа ( test: np.ndarray = np.array([1])) не исправляет ошибку
  • Указание dtype( np.array([1], dtype=np.uint8)) не исправляет ошибку
  • Взятие части test ( test[:].shape) устраняет ошибку

Мой первый инстинкт говорит, что несовместимое поведение с различными NumPYметодами ( arangeпротив zerosи fullт. Д.) Предполагает, что это просто ошибка NumPY. Однако, возможно, есть какая-то основная концепция NumPY, которую я неправильно понимаю. Я хотел бы убедиться, что я не пишу код с неопределенным поведением, который работает только случайно.

stevendesu
источник
1
Я бы обвинял pylintраньшеnumpy
hpaulj

Ответы:

5

У меня недостаточно репутации, чтобы комментировать, но, похоже, это открытый вопрос: https://github.com/PyCQA/pylint/issues/3139

Пока проблема не будет решена с их стороны, я просто изменил бы строку на

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

в мой pylintrcфайл.

ignoring_gravity
источник
1
Спасибо за ссылку на проблему. К сожалению, pylint также жалуется на то, что строки слишком длинные, поэтому я думаю, что могу придерживаться print(test[:].shape[0])вашего решения, так как оно делает мои строки короче и спасает меня от pylintнепрестанного
нытья
2
ПРИМЕЧАНИЕ. Последние версии pylint предупреждают об отключении по идентификатору, поэтому я рекомендую что-то похожее на предыдущую строку:# pylint: disable=unsubscriptable-object # pylint/issues/3139
Брайс Шобер,
2

По состоянию на ноябрь 2019 года:

Как отметил один из пользователей в обсуждении GitHub вы могли бы решить эту проблему, понижая как pylint и астроиду , например , вrequirements.txt

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

или

pip install astroid==2.2.5 & pip install pylint==2.3.1
Томаш Бартковяк
источник