Search code examples
pythonnumpypylint

Why pylint returns `unsubscriptable-object` for numpy.ndarray.shape?


I just put together the following "minimum" repro case (minimum in quotes because I wanted to ensure pylint threw no other errors, warnings, hints, or suggestions - meaning there's a bit of 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()

When I run pylint on this code (pylint pylint_error.py) I get the following 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)

It claims that test.shape is not subscriptable, even though it quite clearly is. When I run the code it works just fine:

$> python pylint_error.py
1

So what's causing pylint to become confused, and how can I fix it?

Some additional notes:

  • If I declare test as np.arange(1) the error goes away
  • If I declare test as np.zeros(1), np.zeros((1)), np.ones(1), or np.ones((1)) the error does not go away
  • If I declare test as np.full((1), 1) the error goes away
  • Specifying the type (test: np.ndarray = np.array([1])) does not fix the error
  • Specifying a dtype (np.array([1], dtype=np.uint8)) does not fix the error
  • Taking a slice of test (test[:].shape) makes the error go away

My first instinct says that the inconsistent behavior with various NumPY methods (arange vs zeros vs full, etc) suggests it's just a bug in NumPY. However it's possible there's some underlying concept to NumPY that I'm misunderstanding. I'd like to be sure I'm not writing code with undefined behavior that's only working on accident.


Solution

  • I don't have enough reputation to comment, but it looks like this is an open issue: https://github.com/PyCQA/pylint/issues/3139

    Until the issue is resolved on their end, I would just change the line to

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

    to my pylintrc file.