Por que o pylint retorna `unsubscriptable-object` para numpy.ndarray.shape?

9

Acabei de montar o seguinte caso "mínimo" de reprodução (mínimo entre aspas porque queria garantir pylint não lançasse outros erros, avisos, dicas ou sugestões - o que significa que há um pouco de clichê):

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 executo pylintesse código ( pylint pylint_error.py), recebo a seguinte saída:

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

Alega que test.shapenão é subscrito, mesmo que seja claramente. Quando executo o código, ele funciona bem:

$> python pylint_error.py
1

Então, o que está causando pylintconfusão, e como posso corrigi-lo?

Algumas notas adicionais:

  • Se eu declarar teste como np.arange(1)o erro desaparece
  • Se eu declarar teste como np.zeros(1), np.zeros((1)), np.ones(1), ou np.ones((1))o erro que não vão embora
  • Se eu declarar teste como np.full((1), 1)o erro desaparece
  • A especificação do tipo ( test: np.ndarray = np.array([1])) não corrige o erro
  • A especificação de um dtype( np.array([1], dtype=np.uint8)) não corrige o erro
  • Fazer uma fatia do teste ( test[:].shape) faz com que o erro desapareça

Meu primeiro instinto diz que o comportamento inconsistente com vários NumPYmétodos ( arangevs zerosvs full, etc) sugere que é apenas um bug NumPY. No entanto, é possível que exista algum conceito subjacente ao NumPYqual estou entendendo mal. Eu gostaria de ter certeza de que não estou escrevendo código com comportamento indefinido que está funcionando apenas por acidente.

stevendesu
fonte
11
Eu culparia pylintantesnumpy
hpaulj 31/10/19

Respostas:

5

Não tenho reputação suficiente para comentar, mas parece que este é um problema em aberto: https://github.com/PyCQA/pylint/issues/3139

Até que o problema seja resolvido, eu mudaria a linha para

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

para o meu pylintrcarquivo.

ignoring_gravity
fonte
11
Obrigado por vincular o problema. Infelizmente pylint também reclama de linhas de ser demasiado longo, então eu acho que pode ficar com print(test[:].shape[0])mais de sua solução, uma vez que faz com que minhas linhas mais curtas e me poupa de pylints incessante irritante
stevendesu
2
NOTA: As versões recentes do pylint avisam sobre a desativação por ID, por isso recomendo algo mais como este na linha anterior:# pylint: disable=unsubscriptable-object # pylint/issues/3139
Bryce Schober em
2

Em novembro de 2019:

Conforme mencionado por um dos usuários na discussão no GitHub, você pode resolver o problema desclassificando o pylint e o astroid , por exemplo, emrequirements.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
fonte