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

Inference failure when function returns one of two constant values #2503

Closed
fizbin opened this issue Sep 19, 2018 · 2 comments
Closed

Inference failure when function returns one of two constant values #2503

fizbin opened this issue Sep 19, 2018 · 2 comments

Comments

@fizbin
Copy link

fizbin commented Sep 19, 2018

Steps to reproduce

  1. Run pylint on this code:
"""pylint test module"""

def return_an_int(param):
    """Returns an int"""
    if param == 0:
        return 1
    return 0

def test_one(param):
    """Should complain about var_one[0], but doesn't"""
    var_one = return_an_int(param)
    return var_one[0]

Current behavior

Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00)

Expected behavior

E: 12,11: Value 'var_one' is unsubscriptable (unsubscriptable-object)

pylint --version output

Originally found on:

No config file found, using default configuration
pylint 1.9.3, 
astroid 1.6.5
Python 2.7.12 (v2.7.12:d33e0cf91556, Jun 26 2016, 12:10:39) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]

Also see identical behavior on this code with:

pylint 2.1.1
astroid 2.0.4
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 26 2018, 23:26:24) 
[Clang 6.0 (clang-600.0.57)]
@fizbin
Copy link
Author

fizbin commented Sep 19, 2018

Note that astroid seems perfectly able to infer that var_one is either the int 1 or the int 0, so the failure is in pylint failing to see that both of those values are unsubscriptable:

In [1]: import astroid

In [2]: src = open("pylinttest_short.py").read()

In [3]: tree = astroid.parse(src)

In [4]: tree.body[1].body[1].value.value
Out[4]: <Name.var_one l.12 at 0x10e2259e8>

In [5]: list(tree.body[1].body[1].value.value.infer())
Out[5]: [<Const.int l.6 at 0x10e2257b8>, <Const.int l.7 at 0x10e2257f0>]

In [6]: list(x.value for x in tree.body[1].body[1].value.value.infer())
Out[6]: [1, 0]

Not too surprisingly given that, the test case can be shortened to:

"""pylint test module"""

def test_one(param):
    """Should complain about var_one[0], but doesn't"""
    var_one = 0
    if param == 0:
        var_one = 1
    return var_one[0]

@PCManticore
Copy link
Contributor

Thanks for reporting a bug! This is currently caused by our use of safe_infer, which returns None on multiple inferred object. I think we should allow safe_infer to return the inferred value when multiple values are sharing the same types, as in this case we can only infer integers from that function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants