summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelog/7469.deprecation.rst1
-rw-r--r--changelog/7469.feature.rst1
-rw-r--r--doc/en/reference.rst2
-rw-r--r--src/_pytest/mark/structures.py11
-rw-r--r--src/pytest/__init__.py2
-rw-r--r--testing/test_mark.py4
6 files changed, 14 insertions, 7 deletions
diff --git a/changelog/7469.deprecation.rst b/changelog/7469.deprecation.rst
index 6922b3bbb..6bbc80755 100644
--- a/changelog/7469.deprecation.rst
+++ b/changelog/7469.deprecation.rst
@@ -2,5 +2,6 @@ Directly constructing the following classes is now deprecated:
- ``_pytest.mark.structures.Mark``
- ``_pytest.mark.structures.MarkDecorator``
+- ``_pytest.mark.structures.MarkGenerator``
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
diff --git a/changelog/7469.feature.rst b/changelog/7469.feature.rst
index 66113aa58..81f93d1f7 100644
--- a/changelog/7469.feature.rst
+++ b/changelog/7469.feature.rst
@@ -4,6 +4,7 @@ The newly-exported types are:
- ``pytest.Mark`` for :class:`marks <pytest.Mark>`.
- ``pytest.MarkDecorator`` for :class:`mark decorators <pytest.MarkDecorator>`.
+- ``pytest.MarkGenerator`` for the :class:`pytest.mark <pytest.MarkGenerator>` singleton.
Constructing them directly is not supported; they are only meant for use in type annotations.
Doing so will emit a deprecation warning, and may become a hard-error in pytest 7.0.
diff --git a/doc/en/reference.rst b/doc/en/reference.rst
index 8bd4111a1..c8e8dca75 100644
--- a/doc/en/reference.rst
+++ b/doc/en/reference.rst
@@ -856,7 +856,7 @@ MarkDecorator
MarkGenerator
~~~~~~~~~~~~~
-.. autoclass:: _pytest.mark.MarkGenerator
+.. autoclass:: pytest.MarkGenerator()
:members:
diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py
index 8bce33e68..ae6920735 100644
--- a/src/_pytest/mark/structures.py
+++ b/src/_pytest/mark/structures.py
@@ -488,9 +488,6 @@ class MarkGenerator:
applies a 'slowtest' :class:`Mark` on ``test_function``.
"""
- _config: Optional[Config] = None
- _markers: Set[str] = set()
-
# See TYPE_CHECKING above.
if TYPE_CHECKING:
skip: _SkipMarkDecorator
@@ -500,7 +497,13 @@ class MarkGenerator:
usefixtures: _UsefixturesMarkDecorator
filterwarnings: _FilterwarningsMarkDecorator
+ def __init__(self, *, _ispytest: bool = False) -> None:
+ check_ispytest(_ispytest)
+ 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")
@@ -541,7 +544,7 @@ class MarkGenerator:
return MarkDecorator(Mark(name, (), {}, _ispytest=True), _ispytest=True)
-MARK_GEN = MarkGenerator()
+MARK_GEN = MarkGenerator(_ispytest=True)
@final
diff --git a/src/pytest/__init__.py b/src/pytest/__init__.py
index 1d5b38ee0..74cf00ee2 100644
--- a/src/pytest/__init__.py
+++ b/src/pytest/__init__.py
@@ -24,6 +24,7 @@ from _pytest.main import Session
from _pytest.mark import Mark
from _pytest.mark import MARK_GEN as mark
from _pytest.mark import MarkDecorator
+from _pytest.mark import MarkGenerator
from _pytest.mark import param
from _pytest.monkeypatch import MonkeyPatch
from _pytest.nodes import Collector
@@ -93,6 +94,7 @@ __all__ = [
"mark",
"Mark",
"MarkDecorator",
+ "MarkGenerator",
"Module",
"MonkeyPatch",
"Package",
diff --git a/testing/test_mark.py b/testing/test_mark.py
index e0b91f0ce..5f4b3e063 100644
--- a/testing/test_mark.py
+++ b/testing/test_mark.py
@@ -21,7 +21,7 @@ class TestMark:
assert attr in module.__all__ # type: ignore
def test_pytest_mark_notcallable(self) -> None:
- mark = MarkGenerator()
+ mark = MarkGenerator(_ispytest=True)
with pytest.raises(TypeError):
mark() # type: ignore[operator]
@@ -40,7 +40,7 @@ class TestMark:
assert pytest.mark.foo.with_args(SomeClass) is not SomeClass # type: ignore[comparison-overlap]
def test_pytest_mark_name_starts_with_underscore(self) -> None:
- mark = MarkGenerator()
+ mark = MarkGenerator(_ispytest=True)
with pytest.raises(AttributeError):
mark._some_name