MCPcopy Create free account
hub / github.com/pytest-dev/pytest / MarkGenerator

Class MarkGenerator

src/_pytest/mark/structures.py:466–534  ·  view source on GitHub ↗

Factory for :class:`MarkDecorator` objects - exposed as a ``pytest.mark`` singleton instance. Example:: import pytest @pytest.mark.slowtest def test_function(): pass applies a 'slowtest' :class:`Mark` on ``test_function``.

Source from the content-addressed store, hash-verified

464
465@final
466class MarkGenerator:
467 """Factory for :class:`MarkDecorator` objects - exposed as
468 a ``pytest.mark`` singleton instance.
469
470 Example::
471
472 import pytest
473
474 @pytest.mark.slowtest
475 def test_function():
476 pass
477
478 applies a 'slowtest' :class:`Mark` on ``test_function``.
479 """
480
481 # See TYPE_CHECKING above.
482 if TYPE_CHECKING:
483 skip: _SkipMarkDecorator
484 skipif: _SkipifMarkDecorator
485 xfail: _XfailMarkDecorator
486 parametrize: _ParametrizeMarkDecorator
487 usefixtures: _UsefixturesMarkDecorator
488 filterwarnings: _FilterwarningsMarkDecorator
489
490 def __init__(self, *, _ispytest: bool = False) -> None:
491 check_ispytest(_ispytest)
492 self._config: Optional[Config] = None
493 self._markers: Set[str] = set()
494
495 def __getattr__(self, name: str) -> MarkDecorator:
496 """Generate a new :class:`MarkDecorator` with the given name."""
497 if name[0] == "_":
498 raise AttributeError("Marker name must NOT start with underscore")
499
500 if self._config is not None:
501 # We store a set of markers as a performance optimisation - if a mark
502 # name is in the set we definitely know it, but a mark may be known and
503 # not in the set. We therefore start by updating the set!
504 if name not in self._markers:
505 for line in self._config.getini("markers"):
506 # example lines: "skipif(condition): skip the given test if..."
507 # or "hypothesis: tests which use Hypothesis", so to get the
508 # marker name we split on both `:` and `(`.
509 marker = line.split(":")[0].split("(")[0].strip()
510 self._markers.add(marker)
511
512 # If the name is not in the set of known marks after updating,
513 # then it really is time to issue a warning or an error.
514 if name not in self._markers:
515 if self._config.option.strict_markers or self._config.option.strict:
516 fail(
517 f"{name!r} not found in `markers` configuration option",
518 pytrace=False,
519 )
520
521 # Raise a specific error for common misspellings of "parametrize".
522 if name in ["parameterize", "parametrise", "parameterise"]:
523 __tracebackhide__ = True

Calls

no outgoing calls