@@ -434,6 +434,32 @@ def _parse_node_id(
434
434
)
435
435
436
436
437
+ def _find_left_bracket (nodeid ):
438
+ """Return tuple of part before final bracket open, separator [, and the remainder.
439
+ Notes:
440
+ Testcase names in case of parametrized tests are wrapped in [<test-case-name>].
441
+ Examples:
442
+ dirname[sometext]/dirname/testfile.py::testset::testname[testcase]
443
+ => ('dirname[sometext]/dirname/testfile.py::testset::testname', '[', 'testcase]')
444
+ dirname/dirname/testfile.py::testset::testname[testcase]
445
+ => ('dirname/dirname/testfile.py::testset::testname', '[', 'testcase]')
446
+ dirname/dirname/testfile.py::testset::testname[testcase[x]]
447
+ => ('dirname/dirname/testfile.py::testset::testname', '[', 'testcase[x]]')
448
+ """
449
+ if not nodeid .endswith ("]" ):
450
+ return nodeid , "" , ""
451
+ bracketcount = 0
452
+ for index , char in enumerate (nodeid [::- 1 ]):
453
+ if char == "]" :
454
+ bracketcount += 1
455
+ elif char == "[" :
456
+ bracketcount -= 1
457
+ if bracketcount == 0 :
458
+ n = len (nodeid ) - 1 - index
459
+ return nodeid [:n ], nodeid [n ], nodeid [n + 1 :]
460
+ return nodeid , "" , ""
461
+
462
+
437
463
def _iter_nodes (
438
464
testid ,
439
465
kind ,
@@ -448,7 +474,7 @@ def _iter_nodes(
448
474
testid = "." + _pathsep + testid
449
475
450
476
if kind == "function" and nodeid .endswith ("]" ):
451
- funcid , sep , parameterized = nodeid . partition ( "[" )
477
+ funcid , sep , parameterized = _find_left_bracket ( nodeid )
452
478
if not sep :
453
479
raise should_never_reach_here (
454
480
nodeid ,
0 commit comments