Code for supporting `with_metaclass` seems broken
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.
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
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.
Not as far as I know. However, is caller always a FunctionDef? Might that be where this is going wrong?
@DanielNoord do you know of any node type which has an args field of type list?
CallContext has list[NodeNG] and Arguments has list[AssignName].
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.