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.
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)
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().
No pylint error.
Workaround: In line 5, change to b = np.array(np.zeros_like(a)).
pylint 2.2.2
astroid 2.1.0
Python 3.7.1
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.
Most helpful comment
@Max16hr the bug arises because of a lack of some dunder methods (such as
__getitem__,__setitem__...) in thendarrayclass in astroid numpy brain and because of a wrong inference ofzeros_like,full_likeetc methods.I'have got a fix but it still needs more work to test correctly all the
ndarraymethods and all the functions that return andarray.I'm working on it.