mark/expression: allow backslash characters in identifiers
Fixes #8983.
This commit is contained in:
parent
a446ee81fd
commit
25c65616f4
|
@ -0,0 +1,2 @@
|
||||||
|
The test selection options ``pytest -k`` and ``pytest -m`` now support matching names containing backslash (`\\`) characters.
|
||||||
|
Backslashes are treated literally, not as escape characters (the values being matched against are already escaped).
|
|
@ -6,7 +6,7 @@ expression: expr? EOF
|
||||||
expr: and_expr ('or' and_expr)*
|
expr: and_expr ('or' and_expr)*
|
||||||
and_expr: not_expr ('and' not_expr)*
|
and_expr: not_expr ('and' not_expr)*
|
||||||
not_expr: 'not' not_expr | '(' expr ')' | ident
|
not_expr: 'not' not_expr | '(' expr ')' | ident
|
||||||
ident: (\w|:|\+|-|\.|\[|\])+
|
ident: (\w|:|\+|-|\.|\[|\]|\\)+
|
||||||
|
|
||||||
The semantics are:
|
The semantics are:
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ class Scanner:
|
||||||
yield Token(TokenType.RPAREN, ")", pos)
|
yield Token(TokenType.RPAREN, ")", pos)
|
||||||
pos += 1
|
pos += 1
|
||||||
else:
|
else:
|
||||||
match = re.match(r"(:?\w|:|\+|-|\.|\[|\])+", input[pos:])
|
match = re.match(r"(:?\w|:|\+|-|\.|\[|\]|\\)+", input[pos:])
|
||||||
if match:
|
if match:
|
||||||
value = match.group(0)
|
value = match.group(0)
|
||||||
if value == "or":
|
if value == "or":
|
||||||
|
|
|
@ -66,6 +66,20 @@ def test_syntax_oddeties(expr: str, expected: bool) -> None:
|
||||||
assert evaluate(expr, matcher) is expected
|
assert evaluate(expr, matcher) is expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_backslash_not_treated_specially() -> None:
|
||||||
|
r"""When generating nodeids, if the source name contains special characters
|
||||||
|
like a newline, they are escaped into two characters like \n. Therefore, a
|
||||||
|
user will never need to insert a literal newline, only \n (two chars). So
|
||||||
|
mark expressions themselves do not support escaping, instead they treat
|
||||||
|
backslashes as regular identifier characters."""
|
||||||
|
matcher = {r"\nfoo\n"}.__contains__
|
||||||
|
|
||||||
|
assert evaluate(r"\nfoo\n", matcher)
|
||||||
|
assert not evaluate(r"foo", matcher)
|
||||||
|
with pytest.raises(ParseError):
|
||||||
|
evaluate("\nfoo\n", matcher)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("expr", "column", "message"),
|
("expr", "column", "message"),
|
||||||
(
|
(
|
||||||
|
@ -129,6 +143,7 @@ def test_syntax_errors(expr: str, column: int, message: str) -> None:
|
||||||
":::",
|
":::",
|
||||||
"a:::c",
|
"a:::c",
|
||||||
"a+-b",
|
"a+-b",
|
||||||
|
r"\nhe\\l\lo\n\t\rbye",
|
||||||
"אבגד",
|
"אבגד",
|
||||||
"aaאבגדcc",
|
"aaאבגדcc",
|
||||||
"a[bcd]",
|
"a[bcd]",
|
||||||
|
@ -156,7 +171,6 @@ def test_valid_idents(ident: str) -> None:
|
||||||
"ident",
|
"ident",
|
||||||
(
|
(
|
||||||
"/",
|
"/",
|
||||||
"\\",
|
|
||||||
"^",
|
"^",
|
||||||
"*",
|
"*",
|
||||||
"=",
|
"=",
|
||||||
|
|
Loading…
Reference in New Issue