diff --git a/changelog/8377.bugfix.rst b/changelog/8377.bugfix.rst new file mode 100644 index 000000000..3df54a949 --- /dev/null +++ b/changelog/8377.bugfix.rst @@ -0,0 +1,2 @@ +The test selection options ``pytest -k`` and ``pytest -m`` now support matching +names containing forward slash (``/``) characters. diff --git a/src/_pytest/mark/expression.py b/src/_pytest/mark/expression.py index 836e1ebd4..9d57e944b 100644 --- a/src/_pytest/mark/expression.py +++ b/src/_pytest/mark/expression.py @@ -6,7 +6,7 @@ expression: expr? EOF expr: and_expr ('or' and_expr)* and_expr: not_expr ('and' not_expr)* not_expr: 'not' not_expr | '(' expr ')' | ident -ident: (\w|:|\+|-|\.|\[|\]|\\)+ +ident: (\w|:|\+|-|\.|\[|\]|\\|/)+ The semantics are: @@ -88,7 +88,7 @@ class Scanner: yield Token(TokenType.RPAREN, ")", pos) pos += 1 else: - match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\)+", input[pos:]) + match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\|/)+", input[pos:]) if match: value = match.group(0) if value == "or": diff --git a/testing/test_mark.py b/testing/test_mark.py index ce65e7d56..19eff00f3 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -1111,7 +1111,7 @@ def test_pytest_param_id_allows_none_or_string(s) -> None: assert pytest.param(id=s) -@pytest.mark.parametrize("expr", ("NOT internal_err", "NOT (internal_err)", "bogus/")) +@pytest.mark.parametrize("expr", ("NOT internal_err", "NOT (internal_err)", "bogus=")) def test_marker_expr_eval_failure_handling(pytester: Pytester, expr) -> None: foo = pytester.makepyfile( """ diff --git a/testing/test_mark_expression.py b/testing/test_mark_expression.py index c758ee667..f3643e7b4 100644 --- a/testing/test_mark_expression.py +++ b/testing/test_mark_expression.py @@ -144,6 +144,7 @@ def test_syntax_errors(expr: str, column: int, message: str) -> None: "a:::c", "a+-b", r"\nhe\\l\lo\n\t\rbye", + "a/b", "אבגד", "aaאבגדcc", "a[bcd]", @@ -170,7 +171,6 @@ def test_valid_idents(ident: str) -> None: @pytest.mark.parametrize( "ident", ( - "/", "^", "*", "=",