11from __future__ import annotations
22
3- from collections .abc import Callable
4- from typing import cast
5-
63from _pytest .mark import MarkMatcher
74from _pytest .mark .expression import Expression
85from _pytest .mark .expression import MatcherCall
96from _pytest .mark .expression import ParseError
107import pytest
118
129
13- def evaluate (input : str , matcher : Callable [[ str ], bool ] ) -> bool :
14- return Expression .compile (input ).evaluate (cast ( MatcherCall , matcher ) )
10+ def evaluate (input : str , matcher : MatcherCall ) -> bool :
11+ return Expression .compile (input ).evaluate (matcher )
1512
1613
1714def test_empty_is_false () -> None :
18- assert not evaluate ("" , lambda ident : False )
19- assert not evaluate ("" , lambda ident : True )
20- assert not evaluate (" " , lambda ident : False )
21- assert not evaluate ("\t " , lambda ident : False )
15+ assert not evaluate ("" , lambda ident , / , ** kwargs : False )
16+ assert not evaluate ("" , lambda ident , / , ** kwargs : True )
17+ assert not evaluate (" " , lambda ident , / , ** kwargs : False )
18+ assert not evaluate ("\t " , lambda ident , / , ** kwargs : False )
2219
2320
2421@pytest .mark .parametrize (
@@ -51,7 +48,9 @@ def test_empty_is_false() -> None:
5148 ),
5249)
5350def test_basic (expr : str , expected : bool ) -> None :
54- matcher = {"true" : True , "false" : False }.__getitem__
51+ def matcher (name : str , / , ** kwargs : str | int | bool | None ) -> bool :
52+ return {"true" : True , "false" : False }[name ]
53+
5554 assert evaluate (expr , matcher ) is expected
5655
5756
@@ -67,7 +66,9 @@ def test_basic(expr: str, expected: bool) -> None:
6766 ),
6867)
6968def test_syntax_oddities (expr : str , expected : bool ) -> None :
70- matcher = {"true" : True , "false" : False }.__getitem__
69+ def matcher (name : str , / , ** kwargs : str | int | bool | None ) -> bool :
70+ return {"true" : True , "false" : False }[name ]
71+
7172 assert evaluate (expr , matcher ) is expected
7273
7374
@@ -77,7 +78,9 @@ def test_backslash_not_treated_specially() -> None:
7778 user will never need to insert a literal newline, only \n (two chars). So
7879 mark expressions themselves do not support escaping, instead they treat
7980 backslashes as regular identifier characters."""
80- matcher = {r"\nfoo\n" }.__contains__
81+
82+ def matcher (name : str , / , ** kwargs : str | int | bool | None ) -> bool :
83+ return {r"\nfoo\n" }.__contains__ (name )
8184
8285 assert evaluate (r"\nfoo\n" , matcher )
8386 assert not evaluate (r"foo" , matcher )
@@ -135,7 +138,7 @@ def test_backslash_not_treated_specially() -> None:
135138)
136139def test_syntax_errors (expr : str , column : int , message : str ) -> None :
137140 with pytest .raises (ParseError ) as excinfo :
138- evaluate (expr , lambda ident : True )
141+ evaluate (expr , lambda ident , / , ** kwargs : True )
139142 assert excinfo .value .column == column
140143 assert excinfo .value .message == message
141144
@@ -172,7 +175,10 @@ def test_syntax_errors(expr: str, column: int, message: str) -> None:
172175 ),
173176)
174177def test_valid_idents (ident : str ) -> None :
175- assert evaluate (ident , {ident : True }.__getitem__ )
178+ def matcher (name : str , / , ** kwargs : str | int | bool | None ) -> bool :
179+ return name == ident
180+
181+ assert evaluate (ident , matcher )
176182
177183
178184@pytest .mark .parametrize (
@@ -199,7 +205,7 @@ def test_valid_idents(ident: str) -> None:
199205)
200206def test_invalid_idents (ident : str ) -> None :
201207 with pytest .raises (ParseError ):
202- evaluate (ident , lambda ident : True )
208+ evaluate (ident , lambda ident , / , ** kwargs : True )
203209
204210
205211@pytest .mark .parametrize (
0 commit comments