@@ -1341,20 +1341,139 @@ def test_missing_attribute(self, df):
1341
1341
with pytest .raises (AttributeError , match = message ):
1342
1342
df .eval ("@pd.thing" )
1343
1343
1344
- def test_failing_quote (self , df ):
1345
- msg = r"(Could not convert ).*( to a valid Python identifier.)"
1346
- with pytest . raises ( SyntaxError , match = msg ):
1347
- df . query ( "`it's` > `that's`" )
1344
+ def test_quote (self , df ):
1345
+ res = df . query ( "`it's` > `that's`" )
1346
+ expect = df [ df [ "it's" ] > df [ "that's" ]]
1347
+ tm . assert_frame_equal ( res , expect )
1348
1348
1349
1349
def test_failing_character_outside_range (self , df ):
1350
1350
msg = r"(Could not convert ).*( to a valid Python identifier.)"
1351
1351
with pytest .raises (SyntaxError , match = msg ):
1352
1352
df .query ("`☺` > 4" )
1353
1353
1354
- def test_failing_hashtag (self , df ):
1355
- msg = "Failed to parse backticks"
1356
- with pytest .raises (SyntaxError , match = msg ):
1357
- df .query ("`foo#bar` > 4" )
1354
+ def test_hashtag (self , df ):
1355
+ res = df .query ("`foo#bar` > 4" )
1356
+ expect = df [df ["foo#bar" ] > 4 ]
1357
+ tm .assert_frame_equal (res , expect )
1358
+
1359
+ def test_expr_with_column_name_with_hashtag_character (self ):
1360
+ # GH 59285
1361
+ df = DataFrame ((1 , 2 , 3 ), columns = ["a#" ])
1362
+ result = df .query ("`a#` < 2" )
1363
+ expected = df [df ["a#" ] < 2 ]
1364
+ tm .assert_frame_equal (result , expected )
1365
+
1366
+ def test_expr_with_comment (self ):
1367
+ # GH 59285
1368
+ df = DataFrame ((1 , 2 , 3 ), columns = ["a#" ])
1369
+ result = df .query ("`a#` < 2 # This is a comment" )
1370
+ expected = df [df ["a#" ] < 2 ]
1371
+ tm .assert_frame_equal (result , expected )
1372
+
1373
+ def test_expr_with_column_name_with_backtick_and_hash (self ):
1374
+ # GH 59285
1375
+ df = DataFrame ((1 , 2 , 3 ), columns = ["a`#b" ])
1376
+ result = df .query ("`a``#b` < 2" )
1377
+ expected = df [df ["a`#b" ] < 2 ]
1378
+ tm .assert_frame_equal (result , expected )
1379
+
1380
+ def test_expr_with_column_name_with_backtick (self ):
1381
+ # GH 59285
1382
+ df = DataFrame ({"a`b" : (1 , 2 , 3 ), "ab" : (4 , 5 , 6 )})
1383
+ result = df .query ("`a``b` < 2" )
1384
+ # Note: Formatting checks may wrongly consider the above ``inline code``.
1385
+ expected = df [df ["a`b" ] < 2 ]
1386
+ tm .assert_frame_equal (result , expected )
1387
+
1388
+ def test_expr_with_string_with_backticks (self ):
1389
+ # GH 59285
1390
+ df = DataFrame (("`" , "`````" , "``````````" ), columns = ["#backticks" ])
1391
+ result = df .query ("'```' < `#backticks`" )
1392
+ expected = df ["```" < df ["#backticks" ]]
1393
+ tm .assert_frame_equal (result , expected )
1394
+
1395
+ def test_expr_with_string_with_backticked_substring_same_as_column_name (self ):
1396
+ # GH 59285
1397
+ df = DataFrame (("`" , "`````" , "``````````" ), columns = ["#backticks" ])
1398
+ result = df .query ("'`#backticks`' < `#backticks`" )
1399
+ expected = df ["`#backticks`" < df ["#backticks" ]]
1400
+ tm .assert_frame_equal (result , expected )
1401
+
1402
+ @pytest .mark .parametrize (
1403
+ "col1,col2,expr" ,
1404
+ [
1405
+ ("it's" , "that's" , "`it's` < `that's`" ),
1406
+ ('it"s' , 'that"s' , '`it"s` < `that"s`' ),
1407
+ ("it's" , 'that\' s "nice"' , "`it's` < `that's \" nice\" `" ),
1408
+ ("it's" , "that's #cool" , "`it's` < `that's #cool` # This is a comment" ),
1409
+ ],
1410
+ )
1411
+ def test_expr_with_column_names_with_special_characters (self , col1 , col2 , expr ):
1412
+ # GH 59285
1413
+ df = DataFrame (
1414
+ [
1415
+ {col1 : 1 , col2 : 2 },
1416
+ {col1 : 3 , col2 : 4 },
1417
+ {col1 : - 1 , col2 : - 2 },
1418
+ {col1 : - 3 , col2 : - 4 },
1419
+ ]
1420
+ )
1421
+ result = df .query (expr )
1422
+ expected = df [df [col1 ] < df [col2 ]]
1423
+ tm .assert_frame_equal (result , expected )
1424
+
1425
+ def test_expr_with_no_backticks (self ):
1426
+ # GH 59285
1427
+ df = DataFrame (("aaa" , "vvv" , "zzz" ), columns = ["column_name" ])
1428
+ result = df .query ("'value' < column_name" )
1429
+ expected = df ["value" < df ["column_name" ]]
1430
+ tm .assert_frame_equal (result , expected )
1431
+
1432
+ def test_expr_with_no_quotes_and_backtick_is_unmatched (self ):
1433
+ # GH 59285
1434
+ df = DataFrame ((1 , 5 , 10 ), columns = ["column-name" ])
1435
+ with pytest .raises (SyntaxError , match = "invalid syntax" ):
1436
+ df .query ("5 < `column-name" )
1437
+
1438
+ def test_expr_with_no_quotes_and_backtick_is_matched (self ):
1439
+ # GH 59285
1440
+ df = DataFrame ((1 , 5 , 10 ), columns = ["column-name" ])
1441
+ result = df .query ("5 < `column-name`" )
1442
+ expected = df [5 < df ["column-name" ]]
1443
+ tm .assert_frame_equal (result , expected )
1444
+
1445
+ def test_expr_with_backtick_opened_before_quote_and_backtick_is_unmatched (self ):
1446
+ # GH 59285
1447
+ df = DataFrame ((1 , 5 , 10 ), columns = ["It's" ])
1448
+ with pytest .raises (SyntaxError , match = "unterminated string literal" ):
1449
+ df .query ("5 < `It's" )
1450
+
1451
+ def test_expr_with_backtick_opened_before_quote_and_backtick_is_matched (self ):
1452
+ # GH 59285
1453
+ df = DataFrame ((1 , 5 , 10 ), columns = ["It's" ])
1454
+ result = df .query ("5 < `It's`" )
1455
+ expected = df [5 < df ["It's" ]]
1456
+ tm .assert_frame_equal (result , expected )
1457
+
1458
+ def test_expr_with_quote_opened_before_backtick_and_quote_is_unmatched (self ):
1459
+ # GH 59285
1460
+ df = DataFrame (("aaa" , "vvv" , "zzz" ), columns = ["column-name" ])
1461
+ with pytest .raises (SyntaxError , match = "unterminated string literal" ):
1462
+ df .query ("`column-name` < 'It`s that\\ 's \" quote\" #hash" )
1463
+
1464
+ def test_expr_with_quote_opened_before_backtick_and_quote_is_matched_at_end (self ):
1465
+ # GH 59285
1466
+ df = DataFrame (("aaa" , "vvv" , "zzz" ), columns = ["column-name" ])
1467
+ result = df .query ("`column-name` < 'It`s that\\ 's \" quote\" #hash'" )
1468
+ expected = df [df ["column-name" ] < 'It`s that\' s "quote" #hash' ]
1469
+ tm .assert_frame_equal (result , expected )
1470
+
1471
+ def test_expr_with_quote_opened_before_backtick_and_quote_is_matched_in_mid (self ):
1472
+ # GH 59285
1473
+ df = DataFrame (("aaa" , "vvv" , "zzz" ), columns = ["column-name" ])
1474
+ result = df .query ("'It`s that\\ 's \" quote\" #hash' < `column-name`" )
1475
+ expected = df ['It`s that\' s "quote" #hash' < df ["column-name" ]]
1476
+ tm .assert_frame_equal (result , expected )
1358
1477
1359
1478
def test_call_non_named_expression (self , df ):
1360
1479
"""
0 commit comments