mark: export pytest.Mark for typing purposes
The type cannot be constructed directly, but is exported for use in type annotations, since it is reachable through existing public API.
This commit is contained in:
parent
89dcfbf293
commit
2ec372df8b
|
@ -0,0 +1,5 @@
|
|||
Directly constructing the following classes is now deprecated:
|
||||
|
||||
- ``_pytest.mark.structures.Mark``
|
||||
|
||||
These have always been considered private, but now issue a deprecation warning, which may become a hard error in pytest 7.0.0.
|
|
@ -0,0 +1,10 @@
|
|||
The types of objects used in pytest's API are now exported so they may be used in type annotations.
|
||||
|
||||
The newly-exported types are:
|
||||
|
||||
- ``pytest.Mark`` for :class:`marks <pytest.Mark>`.
|
||||
|
||||
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.
|
||||
|
||||
Subclassing them is also not supported. This is not currently enforced at runtime, but is detected by type-checkers such as mypy.
|
|
@ -239,7 +239,7 @@ For example:
|
|||
def test_function():
|
||||
...
|
||||
|
||||
Will create and attach a :class:`Mark <_pytest.mark.structures.Mark>` object to the collected
|
||||
Will create and attach a :class:`Mark <pytest.Mark>` object to the collected
|
||||
:class:`Item <pytest.Item>`, which can then be accessed by fixtures or hooks with
|
||||
:meth:`Node.iter_markers <_pytest.nodes.Node.iter_markers>`. The ``mark`` object will have the following attributes:
|
||||
|
||||
|
@ -863,7 +863,7 @@ MarkGenerator
|
|||
Mark
|
||||
~~~~
|
||||
|
||||
.. autoclass:: _pytest.mark.structures.Mark
|
||||
.. autoclass:: pytest.Mark()
|
||||
:members:
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ from ..compat import final
|
|||
from ..compat import NOTSET
|
||||
from ..compat import NotSetType
|
||||
from _pytest.config import Config
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.outcomes import fail
|
||||
from _pytest.warning_types import PytestUnknownMarkWarning
|
||||
|
||||
|
@ -200,21 +201,38 @@ class ParameterSet(
|
|||
|
||||
|
||||
@final
|
||||
@attr.s(frozen=True)
|
||||
@attr.s(frozen=True, init=False, auto_attribs=True)
|
||||
class Mark:
|
||||
#: Name of the mark.
|
||||
name = attr.ib(type=str)
|
||||
name: str
|
||||
#: Positional arguments of the mark decorator.
|
||||
args = attr.ib(type=Tuple[Any, ...])
|
||||
args: Tuple[Any, ...]
|
||||
#: Keyword arguments of the mark decorator.
|
||||
kwargs = attr.ib(type=Mapping[str, Any])
|
||||
kwargs: Mapping[str, Any]
|
||||
|
||||
#: Source Mark for ids with parametrize Marks.
|
||||
_param_ids_from = attr.ib(type=Optional["Mark"], default=None, repr=False)
|
||||
_param_ids_from: Optional["Mark"] = attr.ib(default=None, repr=False)
|
||||
#: Resolved/generated ids with parametrize Marks.
|
||||
_param_ids_generated = attr.ib(
|
||||
type=Optional[Sequence[str]], default=None, repr=False
|
||||
)
|
||||
_param_ids_generated: Optional[Sequence[str]] = attr.ib(default=None, repr=False)
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
args: Tuple[Any, ...],
|
||||
kwargs: Mapping[str, Any],
|
||||
param_ids_from: Optional["Mark"] = None,
|
||||
param_ids_generated: Optional[Sequence[str]] = None,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
""":meta private:"""
|
||||
check_ispytest(_ispytest)
|
||||
# Weirdness to bypass frozen=True.
|
||||
object.__setattr__(self, "name", name)
|
||||
object.__setattr__(self, "args", args)
|
||||
object.__setattr__(self, "kwargs", kwargs)
|
||||
object.__setattr__(self, "_param_ids_from", param_ids_from)
|
||||
object.__setattr__(self, "_param_ids_generated", param_ids_generated)
|
||||
|
||||
def _has_param_ids(self) -> bool:
|
||||
return "ids" in self.kwargs or len(self.args) >= 4
|
||||
|
@ -243,6 +261,7 @@ class Mark:
|
|||
self.args + other.args,
|
||||
dict(self.kwargs, **other.kwargs),
|
||||
param_ids_from=param_ids_from,
|
||||
_ispytest=True,
|
||||
)
|
||||
|
||||
|
||||
|
@ -320,7 +339,7 @@ class MarkDecorator:
|
|||
|
||||
:rtype: MarkDecorator
|
||||
"""
|
||||
mark = Mark(self.name, args, kwargs)
|
||||
mark = Mark(self.name, args, kwargs, _ispytest=True)
|
||||
return self.__class__(self.mark.combined_with(mark))
|
||||
|
||||
# Type ignored because the overloads overlap with an incompatible
|
||||
|
@ -515,7 +534,7 @@ class MarkGenerator:
|
|||
2,
|
||||
)
|
||||
|
||||
return MarkDecorator(Mark(name, (), {}))
|
||||
return MarkDecorator(Mark(name, (), {}, _ispytest=True))
|
||||
|
||||
|
||||
MARK_GEN = MarkGenerator()
|
||||
|
|
|
@ -21,6 +21,7 @@ from _pytest.fixtures import yield_fixture
|
|||
from _pytest.freeze_support import freeze_includes
|
||||
from _pytest.logging import LogCaptureFixture
|
||||
from _pytest.main import Session
|
||||
from _pytest.mark import Mark
|
||||
from _pytest.mark import MARK_GEN as mark
|
||||
from _pytest.mark import param
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
|
@ -89,6 +90,7 @@ __all__ = [
|
|||
"LogCaptureFixture",
|
||||
"main",
|
||||
"mark",
|
||||
"Mark",
|
||||
"Module",
|
||||
"MonkeyPatch",
|
||||
"Package",
|
||||
|
|
Loading…
Reference in New Issue