diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index 8d2275b2f51c5..c19a3951ac359 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -71,3 +71,6 @@ Bug Fixes and ``left`` keyword is specified (:issue:`7226`) - BUG in ``DataFrame.hist`` raises ``TypeError`` when it contains non numeric column (:issue:`7277`) - BUG in ``Index.delete`` does not preserve ``name`` and ``freq`` attributes (:issue:`7302`) +- Bug in ``DataFrame.query()``/``eval`` where local string variables with the @ + sign were being treated as temporaries attempting to be deleted + (:issue:`7300`). diff --git a/pandas/computation/expr.py b/pandas/computation/expr.py index 353c58c23febd..b6a1fcbec8339 100644 --- a/pandas/computation/expr.py +++ b/pandas/computation/expr.py @@ -340,12 +340,10 @@ def _rewrite_membership_op(self, node, left, right): # pop the string variable out of locals and replace it with a list # of one string, kind of a hack if right_str: - self.env.remove_tmp(right.name) name = self.env.add_tmp([right.value]) right = self.term_type(name, self.env) if left_str: - self.env.remove_tmp(left.name) name = self.env.add_tmp([left.value]) left = self.term_type(name, self.env) diff --git a/pandas/computation/scope.py b/pandas/computation/scope.py index 24be71f96b282..875aaa959b264 100644 --- a/pandas/computation/scope.py +++ b/pandas/computation/scope.py @@ -278,16 +278,6 @@ def add_tmp(self, value): # only increment if the variable gets put in the scope return name - def remove_tmp(self, name): - """Remove a temporary variable from this scope - - Parameters - ---------- - name : str - The name of a temporary to be removed - """ - del self.temps[name] - @property def ntemps(self): """The number of temporary variables in this scope""" diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 84bed9be76939..9b727d5752097 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -13685,6 +13685,18 @@ def test_query_single_element_booleans(self): for parser, engine in product(PARSERS, ENGINES): yield self.check_query_single_element_booleans, parser, engine + def check_query_string_scalar_variable(self, parser, engine): + tm.skip_if_no_ne(engine) + df = pd.DataFrame({'Symbol': ['BUD US', 'BUD US', 'IBM US', 'IBM US'], + 'Price': [109.70, 109.72, 183.30, 183.35]}) + e = df[df.Symbol == 'BUD US'] + symb = 'BUD US' + r = df.query('Symbol == @symb', parser=parser, engine=engine) + tm.assert_frame_equal(e, r) + + def test_query_string_scalar_variable(self): + for parser, engine in product(['pandas'], ENGINES): + yield self.check_query_string_scalar_variable, parser, engine class TestDataFrameEvalNumExprPandas(tm.TestCase):