Skip to content

Commit e4f727b

Browse files
danielhriscajreback
authored andcommitted
BUG: fix calling local references with keyword arguments in query (#26426)
1 parent f44ac06 commit e4f727b

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

doc/source/whatsnew/v0.25.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ Bug Fixes
298298
~~~~~~~~~
299299

300300

301-
302301
Categorical
303302
^^^^^^^^^^^
304303

@@ -380,6 +379,7 @@ Indexing
380379
- Bug in which :meth:`DataFrame.append` produced an erroneous warning indicating that a ``KeyError`` will be thrown in the future when the data to be appended contains new columns (:issue:`22252`).
381380
- Bug in which :meth:`DataFrame.to_csv` caused a segfault for a reindexed data frame, when the indices were single-level :class:`MultiIndex` (:issue:`26303`).
382381
- Fixed bug where assigning a :class:`arrays.PandasArray` to a :class:`pandas.core.frame.DataFrame` would raise error (:issue:`26390`)
382+
- Allow keyword arguments for callable local reference used in the :method:`DataFrame.query` string (:issue:`26426`)
383383

384384

385385
Missing

pandas/core/computation/expr.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -633,9 +633,7 @@ def visit_Call(self, node, side=None, **kwargs):
633633
"'{func}'".format(func=node.func.id))
634634

635635
if key.arg:
636-
# TODO: bug?
637-
kwargs.append(ast.keyword(
638-
keyword.arg, self.visit(keyword.value))) # noqa
636+
kwargs[key.arg] = self.visit(key.value).value
639637

640638
return self.const_type(res(*new_args, **kwargs), self.env)
641639

pandas/tests/computation/test_eval.py

+34
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,40 @@ def test_multi_line_expression_local_variable(self):
13451345
assert_frame_equal(expected, df)
13461346
assert ans is None
13471347

1348+
def test_multi_line_expression_callable_local_variable(self):
1349+
# 26426
1350+
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
1351+
1352+
def local_func(a, b):
1353+
return b
1354+
1355+
expected = df.copy()
1356+
expected['c'] = expected['a'] * local_func(1, 7)
1357+
expected['d'] = expected['c'] + local_func(1, 7)
1358+
ans = df.eval("""
1359+
c = a * @local_func(1, 7)
1360+
d = c + @local_func(1, 7)
1361+
""", inplace=True)
1362+
assert_frame_equal(expected, df)
1363+
assert ans is None
1364+
1365+
def test_multi_line_expression_callable_local_variable_with_kwargs(self):
1366+
# 26426
1367+
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
1368+
1369+
def local_func(a, b):
1370+
return b
1371+
1372+
expected = df.copy()
1373+
expected['c'] = expected['a'] * local_func(b=7, a=1)
1374+
expected['d'] = expected['c'] + local_func(b=7, a=1)
1375+
ans = df.eval("""
1376+
c = a * @local_func(b=7, a=1)
1377+
d = c + @local_func(b=7, a=1)
1378+
""", inplace=True)
1379+
assert_frame_equal(expected, df)
1380+
assert ans is None
1381+
13481382
def test_assignment_in_query(self):
13491383
# GH 8664
13501384
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})

0 commit comments

Comments
 (0)