pandas-dev/pandas · error · ValueError
keyword error in function call
Error message
keyword error in function call '{node.func.id}' What it means
Raised in the non-FuncNode branch of visit_Call when iterating node.keywords and encountering an element that is not an ast.keyword node. Under normal Python AST grammar every element of Call.keywords is an ast.keyword, so this ValueError is a defensive guard against malformed/constructed AST or an unexpected AST shape produced by the tokenizer/backtick-quoted-string rewriting. It surfaces as a generic 'keyword error in function call' message.
Solutions
- Avoid keyword arguments to user functions inside eval/query; pass them positionally.
- If you need keyword semantics, call the function in plain Python and pass the result via a @-local variable: r = f(a=1, b=2); df.query('@r > 0').
- Simplify the expression: remove backtick-quoted names from keyword positions and use plain identifiers.
- If the AST is hand-built, ensure every entry in Call.keywords is an instance of ast.keyword.
Example fix
// before
df.query("@my_fn(`weird name`=1)")
// after
val = my_fn(**{"weird name": 1})
df.query("@val > 0") Defensive patterns
Strategy: validation
Validate before calling
import ast
def call_keywords_well_formed(expr: str) -> bool:
tree = ast.parse(expr, mode='eval')
for node in ast.walk(tree):
if isinstance(node, ast.Call):
if any(not isinstance(k, ast.keyword) for k in node.keywords):
return False
return True
assert call_keywords_well_formed(query_str) Type guard
import ast
def keywords_valid(call: ast.Call) -> bool:
return all(isinstance(k, ast.keyword) for k in call.keywords) Try / catch
try:
df.query(query_str)
except ValueError as e:
if 'keyword error in function call' in str(e):
# rebuild without keywords, pass args positionally via @-local
result = fn(*positional_values)
df.query('@result > 0')
else:
raise Prevention
- Avoid backtick-quoted names in keyword positions inside eval/query.
- Prefer calling user functions in plain Python and passing results via @-locals.
- Validate the AST shape of generated query strings in tests.
When it happens
Trigger: Calling a scope-resolved (non-math) function inside eval/query with keyword arguments where one keyword element is not a proper ast.keyword — e.g. df.query('@f(a=1, b=2)') where the AST has been rewritten by backtick/column-name preprocessing into something non-standard. Practically rare; usually indicates a parser edge case or a hand-built expression tree.
Common situations: Backtick-quoted column names used as keyword argument names inside a call to a user function. Mixed positional/keyword calls to user-defined callables in @-local scope. Version regressions in the tokenizer that misclassify keyword tokens.
Related errors
- Function " " does not support keyword arguments
- ' ' nodes are not implemented
- cannot evaluate scalar only bool ops
- Invalid binary operator
- Invalid function call
AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11).
Data as JSON: /api/errors/1455bf6e5c763777.
Report an issue: GitHub.
Appendix: source
Thrown at pandas/core/computation/expr.py:708
if isinstance(res, FuncNode):
new_args = [self.visit(arg) for arg in node.args]
if node.keywords:
raise TypeError(
f'Function "{res.name}" does not support keyword arguments'
)
return res(*new_args)
else:
new_args = [self.visit(arg)(self.env) for arg in node.args]
for key in node.keywords:
if not isinstance(key, ast.keyword):
# error: Item "Attribute" of "Attribute | Name" has no
# attribute "id"
raise ValueError(
f"keyword error in function call '{node.func.id}'" # type: ignore[union-attr]
)
if key.arg:
kwargs[key.arg] = self.visit(key.value)(self.env)
name = self.env.add_tmp(res(*new_args, **kwargs))
return self.term_type(name=name, env=self.env)
def translate_In(self, op):
return op
def visit_Compare(self, node, **kwargs):
ops = node.ops
comps = node.comparators
# base case: we have something like a CMP b
if len(comps) == 1:View on GitHub (pinned to 3b7651241d)