Skip to content

Cannot infer assignment with operator for a simple list of strings #1398

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

Closed
tristanlatr opened this issue Feb 16, 2022 · 8 comments · Fixed by #1399
Closed

Cannot infer assignment with operator for a simple list of strings #1398

tristanlatr opened this issue Feb 16, 2022 · 8 comments · Fixed by #1399
Labels
Enhancement ✨ Improvement to a component

Comments

@tristanlatr
Copy link
Contributor

tristanlatr commented Feb 16, 2022

Steps to reproduce

def test_imported_module_var_inferable():
    mod1 = parse(("from top.mod import v as z\n"
                 "w = [1] + z"),
                 module_name='top')
    mod2 = parse("v = [2]", module_name='top.mod')
    w_val = mod1.body[-1].value
    i_w_val = next(w_val.infer())
    assert i_w_val != util.Uninferable
    assert i_w_val.as_string() == "[1, 2]" # Works

def test_imported_module_var_inferable2():
    mod1 = parse(("from top.mod import v as z\n"
                 "w = ['1'] + z"),
                 module_name='top')
    mod2 = parse("v = ['2']", module_name='top.mod')
    w_val = mod1.body[-1].value
    i_w_val = next(w_val.infer())
    assert i_w_val != util.Uninferable
    assert i_w_val.as_string() == "['1', '2']" # Fails with result ['1', 2] instead

def test_imported_module_var_inferable3():
    mod1 = parse(("from top.mod import __dunder_var__ as v\n"
                 "__dunder_var__ = ['w'] + v"),
                 module_name='top')
    mod2 = parse("__dunder_var__ = ['v']", module_name='top.mod')
    w_val = mod1.body[-1].value
    i_w_val = next(w_val.infer())
    assert i_w_val != util.Uninferable # Retuns Uninferable
    assert i_w_val.as_string() == "['w', 'v']"

Current behavior

It seems that operators are fully supported for lists of ints but not for list of strings, I'm unsure why, it seems the same level of complexity. Also it's very weird that it gives the Uninferable result for dunder variables.

Expected behavior

All tests should pass IMO.

Astroid version 2.9.3

@Pierre-Sassoulas Pierre-Sassoulas added the Enhancement ✨ Improvement to a component label Feb 16, 2022
@tristanlatr
Copy link
Contributor Author

Sorry this might be false manipulation, I've added these tests to tests/unittest_inference.py and they failed, but running them manually in the python interactive interpreter, it works as expected. So I'm confused.

@Pierre-Sassoulas
Copy link
Member

If you open a PR adding those tests we'll be able to see if they pass for all interpreters or only some of them :)

@tristanlatr
Copy link
Contributor Author

Ok!

tristanlatr added a commit to tristanlatr/astroid that referenced this issue Feb 16, 2022
@tristanlatr
Copy link
Contributor Author

So yes it fails @Pierre-Sassoulas, do you have an idea where to look for the issue? Thanks

@tristanlatr
Copy link
Contributor Author

tristanlatr commented Feb 16, 2022

It's so weird because the follwing works:

>>> from astroid import parse
>>> mod1 = parse(("from top.mod import __dunder_var__ as v\n"
...                  "__dunder_var__ = ['w'] + v"),
...                  module_name='top')
>>> mod2 = parse("__dunder_var__ = ['v']", module_name='top.mod')
>>> list(mod1.body[-1].value.infer())[0].as_string()
"['w', 'v']"

But in the pytest env it doesn't :/

@Pierre-Sassoulas
Copy link
Member

Could it be because from top.mod is importable in your local environment ? (I don't know anything about this module so I might be off)

@tristanlatr
Copy link
Contributor Author

tristanlatr commented Feb 16, 2022

No, top.mod is only defined because I passed module_name=“top.mod” to the parse() function. And it should work right ?

@tristanlatr
Copy link
Contributor Author

Ok, sorry that was indeed a false manipulation, the fake module top.mod was already in the AstroidManager cache such that it created some side effects on the inference even if we have parsed another module with the same name after.

Adding AstroidManager().clear_cache() before the tests seems to workaround the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement ✨ Improvement to a component
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants