Skip to content

Commit feaa0d0

Browse files
WillAydjreback
authored andcommitted
DOC: Error msg using Python keyword in numexpr query pandas-dev#18221 (pandas-dev#18248)
1 parent c3cfe90 commit feaa0d0

File tree

4 files changed

+23
-3
lines changed

4 files changed

+23
-3
lines changed

doc/source/whatsnew/v0.22.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,6 @@ Categorical
161161
Other
162162
^^^^^
163163

164-
-
164+
- Improved error message when attempting to use a Python keyword as an identifier in a numexpr query (:issue:`18221`)
165165
-
166166
-

pandas/core/computation/expr.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,14 @@ def __init__(self, env, engine, parser, preparser=_preparse):
307307
def visit(self, node, **kwargs):
308308
if isinstance(node, string_types):
309309
clean = self.preparser(node)
310-
node = ast.fix_missing_locations(ast.parse(clean))
310+
try:
311+
node = ast.fix_missing_locations(ast.parse(clean))
312+
except SyntaxError as e:
313+
from keyword import iskeyword
314+
if any(iskeyword(x) for x in clean.split()):
315+
e.msg = ("Python keyword not valid identifier"
316+
" in numexpr query")
317+
raise e
311318

312319
method = 'visit_' + node.__class__.__name__
313320
visitor = getattr(self, method)

pandas/core/frame.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2267,7 +2267,8 @@ def query(self, expr, inplace=False, **kwargs):
22672267
by default, which allows you to treat both the index and columns of the
22682268
frame as a column in the frame.
22692269
The identifier ``index`` is used for the frame index; you can also
2270-
use the name of the index to identify it in a query.
2270+
use the name of the index to identify it in a query. Please note that
2271+
Python keywords may not be used as identifiers.
22712272
22722273
For further details and examples see the ``query`` documentation in
22732274
:ref:`indexing <indexing.query>`.

pandas/tests/computation/test_eval.py

+12
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,18 @@ def test_float_truncation(self):
718718
expected = df.loc[[1], :]
719719
tm.assert_frame_equal(expected, result)
720720

721+
def test_disallow_python_keywords(self):
722+
# GH 18221
723+
df = pd.DataFrame([[0, 0, 0]], columns=['foo', 'bar', 'class'])
724+
msg = "Python keyword not valid identifier in numexpr query"
725+
with tm.assert_raises_regex(SyntaxError, msg):
726+
df.query('class == 0')
727+
728+
df = pd.DataFrame()
729+
df.index.name = 'lambda'
730+
with tm.assert_raises_regex(SyntaxError, msg):
731+
df.query('lambda == 0')
732+
721733

722734
class TestEvalNumexprPython(TestEvalNumexprPandas):
723735

0 commit comments

Comments
 (0)