diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index 77dabd95dec..90c14a4addb 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -239,11 +239,14 @@ def deselect_by_mark(items: "List[Item]", config: Config) -> None: expr = _parse_expression(matchexpr, "Wrong expression passed to '-m'") remaining: List[Item] = [] deselected: List[Item] = [] + remaining_append = remaining.append + deselected_append = deselected.append + for item in items: if expr.evaluate(MarkMatcher.from_item(item)): - remaining.append(item) + remaining_append(item) else: - deselected.append(item) + deselected_append(item) if deselected: config.hook.pytest_deselected(items=deselected) items[:] = remaining diff --git a/src/_pytest/mark/expression.py b/src/_pytest/mark/expression.py index 78b7fda696b..bf051d36a4b 100644 --- a/src/_pytest/mark/expression.py +++ b/src/_pytest/mark/expression.py @@ -28,6 +28,9 @@ from typing import Sequence +_EMPTY_BUILTINS = {"__builtins__": {}} + + __all__ = [ "Expression", "ParseError", @@ -46,7 +49,7 @@ class TokenType(enum.Enum): @dataclasses.dataclass(frozen=True) class Token: - __slots__ = ("type", "value", "pos") + __slots__ = ("pos", "type", "value") type: TokenType value: str pos: int @@ -68,7 +71,7 @@ def __str__(self) -> str: class Scanner: - __slots__ = ("tokens", "current") + __slots__ = ("current", "tokens") def __init__(self, input: str) -> None: self.tokens = self.lex(input) @@ -219,5 +222,5 @@ def evaluate(self, matcher: Callable[[str], bool]) -> bool: :returns: Whether the expression matches or not. """ - ret: bool = eval(self.code, {"__builtins__": {}}, MatcherAdapter(matcher)) + ret: bool = eval(self.code, _EMPTY_BUILTINS, MatcherAdapter(matcher)) return ret