astroid icon indicating copy to clipboard operation
astroid copied to clipboard

Code for supporting `with_metaclass` seems broken

Open tushar-deepsource opened this issue 3 years ago • 6 comments

So this code works as expected:

node = astroid.extract_node('''
def foo():
    return 42
''')
print(list(node.infer_call_result(caller=node)))
$ python a.py
[<Const.int l.3 at 0x105704070>]

But this breaks:

node = astroid.extract_node('''
def with_metaclass(meta, *bases):
    return 42
''')
print(list(node.infer_call_result(caller=node)))
$ python a.py
Traceback (most recent call last):
  File "/Users/tusharsadhwani/a.py", line 14, in <module>
    print(list(node.infer_call_result(node)))
  File "/Users/tusharsadhwani/venv/lib/python3.10/site-packages/astroid/nodes/scoped_nodes/scoped_nodes.py", line 1738, in infer_call_result
    metaclass = next(caller.args[0].infer(context), None)
TypeError: 'Arguments' object is not subscriptable

astroid seems to have special handling for functions called with_metaclass, which seems to be broken.

Am I using the method wrongly? I tried using it just as I saw it being used in the project itself.

tushar-deepsource avatar Aug 08 '22 09:08 tushar-deepsource

This seems relevant:

https://github.com/PyCQA/astroid/blob/1a698acd4ca746851e6a525bf7e012ac6e6eb877/astroid/nodes/scoped_nodes/scoped_nodes.py#L1702-L1712

I am not familiar with that code, but it seems like this is indeed very error-prone.

DanielNoord avatar Aug 08 '22 11:08 DanielNoord

@DanielNoord

https://github.com/PyCQA/astroid/blob/1a698acd4ca746851e6a525bf7e012ac6e6eb877/astroid/nodes/scoped_nodes/scoped_nodes.py#L1713

I think this line is the exact problem. Did FunctionDef.args ever return a list of nodes before? It seems to return an Arguments type now.

tushar-deepsource avatar Aug 09 '22 10:08 tushar-deepsource

Not as far as I know. However, is caller always a FunctionDef? Might that be where this is going wrong?

DanielNoord avatar Aug 09 '22 19:08 DanielNoord

@DanielNoord do you know of any node type which has an args field of type list?

tusharsadhwani avatar Aug 10 '22 05:08 tusharsadhwani

CallContext has list[NodeNG] and Arguments has list[AssignName].

DanielNoord avatar Aug 10 '22 07:08 DanielNoord

It looks like this is happening whether or not six is involved, but yes, since #1622 we no longer inject a Call as a fake base. That fake Call would have had .args.

jacobtylerwalls avatar Aug 20 '22 23:08 jacobtylerwalls