Open eugene57 opened 2 years ago
I don't think this is a bug. node.value
is actually referring to the Subscript
node which is 42
and thus an int
. See:
❯ cat test.py
import astroid
code = """
class Test:
def __getitem__(self, key):
if key == 1:
return 42
else:
return None
x = Test()
result = x[42] #@
"""
node = astroid.extract_node(code)
x = node.value.inferred()
print(type(node.value))
print(type(x[0]))
print(x[0].value)
❯ python3 test.py
<class 'astroid.nodes.node_classes.Subscript'>
<class 'astroid.nodes.node_classes.Const'>
42
No-no.
Actually, node.value
is x[42]
as you can see below:
print(node.value.repr_tree())
Subscript(
ctx=<Context.Load: 1>,
value=Name(name='x'),
slice=Index(value=Const(value=42)))
Inference of x[42]
checks call result of Test.__getitem__
but uses only first inferred value, not all the possible ones. See https://github.com/PyCQA/astroid/blob/main/astroid/nodes/scoped_nodes/scoped_nodes.py#L2926.
Maybe example would be a bit simpler if we use result = x["abc"]
instead of result = x[42]
. This way:
import astroid
code = """
class Test:
def __getitem__(self, key):
if key == 1:
return 42
else:
return None
x = Test()
result = x["abc"] #@
"""
node = astroid.extract_node(code)
x = node.value.inferred()
print(x)
It still prints [<Const.int l.5 at 0x7fd3ae65fad0>]
--- first inference result of Test.__getitem__
call.
Ah my bad, I misinterpreted the result.
This will be difficult to fix though, as we can't simply change getitem
to return a list or tuple instead of a single node..
Not sure what the best way to approach this is.
This will be difficult to fix though, as we can't simply change getitem to return a list or tuple instead of a single node..
I think that's exactly what we need to do.
Steps to reproduce
Current behavior
Only
int
is inferred:Expected behavior
I expect to see both
int
andNone
as possible values.python -c "from astroid import __pkginfo__; print(__pkginfo__.version)"
output2.7.3