Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
Max16hr opened this issue Feb 14, 2019 · 10 comments · Fixed by pylint-dev/astroid#664
Closed
Assignees
Labels
Bug 🪲 Needs astroid Brain 🧠 Needs a brain tip in astroid (then an astroid upgrade)

Comments

@Max16hr
Copy link

Max16hr commented Feb 14, 2019

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

@Max16hr Max16hr changed the title False negative: "Does not support item assignment" error with np.zeros_like False positive: "Does not support item assignment" error with np.zeros_like Feb 14, 2019
@hippo91 hippo91 self-assigned this Feb 16, 2019
@PCManticore PCManticore added Bug 🪲 Needs astroid Brain 🧠 Needs a brain tip in astroid (then an astroid upgrade) labels Feb 17, 2019
@PCManticore
Copy link
Contributor

Thanks for the report!

@hippo91
Copy link
Contributor

hippo91 commented Mar 30, 2019

@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.

@VasLem
Copy link

VasLem commented Jul 2, 2019

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

@hippo91
Copy link
Contributor

hippo91 commented Jul 6, 2019

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

@olivbau
Copy link

olivbau commented Jul 16, 2019

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

@DungMinhDao
Copy link

DungMinhDao commented Jul 26, 2019

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

zmoon added a commit to zmoon/pyspctral2 that referenced this issue Jul 30, 2019
Currently a bug with assigning to arrays created with `*_like(arr)`
  ref: pylint-dev/pylint#2747
@hippo91
Copy link
Contributor

hippo91 commented Aug 11, 2019

@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.

@hippo91
Copy link
Contributor

hippo91 commented Aug 11, 2019

@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.

@RichardPflaum
Copy link

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..

@hippo91
Copy link
Contributor

hippo91 commented Sep 6, 2019

@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 pylint-dev/astroid#664. With the next version of astroid your problem should disappear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug 🪲 Needs astroid Brain 🧠 Needs a brain tip in astroid (then an astroid upgrade)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants