Merge 54beed5df7
into 63dfa4bb84
This commit is contained in:
commit
f91f6f470c
1
AUTHORS
1
AUTHORS
|
@ -271,6 +271,7 @@ Matt Bachmann
|
|||
Matt Duck
|
||||
Matt Williams
|
||||
Matthias Hafner
|
||||
Max Berkowitz
|
||||
Maxim Filipenko
|
||||
Maximilian Cosmo Sitter
|
||||
mbyt
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Emit a warning when unregistered marks are used with the command line option -m.
|
|
@ -236,7 +236,7 @@ def deselect_by_mark(items: "List[Item]", config: Config) -> None:
|
|||
if not matchexpr:
|
||||
return
|
||||
|
||||
expr = _parse_expression(matchexpr, "Wrong expression passed to '-m'")
|
||||
expr = _parse_expression(matchexpr, "Wrong expression passed to '-m'", True)
|
||||
remaining: List[Item] = []
|
||||
deselected: List[Item] = []
|
||||
for item in items:
|
||||
|
@ -249,9 +249,9 @@ def deselect_by_mark(items: "List[Item]", config: Config) -> None:
|
|||
items[:] = remaining
|
||||
|
||||
|
||||
def _parse_expression(expr: str, exc_message: str) -> Expression:
|
||||
def _parse_expression(expr: str, exc_message: str, mark: bool = False) -> Expression:
|
||||
try:
|
||||
return Expression.compile(expr)
|
||||
return Expression.compile(expr, mark)
|
||||
except ParseError as e:
|
||||
raise UsageError(f"{exc_message}: {expr}: {e}") from None
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ from typing import NoReturn
|
|||
from typing import Optional
|
||||
from typing import Sequence
|
||||
|
||||
from .structures import MARK_GEN
|
||||
|
||||
|
||||
__all__ = [
|
||||
"Expression",
|
||||
|
@ -197,12 +199,19 @@ class Expression:
|
|||
self.code = code
|
||||
|
||||
@classmethod
|
||||
def compile(self, input: str) -> "Expression":
|
||||
def compile(self, input: str, mark: bool = False) -> "Expression":
|
||||
"""Compile a match expression.
|
||||
|
||||
:param input: The input expression - one line.
|
||||
"""
|
||||
astexpr = expression(Scanner(input))
|
||||
|
||||
if mark:
|
||||
for node in ast.walk(astexpr):
|
||||
# if the node is an identifier, i.e. a mark name
|
||||
if isinstance(node, ast.Name):
|
||||
MARK_GEN.verify_mark(node.id[len(IDENT_PREFIX) :])
|
||||
|
||||
code: types.CodeType = compile(
|
||||
astexpr,
|
||||
filename="<pytest match expression>",
|
||||
|
|
|
@ -520,11 +520,7 @@ class MarkGenerator:
|
|||
self._config: Optional[Config] = None
|
||||
self._markers: Set[str] = set()
|
||||
|
||||
def __getattr__(self, name: str) -> MarkDecorator:
|
||||
"""Generate a new :class:`MarkDecorator` with the given name."""
|
||||
if name[0] == "_":
|
||||
raise AttributeError("Marker name must NOT start with underscore")
|
||||
|
||||
def verify_mark(self, name: str) -> None:
|
||||
if self._config is not None:
|
||||
# We store a set of markers as a performance optimisation - if a mark
|
||||
# name is in the set we definitely know it, but a mark may be known and
|
||||
|
@ -556,9 +552,16 @@ class MarkGenerator:
|
|||
"custom marks to avoid this warning - for details, see "
|
||||
"https://docs.pytest.org/en/stable/how-to/mark.html",
|
||||
PytestUnknownMarkWarning,
|
||||
2,
|
||||
3,
|
||||
)
|
||||
|
||||
def __getattr__(self, name: str) -> MarkDecorator:
|
||||
"""Generate a new :class:`MarkDecorator` with the given name."""
|
||||
if name[0] == "_":
|
||||
raise AttributeError("Marker name must NOT start with underscore")
|
||||
|
||||
self.verify_mark(name)
|
||||
|
||||
return MarkDecorator(Mark(name, (), {}, _ispytest=True), _ispytest=True)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue