Skip to content

Commit aec3899

Browse files
committed
Merge pull request #6430 from cpcloud/eval-fix-at-containing-strings
BUG: correctly tokenize local variable references
2 parents 2717ed3 + ae69462 commit aec3899

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

pandas/computation/expr.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,13 @@ def _replace_booleans(source):
5757

5858
def _replace_locals(source, local_symbol='@'):
5959
"""Replace local variables with a syntactically valid name."""
60-
return source.replace(local_symbol, _LOCAL_TAG)
60+
res = []
61+
for toknum, tokval, _, _, _ in tokenize_string(source):
62+
if toknum == tokenize.OP and tokval == local_symbol:
63+
res.append((tokenize.OP, _LOCAL_TAG))
64+
else:
65+
res.append((toknum, tokval))
66+
return tokenize.untokenize(res)
6167

6268

6369
def _preparse(source):

pandas/tests/test_frame.py

+8
Original file line numberDiff line numberDiff line change
@@ -12774,6 +12774,14 @@ def test_local_variable_with_in(self):
1277412774
result = df.query('@b - 1 in a', engine=engine, parser=parser)
1277512775
tm.assert_frame_equal(expected, result)
1277612776

12777+
def test_at_inside_string(self):
12778+
engine, parser = self.engine, self.parser
12779+
skip_if_no_pandas_parser(parser)
12780+
c = 1
12781+
df = DataFrame({'a': ['a', 'a', 'b', 'b', '@c', '@c']})
12782+
result = df.query('a == "@c"', engine=engine, parser=parser)
12783+
expected = df[df.a == "@c"]
12784+
tm.assert_frame_equal(result, expected)
1277712785

1277812786
class TestDataFrameQueryNumExprPython(TestDataFrameQueryNumExprPandas):
1277912787

0 commit comments

Comments
 (0)