Skip to content

Commit 6d8fbb2

Browse files
add tests
1 parent 82bcba8 commit 6d8fbb2

File tree

2 files changed

+65
-8
lines changed

2 files changed

+65
-8
lines changed

pandas/core/computation/parsing.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,13 @@ def _split_by_backtick(s: str) -> list[tuple[bool, str]]:
216216
if (quote_index == -1) or (backtick_index < quote_index):
217217
next_backtick_index = s.find("`", backtick_index + 1)
218218

219-
# Backtick is unmatched (Possibly a mistake)
219+
# Backtick is unmatched (Bad syntax)
220220
if next_backtick_index == -1:
221221
substrings.append((False, substring + s[i:]))
222222
break
223223
# Backtick is matched
224224
else:
225-
if i != backtick_index:
225+
if substring or (i != backtick_index):
226226
substrings.append((False, substring + s[i:backtick_index]))
227227
substrings.append((True, s[backtick_index : next_backtick_index + 1]))
228228
substring = ""
@@ -238,19 +238,15 @@ def _split_by_backtick(s: str) -> list[tuple[bool, str]]:
238238
next_quote_index = i + end - 1
239239
break
240240

241-
# Quote is unmatched (Possibly a mistake)
242-
if next_quote_index == -1:
243-
substrings.append((False, substring + s[i:]))
244-
break
241+
# Quote is unmatched (Bad syntax), or
245242
# Quote is matched, and the next quote is at the end of the string
246-
elif next_quote_index + 1 == len(s):
243+
if (next_quote_index == -1) or (next_quote_index + 1 == len(s)):
247244
substrings.append((False, substring + s[i:]))
248245
break
249246
# Quote is matched, and the next quote is in the middle of the string
250247
else:
251248
substring += s[i : next_quote_index + 1]
252249
i = next_quote_index + 1
253-
continue
254250

255251
return substrings
256252

pandas/tests/computation/test_eval.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2034,6 +2034,67 @@ def test_query_on_column_names_with_special_characters(col1, col2, expr):
20342034
tm.assert_frame_equal(result, expected)
20352035

20362036

2037+
def test_query_on_expr_with_no_backticks():
2038+
# GH 59285
2039+
df = DataFrame(("aaa", "vvv", "zzz"), columns=["column_name"])
2040+
result = df.query("'value' < column_name")
2041+
expected = df["value" < df["column_name"]]
2042+
tm.assert_frame_equal(result, expected)
2043+
2044+
2045+
def test_query_on_expr_with_no_quotes_and_backtick_is_unmatched():
2046+
# GH 59285
2047+
df = DataFrame((1, 5, 10), columns=["column-name"])
2048+
with pytest.raises(SyntaxError, match="invalid syntax"):
2049+
df.query("5 < `column-name")
2050+
2051+
2052+
def test_query_on_expr_with_no_quotes_and_backtick_is_matched():
2053+
# GH 59285
2054+
df = DataFrame((1, 5, 10), columns=["column-name"])
2055+
result = df.query("5 < `column-name`")
2056+
expected = df[5 < df["column-name"]]
2057+
tm.assert_frame_equal(result, expected)
2058+
2059+
2060+
def test_query_on_expr_with_backtick_opened_before_quote_and_backtick_is_unmatched():
2061+
# GH 59285
2062+
df = DataFrame((1, 5, 10), columns=["It's"])
2063+
with pytest.raises(SyntaxError, match="unterminated string literal"):
2064+
df.query("5 < `It's")
2065+
2066+
2067+
def test_query_on_expr_with_backtick_opened_before_quote_and_backtick_is_matched():
2068+
# GH 59285
2069+
df = DataFrame((1, 5, 10), columns=["It's"])
2070+
result = df.query("5 < `It's`")
2071+
expected = df[5 < df["It's"]]
2072+
tm.assert_frame_equal(result, expected)
2073+
2074+
2075+
def test_query_on_expr_with_quote_opened_before_backtick_and_quote_is_unmatched():
2076+
# GH 59285
2077+
df = DataFrame(("aaa", "vvv", "zzz"), columns=['It`s that\\\'s "quote" #hash'])
2078+
with pytest.raises(SyntaxError, match="unterminated string literal"):
2079+
df.query("`column-name` < 'It`s that\\'s \"quote\" #hash")
2080+
2081+
2082+
def test_query_on_expr_with_quote_opened_before_backtick_and_quote_is_matched_at_end():
2083+
# GH 59285
2084+
df = DataFrame(("aaa", "vvv", "zzz"), columns=["column-name"])
2085+
result = df.query("`column-name` < 'It`s that\\'s \"quote\" #hash'")
2086+
expected = df[df["column-name"] < 'It`s that\'s "quote" #hash']
2087+
tm.assert_frame_equal(result, expected)
2088+
2089+
2090+
def test_query_on_expr_with_quote_opened_before_backtick_and_quote_is_matched_in_mid():
2091+
# GH 59285
2092+
df = DataFrame(("aaa", "vvv", "zzz"), columns=["column-name"])
2093+
result = df.query("'It`s that\\'s \"quote\" #hash' < `column-name`")
2094+
expected = df['It`s that\'s "quote" #hash' < df["column-name"]]
2095+
tm.assert_frame_equal(result, expected)
2096+
2097+
20372098
def test_set_inplace():
20382099
# https://github.com/pandas-dev/pandas/issues/47449
20392100
# Ensure we don't only update the DataFrame inplace, but also the actual

0 commit comments

Comments
 (0)