This is in reference to Python 3.2. Pertinent grammar rules are as follows (http://docs.python.org/py3k/reference/grammar.html):
power: atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_comp] ')' |
'[' [testlist_comp] ']' |
'{' [dictorsetmaker] '}' |
NAME | NUMBER | STRING+ | '...' | 'None' | 'True' | 'False')
trailer: '(' [arglist] ')' | '[' subscriptlist ']' | '.' NAME
According to this a basic function call could look like:
atom '(' ')'
But I believe we can’t just put any atom in there. For example, even though 1 is an atom (NUMBER), 1 is not a function and therefore you cannot call it with something like 1(). My question is: given an instance of the power grammar rule, could its atom be substituted with any rule of atom‘s other than NAME in a parse tree of a Python program and still run?
EDIT (ANSWER):
Anything that is “callable” may be called with the () operator. (http://docs.python.org/py3k/reference/expressions.html#calls):
call ::= primary "(" [argument_list [","] | comprehension] ")"
The
primarymust evaluate to a callable object (user-defined functions, built-in functions, methods of built-in objects, class objects, methods of class instances, and all objects having a__call__()method are callable).
This means you can do stuff like:
>>> eval.__call__.__call__("print(\"x\")")
x
Or even crazier (useless) stuff:
>>> a = lambda x : [abs, lambda y : y][0 if x < 0 else 1](x)
>>> a(1)
1
>>> a(-1)
1
>>> a(0)
0
Notice that the error here is a
TypeErrorand not aSyntaxError. It is perfectly legal syntax to try to call a number; numbers just don’t have any actual call functionality.