Pylint: Pylint gets TensorFlow's tf.split all wrong

Created on 12 May 2020  路  9Comments  路  Source: PyCQA/pylint

Steps to reproduce

import tensorflow as tf
tf.split([0, 0], num_or_size_splits=[1, 1], axis=-1)
print("Done.")

Current behavior

Code runs fine, but

bug.py:3:0: E1123: Unexpected keyword argument 'num_or_size_splits' in function call (unexpected-keyword-arg)
bug.py:3:0: E1124: Argument 'axis' passed by position and keyword in function call (redundant-keyword-arg)
bug.py:3:0: E1120: No value for argument 'value' in function call (no-value-for-parameter)
bug.py:3:0: E1120: No value for argument 'num_split' in function call (no-value-for-parameter)

Expected behavior

Perfect score

pylint --version output

tensorflow 2.2.0
pylint 2.5.2
astroid 2.4.1
Python 3.8.2 (default, Feb 26 2020, 09:52:54) 
[GCC 7.5.0]
false-positive regression

Most helpful comment

This does not happen with the pylint version installed with my package manager (2.2.2):

pylint3 2.2.2
astroid 2.1.0
Python 3.7.3 (default, Jul 25 2020, 13:03:44) 
[GCC 8.3.0]

And still happens in pylint 2.6.0 installed in a virtualenv:

pylint 2.6.0
astroid 2.4.2
Python 3.7.3 (default, Dec 20 2019, 18:57:59) 
[GCC 8.3.0]

In case it is useful to know, this also affects the functions tf.one_hot, tf.gather and tf.concat in tensorflow v2.2.0

All 9 comments

Maybe related:

import tensorflow as tf
print(tf.random.uniform(()))

yields

bug.py:3:6: E1120: No value for argument 'dtype' in function call (no-value-for-parameter)

although the code runs fine.

Maybe related:

import tensorflow as tf

x = tf.convert_to_tensor([1, 2, 3])
print(tf.cast(x, dtype=tf.float64))
y = tf.convert_to_tensor([1, 2, 3])
print(tf.concat([x,y], axis=-1))
print(-tf.math.log(x))

yields

bug.py:4:0: E1123: Unexpected keyword argument 'dtype' in function call (unexpected-keyword-arg)
bug.py:4:0: E1120: No value for argument 'DstT' in function call (no-value-for-parameter)
bug.py:6:6: E1123: Unexpected keyword argument 'axis' in function call (unexpected-keyword-arg)
bug.py:6:6: E1120: No value for argument 'values' in function call (no-value-for-parameter)
bug.py:7:6: E1130: bad operand type for unary -: object (invalid-unary-operand-type)

but outputs the following expected result:

tf.Tensor([1. 2. 3.], shape=(3,), dtype=float64)
tf.Tensor([1. 2. 3. 1. 2. 3.], shape=(6,), dtype=float32)
tf.Tensor([-0.        -0.6931472 -1.0986123], shape=(3,), dtype=float32)

Same issue.
I noticed tensorflow==2.2.0 causes this problem but tensorflow==2.1.0 dose not.

I also try to specify ignored-modules but it didn't work.

"""a"""
import tensorflow as tf


tf.concat([1, 2], axis=0)

with the following .pylintrc

[TYPECHECK]
ignored-modules=tensorflow

yields

************* Module main
main.py:5:0: E1123: Unexpected keyword argument 'axis' in function call (unexpected-keyword-arg)
main.py:5:0: E1120: No value for argument 'values' in function call (no-value-for-parameter)

My environment is as follows.

pylint 2.5.2
astroid 2.4.1
Python 3.8.0 (default, Oct 16 2019, 10:08:31)
[GCC 9.2.0]

Same for me with concat and other functions from tensorflow, since 2.2.0.

Env

pylint 2.5.2
astroid 2.4.1
Python 3.7.5 (default, Nov  7 2019, 10:50:52) 
[GCC 8.3.0]

Looks as though the combination of TF 2.2.0 and pylint 2.5 is picking up the internal gen_array_ops functions (e.g. def split(axis, value, num_split, name=None)) instead of the exported ones.

I don't know enough about TF's exporting, nor about pylint, to have any idea why that would be happening though...

Did some bisecting on the pylint side and came up with this: https://github.com/PyCQA/pylint/commit/01dfa522195d79217c43065d3d013e2ee31d47b7

I think what's happening is:

  • astroid is inferring multiple possible functions for the split (or similar) call, due to various wildcard imports in TF (e.g. https://github.com/tensorflow/tensorflow/blob/v2.2.0/tensorflow/python/ops/array_ops.py#L40)
  • all those functions have the same pytype (they're all just functions), so safe_infer is returning the first hit, which happens to be the one from gen_array_ops

Maybe safe_infer needs to be a little more circumspect when deciding whether a list of inferred values is ambiguous?

+@PCManticore, any ideas about what we can do here? (see comment above)

Also complaining about missing args to tf.sparse.reorder in v2.3.0

This does not happen with the pylint version installed with my package manager (2.2.2):

pylint3 2.2.2
astroid 2.1.0
Python 3.7.3 (default, Jul 25 2020, 13:03:44) 
[GCC 8.3.0]

And still happens in pylint 2.6.0 installed in a virtualenv:

pylint 2.6.0
astroid 2.4.2
Python 3.7.3 (default, Dec 20 2019, 18:57:59) 
[GCC 8.3.0]

In case it is useful to know, this also affects the functions tf.one_hot, tf.gather and tf.concat in tensorflow v2.2.0

Was this page helpful?
0 / 5 - 0 ratings