Pylint: False positive: "Does not support item assignment" error with np.zeros_like

Created on 14 Feb 2019  路  10Comments  路  Source: PyCQA/pylint

Hi there!
Pylint gives a false-positive error while using numpy.zeros_like().
This numpy method will return a ndarray object. But while trying to address this object by indexing, pylint will raise an error although python works fine.

Code to reproduce:.

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
b = np.zeros_like(a)
print(b)

index = (0, 1)

a[index] = 9
print(a)

b[index] = 9
print(b)

Current behavior

Pylint gives

'b' does not support item assignment

in line 13. But Python runs the program without any problem.

Same issue with np.full_like(), np.empty_like(), np.ones_like().

Expected behavior

No pylint error.
Workaround: In line 5, change to b = np.array(np.zeros_like(a)).

pylint --version output

pylint 2.2.2
astroid 2.1.0
Python 3.7.1

astroid brain bug

Most helpful comment

@Max16hr the bug arises because of a lack of some dunder methods (such as __getitem__, __setitem__ ...) in the ndarray class in astroid numpy brain and because of a wrong inference of zeros_like, full_like etc methods.
I'have got a fix but it still needs more work to test correctly all the ndarray methods and all the functions that return a ndarray.
I'm working on it.

All 10 comments

Thanks for the report!

@Max16hr the bug arises because of a lack of some dunder methods (such as __getitem__, __setitem__ ...) in the ndarray class in astroid numpy brain and because of a wrong inference of zeros_like, full_like etc methods.
I'have got a fix but it still needs more work to test correctly all the ndarray methods and all the functions that return a ndarray.
I'm working on it.

This bug has not been fixed, I can reproduce the same behavior.

@VasLem thanks for your remark.
Can you please send a precise example of your code please?

Here is an example

arr1 = np.array([1,2,3])
arr2 = np.ones_like(arr1, dtype=np.uint8)
arr2[arr1 >= 2] = 255

print(arr2)
# [  1 255 255]

Line 3 : 'arr2' does not support item assignmentpylint(unsupported-assignment-operation)
Pylint : 2.3.1

There are still bugs with pylint. Here is my example:

import numpy as np 

def check_grad(fn, gr, X):
    X_flat    = X.reshape(-1)           # convert X to 1d array -> l for loop needed
    shape_X   = X.shape                 # original shape of X
    num_grad  = np.zeros_like(X)        # numerical grad, shape = shape of X
    grad_flat = np.zeros_like(X_flat)   # 1d version of grad
    eps       = 1e-6                    # a small number, 1e-10 --> 1e-6 is usually good
    numElems  = X_flat.shape[0]         # number of elements in X
    # calculate numerical gradient
    for i in range(numElems):           # iterate over all elements of X
        Xp_flat      = X_flat.copy() 
        Xn_flat      = X_flat.copy() 
        Xp_flat[i]  += eps
        Xn_flat[i]  -= eps
        Xp           = Xp_flat.reshape(shape_X)
        Xn           = Xn_flat.reshape(shape_X)
        grad_flat[i] = (fn(Xp) - fn(Xn))/(2*eps)
    num_grad = grad_flat.reshape(shape_X)
    diff = np.linalg.norm(num_grad - gr(X))
    print('Difference between 2 methods should be small: ', diff)

m, n = 10, 20
A = np.random.rand(m, n)
X = np.random.rand(n, m)

def fn1(X):
    return np.trace(A.dot(X))

def gr1(X):
    return A.T 

check_grad(fn1, gr1, X)

In line 18: 'grad_flat' does not support item assignment
In line 20: Instances of 'tuple' has no 'reshape' member
However, everything turns out to be just fine with Python interpreter
Pylint: 2.3.1

@olivbau
I can confirm that using pylint (2.3.1) and astroid (2.2.5) the message does not support item assignment聽is emitted.
However when using the master branch of astroid it is no more emitted.
I assume that you won't be facing this message anymore as soon as a new release of astroid will be published.

@DungMinhDao
It appears that with the astroid's master branch those messages are not yet emitted.
So i assume you won't be facing this problem anymore as soon as a new astroid聽version will be published.

Is there any workaround? I could get rid of similar errors by adding numpy.ndarray to the --ignored-classes. Pylint seems to think the return of zeros_like() is a tuple though..

@RichardHuenermann you are right. With the current version of astroid the zeros_like function return is inferred as a tuple. It is no more the case with the master branch of astroid thanks to PyCQA/astroid#664. With the next version of astroid聽your problem should disappear.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ethanchewy picture ethanchewy  路  3Comments

GergelyKalmar picture GergelyKalmar  路  3Comments

lancelote picture lancelote  路  3Comments

jrial picture jrial  路  3Comments

elirnm picture elirnm  路  3Comments