Merge pull request #8017 from bluetech/typing-public-fixtures
Export types of builtin fixtures for type annotations
This commit is contained in:
commit
760a73c08c
|
@ -0,0 +1,18 @@
|
|||
Directly constructing/calling the following classes/functions is now deprecated:
|
||||
|
||||
- ``_pytest.cacheprovider.Cache``
|
||||
- ``_pytest.cacheprovider.Cache.for_config()``
|
||||
- ``_pytest.cacheprovider.Cache.clear_cache()``
|
||||
- ``_pytest.cacheprovider.Cache.cache_dir_from_config()``
|
||||
- ``_pytest.capture.CaptureFixture``
|
||||
- ``_pytest.fixtures.FixtureRequest``
|
||||
- ``_pytest.fixtures.SubRequest``
|
||||
- ``_pytest.logging.LogCaptureFixture``
|
||||
- ``_pytest.pytester.Pytester``
|
||||
- ``_pytest.pytester.Testdir``
|
||||
- ``_pytest.recwarn.WarningsRecorder``
|
||||
- ``_pytest.recwarn.WarningsChecker``
|
||||
- ``_pytest.tmpdir.TempPathFactory``
|
||||
- ``_pytest.tmpdir.TempdirFactory``
|
||||
|
||||
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,23 @@
|
|||
It is now possible to construct a :class:`MonkeyPatch` object directly as ``pytest.MonkeyPatch()``,
|
||||
in cases when the :fixture:`monkeypatch` fixture cannot be used. Previously some users imported it
|
||||
from the private `_pytest.monkeypatch.MonkeyPatch` namespace.
|
||||
|
||||
The types of builtin pytest fixtures are now exported so they may be used in type annotations of test functions.
|
||||
The newly-exported types are:
|
||||
|
||||
- ``pytest.FixtureRequest`` for the :fixture:`request` fixture.
|
||||
- ``pytest.Cache`` for the :fixture:`cache` fixture.
|
||||
- ``pytest.CaptureFixture[str]`` for the :fixture:`capfd` and :fixture:`capsys` fixtures.
|
||||
- ``pytest.CaptureFixture[bytes]`` for the :fixture:`capfdbinary` and :fixture:`capsysbinary` fixtures.
|
||||
- ``pytest.LogCaptureFixture`` for the :fixture:`caplog` fixture.
|
||||
- ``pytest.Pytester`` for the :fixture:`pytester` fixture.
|
||||
- ``pytest.Testdir`` for the :fixture:`testdir` fixture.
|
||||
- ``pytest.TempdirFactory`` for the :fixture:`tmpdir_factory` fixture.
|
||||
- ``pytest.TempPathFactory`` for the :fixture:`tmp_path_factory` fixture.
|
||||
- ``pytest.MonkeyPatch`` for the :fixture:`monkeypatch` fixture.
|
||||
- ``pytest.WarningsRecorder`` for the :fixture:`recwarn` fixture.
|
||||
|
||||
Constructing them is not supported (except for `MonkeyPatch`); 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.
|
|
@ -314,11 +314,10 @@ request ``pytestconfig`` into your fixture and get it with ``pytestconfig.cache`
|
|||
Under the hood, the cache plugin uses the simple
|
||||
``dumps``/``loads`` API of the :py:mod:`json` stdlib module.
|
||||
|
||||
.. currentmodule:: _pytest.cacheprovider
|
||||
``config.cache`` is an instance of :class:`pytest.Cache`:
|
||||
|
||||
.. automethod:: Cache.get
|
||||
.. automethod:: Cache.set
|
||||
.. automethod:: Cache.makedir
|
||||
.. autoclass:: pytest.Cache()
|
||||
:members:
|
||||
|
||||
|
||||
.. fixture:: capsys
|
||||
|
@ -328,12 +327,10 @@ capsys
|
|||
|
||||
**Tutorial**: :doc:`capture`.
|
||||
|
||||
.. currentmodule:: _pytest.capture
|
||||
|
||||
.. autofunction:: capsys()
|
||||
.. autofunction:: _pytest.capture.capsys()
|
||||
:no-auto-options:
|
||||
|
||||
Returns an instance of :py:class:`CaptureFixture`.
|
||||
Returns an instance of :class:`CaptureFixture[str] <pytest.CaptureFixture>`.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -344,7 +341,7 @@ capsys
|
|||
captured = capsys.readouterr()
|
||||
assert captured.out == "hello\n"
|
||||
|
||||
.. autoclass:: CaptureFixture()
|
||||
.. autoclass:: pytest.CaptureFixture()
|
||||
:members:
|
||||
|
||||
|
||||
|
@ -355,10 +352,10 @@ capsysbinary
|
|||
|
||||
**Tutorial**: :doc:`capture`.
|
||||
|
||||
.. autofunction:: capsysbinary()
|
||||
.. autofunction:: _pytest.capture.capsysbinary()
|
||||
:no-auto-options:
|
||||
|
||||
Returns an instance of :py:class:`CaptureFixture`.
|
||||
Returns an instance of :class:`CaptureFixture[bytes] <pytest.CaptureFixture>`.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -377,10 +374,10 @@ capfd
|
|||
|
||||
**Tutorial**: :doc:`capture`.
|
||||
|
||||
.. autofunction:: capfd()
|
||||
.. autofunction:: _pytest.capture.capfd()
|
||||
:no-auto-options:
|
||||
|
||||
Returns an instance of :py:class:`CaptureFixture`.
|
||||
Returns an instance of :class:`CaptureFixture[str] <pytest.CaptureFixture>`.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -399,10 +396,10 @@ capfdbinary
|
|||
|
||||
**Tutorial**: :doc:`capture`.
|
||||
|
||||
.. autofunction:: capfdbinary()
|
||||
.. autofunction:: _pytest.capture.capfdbinary()
|
||||
:no-auto-options:
|
||||
|
||||
Returns an instance of :py:class:`CaptureFixture`.
|
||||
Returns an instance of :class:`CaptureFixture[bytes] <pytest.CaptureFixture>`.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -443,7 +440,7 @@ request
|
|||
|
||||
The ``request`` fixture is a special fixture providing information of the requesting test function.
|
||||
|
||||
.. autoclass:: _pytest.fixtures.FixtureRequest()
|
||||
.. autoclass:: pytest.FixtureRequest()
|
||||
:members:
|
||||
|
||||
|
||||
|
@ -485,9 +482,9 @@ caplog
|
|||
.. autofunction:: _pytest.logging.caplog()
|
||||
:no-auto-options:
|
||||
|
||||
Returns a :class:`_pytest.logging.LogCaptureFixture` instance.
|
||||
Returns a :class:`pytest.LogCaptureFixture` instance.
|
||||
|
||||
.. autoclass:: _pytest.logging.LogCaptureFixture
|
||||
.. autoclass:: pytest.LogCaptureFixture()
|
||||
:members:
|
||||
|
||||
|
||||
|
@ -514,9 +511,7 @@ pytester
|
|||
|
||||
.. versionadded:: 6.2
|
||||
|
||||
.. currentmodule:: _pytest.pytester
|
||||
|
||||
Provides a :class:`Pytester` instance that can be used to run and test pytest itself.
|
||||
Provides a :class:`~pytest.Pytester` instance that can be used to run and test pytest itself.
|
||||
|
||||
It provides an empty directory where pytest can be executed in isolation, and contains facilities
|
||||
to write tests, configuration files, and match against expected output.
|
||||
|
@ -529,17 +524,17 @@ To use it, include in your topmost ``conftest.py`` file:
|
|||
|
||||
|
||||
|
||||
.. autoclass:: Pytester()
|
||||
.. autoclass:: pytest.Pytester()
|
||||
:members:
|
||||
|
||||
.. autoclass:: RunResult()
|
||||
.. autoclass:: _pytest.pytester.RunResult()
|
||||
:members:
|
||||
|
||||
.. autoclass:: LineMatcher()
|
||||
.. autoclass:: _pytest.pytester.LineMatcher()
|
||||
:members:
|
||||
:special-members: __str__
|
||||
|
||||
.. autoclass:: HookRecorder()
|
||||
.. autoclass:: _pytest.pytester.HookRecorder()
|
||||
:members:
|
||||
|
||||
.. fixture:: testdir
|
||||
|
@ -552,7 +547,7 @@ legacy ``py.path.local`` objects instead when applicable.
|
|||
|
||||
New code should avoid using :fixture:`testdir` in favor of :fixture:`pytester`.
|
||||
|
||||
.. autoclass:: Testdir()
|
||||
.. autoclass:: pytest.Testdir()
|
||||
:members:
|
||||
|
||||
|
||||
|
@ -563,12 +558,10 @@ recwarn
|
|||
|
||||
**Tutorial**: :ref:`assertwarnings`
|
||||
|
||||
.. currentmodule:: _pytest.recwarn
|
||||
|
||||
.. autofunction:: recwarn()
|
||||
.. autofunction:: _pytest.recwarn.recwarn()
|
||||
:no-auto-options:
|
||||
|
||||
.. autoclass:: WarningsRecorder()
|
||||
.. autoclass:: pytest.WarningsRecorder()
|
||||
:members:
|
||||
|
||||
Each recorded warning is an instance of :class:`warnings.WarningMessage`.
|
||||
|
@ -585,13 +578,11 @@ tmp_path
|
|||
|
||||
**Tutorial**: :doc:`tmpdir`
|
||||
|
||||
.. currentmodule:: _pytest.tmpdir
|
||||
|
||||
.. autofunction:: tmp_path()
|
||||
.. autofunction:: _pytest.tmpdir.tmp_path()
|
||||
:no-auto-options:
|
||||
|
||||
|
||||
.. fixture:: tmp_path_factory
|
||||
.. fixture:: _pytest.tmpdir.tmp_path_factory
|
||||
|
||||
tmp_path_factory
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
@ -600,12 +591,9 @@ tmp_path_factory
|
|||
|
||||
.. _`tmp_path_factory factory api`:
|
||||
|
||||
``tmp_path_factory`` instances have the following methods:
|
||||
``tmp_path_factory`` is an instance of :class:`~pytest.TempPathFactory`:
|
||||
|
||||
.. currentmodule:: _pytest.tmpdir
|
||||
|
||||
.. automethod:: TempPathFactory.mktemp
|
||||
.. automethod:: TempPathFactory.getbasetemp
|
||||
.. autoclass:: pytest.TempPathFactory()
|
||||
|
||||
|
||||
.. fixture:: tmpdir
|
||||
|
@ -615,9 +603,7 @@ tmpdir
|
|||
|
||||
**Tutorial**: :doc:`tmpdir`
|
||||
|
||||
.. currentmodule:: _pytest.tmpdir
|
||||
|
||||
.. autofunction:: tmpdir()
|
||||
.. autofunction:: _pytest.tmpdir.tmpdir()
|
||||
:no-auto-options:
|
||||
|
||||
|
||||
|
@ -630,12 +616,9 @@ tmpdir_factory
|
|||
|
||||
.. _`tmpdir factory api`:
|
||||
|
||||
``tmpdir_factory`` instances have the following methods:
|
||||
``tmp_path_factory`` is an instance of :class:`~pytest.TempdirFactory`:
|
||||
|
||||
.. currentmodule:: _pytest.tmpdir
|
||||
|
||||
.. automethod:: TempdirFactory.mktemp
|
||||
.. automethod:: TempdirFactory.getbasetemp
|
||||
.. autoclass:: pytest.TempdirFactory()
|
||||
|
||||
|
||||
.. _`hook-reference`:
|
||||
|
|
|
@ -25,6 +25,7 @@ from _pytest.config import Config
|
|||
from _pytest.config import ExitCode
|
||||
from _pytest.config import hookimpl
|
||||
from _pytest.config.argparsing import Parser
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
from _pytest.main import Session
|
||||
|
@ -53,7 +54,7 @@ Signature: 8a477f597d28d172789f06886806bc55
|
|||
|
||||
|
||||
@final
|
||||
@attr.s
|
||||
@attr.s(init=False)
|
||||
class Cache:
|
||||
_cachedir = attr.ib(type=Path, repr=False)
|
||||
_config = attr.ib(type=Config, repr=False)
|
||||
|
@ -64,26 +65,52 @@ class Cache:
|
|||
# sub-directory under cache-dir for values created by "set"
|
||||
_CACHE_PREFIX_VALUES = "v"
|
||||
|
||||
@classmethod
|
||||
def for_config(cls, config: Config) -> "Cache":
|
||||
cachedir = cls.cache_dir_from_config(config)
|
||||
if config.getoption("cacheclear") and cachedir.is_dir():
|
||||
cls.clear_cache(cachedir)
|
||||
return cls(cachedir, config)
|
||||
def __init__(
|
||||
self, cachedir: Path, config: Config, *, _ispytest: bool = False
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._cachedir = cachedir
|
||||
self._config = config
|
||||
|
||||
@classmethod
|
||||
def clear_cache(cls, cachedir: Path) -> None:
|
||||
"""Clear the sub-directories used to hold cached directories and values."""
|
||||
def for_config(cls, config: Config, *, _ispytest: bool = False) -> "Cache":
|
||||
"""Create the Cache instance for a Config.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
check_ispytest(_ispytest)
|
||||
cachedir = cls.cache_dir_from_config(config, _ispytest=True)
|
||||
if config.getoption("cacheclear") and cachedir.is_dir():
|
||||
cls.clear_cache(cachedir, _ispytest=True)
|
||||
return cls(cachedir, config, _ispytest=True)
|
||||
|
||||
@classmethod
|
||||
def clear_cache(cls, cachedir: Path, _ispytest: bool = False) -> None:
|
||||
"""Clear the sub-directories used to hold cached directories and values.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
check_ispytest(_ispytest)
|
||||
for prefix in (cls._CACHE_PREFIX_DIRS, cls._CACHE_PREFIX_VALUES):
|
||||
d = cachedir / prefix
|
||||
if d.is_dir():
|
||||
rm_rf(d)
|
||||
|
||||
@staticmethod
|
||||
def cache_dir_from_config(config: Config) -> Path:
|
||||
def cache_dir_from_config(config: Config, *, _ispytest: bool = False) -> Path:
|
||||
"""Get the path to the cache directory for a Config.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
check_ispytest(_ispytest)
|
||||
return resolve_from_str(config.getini("cache_dir"), config.rootpath)
|
||||
|
||||
def warn(self, fmt: str, **args: object) -> None:
|
||||
def warn(self, fmt: str, *, _ispytest: bool = False, **args: object) -> None:
|
||||
"""Issue a cache warning.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
check_ispytest(_ispytest)
|
||||
import warnings
|
||||
from _pytest.warning_types import PytestCacheWarning
|
||||
|
||||
|
@ -152,7 +179,7 @@ class Cache:
|
|||
cache_dir_exists_already = self._cachedir.exists()
|
||||
path.parent.mkdir(exist_ok=True, parents=True)
|
||||
except OSError:
|
||||
self.warn("could not create cache path {path}", path=path)
|
||||
self.warn("could not create cache path {path}", path=path, _ispytest=True)
|
||||
return
|
||||
if not cache_dir_exists_already:
|
||||
self._ensure_supporting_files()
|
||||
|
@ -160,7 +187,7 @@ class Cache:
|
|||
try:
|
||||
f = path.open("w")
|
||||
except OSError:
|
||||
self.warn("cache could not write path {path}", path=path)
|
||||
self.warn("cache could not write path {path}", path=path, _ispytest=True)
|
||||
else:
|
||||
with f:
|
||||
f.write(data)
|
||||
|
@ -469,7 +496,7 @@ def pytest_cmdline_main(config: Config) -> Optional[Union[int, ExitCode]]:
|
|||
|
||||
@hookimpl(tryfirst=True)
|
||||
def pytest_configure(config: Config) -> None:
|
||||
config.cache = Cache.for_config(config)
|
||||
config.cache = Cache.for_config(config, _ispytest=True)
|
||||
config.pluginmanager.register(LFPlugin(config), "lfplugin")
|
||||
config.pluginmanager.register(NFPlugin(config), "nfplugin")
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ from _pytest.compat import final
|
|||
from _pytest.config import Config
|
||||
from _pytest.config import hookimpl
|
||||
from _pytest.config.argparsing import Parser
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.fixtures import SubRequest
|
||||
from _pytest.nodes import Collector
|
||||
|
@ -826,10 +827,13 @@ class CaptureManager:
|
|||
|
||||
|
||||
class CaptureFixture(Generic[AnyStr]):
|
||||
"""Object returned by the :py:func:`capsys`, :py:func:`capsysbinary`,
|
||||
:py:func:`capfd` and :py:func:`capfdbinary` fixtures."""
|
||||
"""Object returned by the :fixture:`capsys`, :fixture:`capsysbinary`,
|
||||
:fixture:`capfd` and :fixture:`capfdbinary` fixtures."""
|
||||
|
||||
def __init__(self, captureclass, request: SubRequest) -> None:
|
||||
def __init__(
|
||||
self, captureclass, request: SubRequest, *, _ispytest: bool = False
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self.captureclass = captureclass
|
||||
self.request = request
|
||||
self._capture: Optional[MultiCapture[AnyStr]] = None
|
||||
|
@ -904,7 +908,7 @@ def capsys(request: SubRequest) -> Generator[CaptureFixture[str], None, None]:
|
|||
``out`` and ``err`` will be ``text`` objects.
|
||||
"""
|
||||
capman = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capture_fixture = CaptureFixture[str](SysCapture, request)
|
||||
capture_fixture = CaptureFixture[str](SysCapture, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
yield capture_fixture
|
||||
|
@ -921,7 +925,7 @@ def capsysbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None,
|
|||
``out`` and ``err`` will be ``bytes`` objects.
|
||||
"""
|
||||
capman = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capture_fixture = CaptureFixture[bytes](SysCaptureBinary, request)
|
||||
capture_fixture = CaptureFixture[bytes](SysCaptureBinary, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
yield capture_fixture
|
||||
|
@ -938,7 +942,7 @@ def capfd(request: SubRequest) -> Generator[CaptureFixture[str], None, None]:
|
|||
``out`` and ``err`` will be ``text`` objects.
|
||||
"""
|
||||
capman = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capture_fixture = CaptureFixture[str](FDCapture, request)
|
||||
capture_fixture = CaptureFixture[str](FDCapture, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
yield capture_fixture
|
||||
|
@ -955,7 +959,7 @@ def capfdbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None, N
|
|||
``out`` and ``err`` will be ``byte`` objects.
|
||||
"""
|
||||
capman = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capture_fixture = CaptureFixture[bytes](FDCaptureBinary, request)
|
||||
capture_fixture = CaptureFixture[bytes](FDCaptureBinary, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
yield capture_fixture
|
||||
|
|
|
@ -256,6 +256,7 @@ default_plugins = essential_plugins + (
|
|||
|
||||
builtin_plugins = set(default_plugins)
|
||||
builtin_plugins.add("pytester")
|
||||
builtin_plugins.add("pytester_assertions")
|
||||
|
||||
|
||||
def get_config(
|
||||
|
|
|
@ -8,6 +8,8 @@ All constants defined in this module should be either instances of
|
|||
:class:`PytestWarning`, or :class:`UnformattedWarning`
|
||||
in case of warnings which need to format their messages.
|
||||
"""
|
||||
from warnings import warn
|
||||
|
||||
from _pytest.warning_types import PytestDeprecationWarning
|
||||
from _pytest.warning_types import UnformattedWarning
|
||||
|
||||
|
@ -59,3 +61,27 @@ FSCOLLECTOR_GETHOOKPROXY_ISINITPATH = PytestDeprecationWarning(
|
|||
STRICT_OPTION = PytestDeprecationWarning(
|
||||
"The --strict option is deprecated, use --strict-markers instead."
|
||||
)
|
||||
|
||||
PRIVATE = PytestDeprecationWarning("A private pytest class or function was used.")
|
||||
|
||||
|
||||
# You want to make some `__init__` or function "private".
|
||||
#
|
||||
# def my_private_function(some, args):
|
||||
# ...
|
||||
#
|
||||
# Do this:
|
||||
#
|
||||
# def my_private_function(some, args, *, _ispytest: bool = False):
|
||||
# check_ispytest(_ispytest)
|
||||
# ...
|
||||
#
|
||||
# Change all internal/allowed calls to
|
||||
#
|
||||
# my_private_function(some, args, _ispytest=True)
|
||||
#
|
||||
# All other calls will get the default _ispytest=False and trigger
|
||||
# the warning (possibly error in the future).
|
||||
def check_ispytest(ispytest: bool) -> None:
|
||||
if not ispytest:
|
||||
warn(PRIVATE, stacklevel=3)
|
||||
|
|
|
@ -563,7 +563,7 @@ def _setup_fixtures(doctest_item: DoctestItem) -> FixtureRequest:
|
|||
doctest_item._fixtureinfo = fm.getfixtureinfo( # type: ignore[attr-defined]
|
||||
node=doctest_item, func=func, cls=None, funcargs=False
|
||||
)
|
||||
fixture_request = FixtureRequest(doctest_item)
|
||||
fixture_request = FixtureRequest(doctest_item, _ispytest=True)
|
||||
fixture_request._fillfixtures()
|
||||
return fixture_request
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ from _pytest.compat import safe_getattr
|
|||
from _pytest.config import _PluggyPlugin
|
||||
from _pytest.config import Config
|
||||
from _pytest.config.argparsing import Parser
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.deprecated import FILLFUNCARGS
|
||||
from _pytest.deprecated import YIELD_FIXTURE
|
||||
from _pytest.mark import Mark
|
||||
|
@ -367,7 +368,7 @@ def _fill_fixtures_impl(function: "Function") -> None:
|
|||
assert function.parent is not None
|
||||
fi = fm.getfixtureinfo(function.parent, function.obj, None)
|
||||
function._fixtureinfo = fi
|
||||
request = function._request = FixtureRequest(function)
|
||||
request = function._request = FixtureRequest(function, _ispytest=True)
|
||||
request._fillfixtures()
|
||||
# Prune out funcargs for jstests.
|
||||
newfuncargs = {}
|
||||
|
@ -429,7 +430,8 @@ class FixtureRequest:
|
|||
indirectly.
|
||||
"""
|
||||
|
||||
def __init__(self, pyfuncitem) -> None:
|
||||
def __init__(self, pyfuncitem, *, _ispytest: bool = False) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._pyfuncitem = pyfuncitem
|
||||
#: Fixture for which this request is being performed.
|
||||
self.fixturename: Optional[str] = None
|
||||
|
@ -674,7 +676,9 @@ class FixtureRequest:
|
|||
if paramscopenum is not None:
|
||||
scope = scopes[paramscopenum]
|
||||
|
||||
subrequest = SubRequest(self, scope, param, param_index, fixturedef)
|
||||
subrequest = SubRequest(
|
||||
self, scope, param, param_index, fixturedef, _ispytest=True
|
||||
)
|
||||
|
||||
# Check if a higher-level scoped fixture accesses a lower level one.
|
||||
subrequest._check_scope(argname, self.scope, scope)
|
||||
|
@ -751,7 +755,10 @@ class SubRequest(FixtureRequest):
|
|||
param,
|
||||
param_index: int,
|
||||
fixturedef: "FixtureDef[object]",
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._parent_request = request
|
||||
self.fixturename = fixturedef.argname
|
||||
if param is not NOTSET:
|
||||
|
@ -769,6 +776,8 @@ class SubRequest(FixtureRequest):
|
|||
return f"<SubRequest {self.fixturename!r} for {self._pyfuncitem!r}>"
|
||||
|
||||
def addfinalizer(self, finalizer: Callable[[], object]) -> None:
|
||||
"""Add finalizer/teardown function to be called after the last test
|
||||
within the requesting test context finished execution."""
|
||||
self._fixturedef.addfinalizer(finalizer)
|
||||
|
||||
def _schedule_finalizers(
|
||||
|
|
|
@ -27,6 +27,7 @@ from _pytest.config import create_terminal_writer
|
|||
from _pytest.config import hookimpl
|
||||
from _pytest.config import UsageError
|
||||
from _pytest.config.argparsing import Parser
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
from _pytest.main import Session
|
||||
|
@ -346,7 +347,8 @@ class LogCaptureHandler(logging.StreamHandler):
|
|||
class LogCaptureFixture:
|
||||
"""Provides access and control of log capturing."""
|
||||
|
||||
def __init__(self, item: nodes.Node) -> None:
|
||||
def __init__(self, item: nodes.Node, *, _ispytest: bool = False) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._item = item
|
||||
self._initial_handler_level: Optional[int] = None
|
||||
# Dict of log name -> log level.
|
||||
|
@ -482,7 +484,7 @@ def caplog(request: FixtureRequest) -> Generator[LogCaptureFixture, None, None]:
|
|||
* caplog.record_tuples -> list of (logger_name, level, message) tuples
|
||||
* caplog.clear() -> clear captured records and formatted log output string
|
||||
"""
|
||||
result = LogCaptureFixture(request.node)
|
||||
result = LogCaptureFixture(request.node, _ispytest=True)
|
||||
yield result
|
||||
result._finalize()
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
"""(Disabled by default) support for testing pytest and pytest plugins."""
|
||||
"""(Disabled by default) support for testing pytest and pytest plugins.
|
||||
|
||||
PYTEST_DONT_REWRITE
|
||||
"""
|
||||
import collections.abc
|
||||
import contextlib
|
||||
import gc
|
||||
|
@ -45,6 +48,7 @@ from _pytest.config import hookimpl
|
|||
from _pytest.config import main
|
||||
from _pytest.config import PytestPluginManager
|
||||
from _pytest.config.argparsing import Parser
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
from _pytest.main import Session
|
||||
|
@ -66,6 +70,9 @@ if TYPE_CHECKING:
|
|||
import pexpect
|
||||
|
||||
|
||||
pytest_plugins = ["pytester_assertions"]
|
||||
|
||||
|
||||
IGNORE_PAM = [ # filenames added when obtaining details about the current user
|
||||
"/var/lib/sss/mc/passwd"
|
||||
]
|
||||
|
@ -408,16 +415,12 @@ class HookRecorder:
|
|||
|
||||
def assertoutcome(self, passed: int = 0, skipped: int = 0, failed: int = 0) -> None:
|
||||
__tracebackhide__ = True
|
||||
from _pytest.pytester_assertions import assertoutcome
|
||||
|
||||
outcomes = self.listoutcomes()
|
||||
realpassed, realskipped, realfailed = outcomes
|
||||
obtained = {
|
||||
"passed": len(realpassed),
|
||||
"skipped": len(realskipped),
|
||||
"failed": len(realfailed),
|
||||
}
|
||||
expected = {"passed": passed, "skipped": skipped, "failed": failed}
|
||||
assert obtained == expected, outcomes
|
||||
assertoutcome(
|
||||
outcomes, passed=passed, skipped=skipped, failed=failed,
|
||||
)
|
||||
|
||||
def clear(self) -> None:
|
||||
self.calls[:] = []
|
||||
|
@ -452,7 +455,7 @@ def pytester(request: FixtureRequest, tmp_path_factory: TempPathFactory) -> "Pyt
|
|||
It is particularly useful for testing plugins. It is similar to the :fixture:`tmp_path`
|
||||
fixture but provides methods which aid in testing pytest itself.
|
||||
"""
|
||||
return Pytester(request, tmp_path_factory)
|
||||
return Pytester(request, tmp_path_factory, _ispytest=True)
|
||||
|
||||
|
||||
@fixture
|
||||
|
@ -463,7 +466,7 @@ def testdir(pytester: "Pytester") -> "Testdir":
|
|||
|
||||
New code should avoid using :fixture:`testdir` in favor of :fixture:`pytester`.
|
||||
"""
|
||||
return Testdir(pytester)
|
||||
return Testdir(pytester, _ispytest=True)
|
||||
|
||||
|
||||
@fixture
|
||||
|
@ -574,25 +577,18 @@ class RunResult:
|
|||
"""Assert that the specified outcomes appear with the respective
|
||||
numbers (0 means it didn't occur) in the text output from a test run."""
|
||||
__tracebackhide__ = True
|
||||
from _pytest.pytester_assertions import assert_outcomes
|
||||
|
||||
d = self.parseoutcomes()
|
||||
obtained = {
|
||||
"passed": d.get("passed", 0),
|
||||
"skipped": d.get("skipped", 0),
|
||||
"failed": d.get("failed", 0),
|
||||
"errors": d.get("errors", 0),
|
||||
"xpassed": d.get("xpassed", 0),
|
||||
"xfailed": d.get("xfailed", 0),
|
||||
}
|
||||
expected = {
|
||||
"passed": passed,
|
||||
"skipped": skipped,
|
||||
"failed": failed,
|
||||
"errors": errors,
|
||||
"xpassed": xpassed,
|
||||
"xfailed": xfailed,
|
||||
}
|
||||
assert obtained == expected
|
||||
outcomes = self.parseoutcomes()
|
||||
assert_outcomes(
|
||||
outcomes,
|
||||
passed=passed,
|
||||
skipped=skipped,
|
||||
failed=failed,
|
||||
errors=errors,
|
||||
xpassed=xpassed,
|
||||
xfailed=xfailed,
|
||||
)
|
||||
|
||||
|
||||
class CwdSnapshot:
|
||||
|
@ -653,8 +649,13 @@ class Pytester:
|
|||
pass
|
||||
|
||||
def __init__(
|
||||
self, request: FixtureRequest, tmp_path_factory: TempPathFactory
|
||||
self,
|
||||
request: FixtureRequest,
|
||||
tmp_path_factory: TempPathFactory,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._request = request
|
||||
self._mod_collections: WeakKeyDictionary[
|
||||
Collector, List[Union[Item, Collector]]
|
||||
|
@ -1485,7 +1486,7 @@ class LineComp:
|
|||
|
||||
|
||||
@final
|
||||
@attr.s(repr=False, str=False)
|
||||
@attr.s(repr=False, str=False, init=False)
|
||||
class Testdir:
|
||||
"""
|
||||
Similar to :class:`Pytester`, but this class works with legacy py.path.local objects instead.
|
||||
|
@ -1500,7 +1501,9 @@ class Testdir:
|
|||
TimeoutExpired = Pytester.TimeoutExpired
|
||||
Session = Pytester.Session
|
||||
|
||||
_pytester: Pytester = attr.ib()
|
||||
def __init__(self, pytester: Pytester, *, _ispytest: bool = False) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._pytester = pytester
|
||||
|
||||
@property
|
||||
def tmpdir(self) -> py.path.local:
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
"""Helper plugin for pytester; should not be loaded on its own."""
|
||||
# This plugin contains assertions used by pytester. pytester cannot
|
||||
# contain them itself, since it is imported by the `pytest` module,
|
||||
# hence cannot be subject to assertion rewriting, which requires a
|
||||
# module to not be already imported.
|
||||
from typing import Dict
|
||||
from typing import Sequence
|
||||
from typing import Tuple
|
||||
from typing import Union
|
||||
|
||||
from _pytest.reports import CollectReport
|
||||
from _pytest.reports import TestReport
|
||||
|
||||
|
||||
def assertoutcome(
|
||||
outcomes: Tuple[
|
||||
Sequence[TestReport],
|
||||
Sequence[Union[CollectReport, TestReport]],
|
||||
Sequence[Union[CollectReport, TestReport]],
|
||||
],
|
||||
passed: int = 0,
|
||||
skipped: int = 0,
|
||||
failed: int = 0,
|
||||
) -> None:
|
||||
__tracebackhide__ = True
|
||||
|
||||
realpassed, realskipped, realfailed = outcomes
|
||||
obtained = {
|
||||
"passed": len(realpassed),
|
||||
"skipped": len(realskipped),
|
||||
"failed": len(realfailed),
|
||||
}
|
||||
expected = {"passed": passed, "skipped": skipped, "failed": failed}
|
||||
assert obtained == expected, outcomes
|
||||
|
||||
|
||||
def assert_outcomes(
|
||||
outcomes: Dict[str, int],
|
||||
passed: int = 0,
|
||||
skipped: int = 0,
|
||||
failed: int = 0,
|
||||
errors: int = 0,
|
||||
xpassed: int = 0,
|
||||
xfailed: int = 0,
|
||||
) -> None:
|
||||
"""Assert that the specified outcomes appear with the respective
|
||||
numbers (0 means it didn't occur) in the text output from a test run."""
|
||||
__tracebackhide__ = True
|
||||
|
||||
obtained = {
|
||||
"passed": outcomes.get("passed", 0),
|
||||
"skipped": outcomes.get("skipped", 0),
|
||||
"failed": outcomes.get("failed", 0),
|
||||
"errors": outcomes.get("errors", 0),
|
||||
"xpassed": outcomes.get("xpassed", 0),
|
||||
"xfailed": outcomes.get("xfailed", 0),
|
||||
}
|
||||
expected = {
|
||||
"passed": passed,
|
||||
"skipped": skipped,
|
||||
"failed": failed,
|
||||
"errors": errors,
|
||||
"xpassed": xpassed,
|
||||
"xfailed": xfailed,
|
||||
}
|
||||
assert obtained == expected
|
|
@ -1620,7 +1620,7 @@ class Function(PyobjMixin, nodes.Item):
|
|||
|
||||
def _initrequest(self) -> None:
|
||||
self.funcargs: Dict[str, object] = {}
|
||||
self._request = fixtures.FixtureRequest(self)
|
||||
self._request = fixtures.FixtureRequest(self, _ispytest=True)
|
||||
|
||||
@property
|
||||
def function(self):
|
||||
|
|
|
@ -16,6 +16,7 @@ from typing import TypeVar
|
|||
from typing import Union
|
||||
|
||||
from _pytest.compat import final
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.outcomes import fail
|
||||
|
||||
|
@ -30,7 +31,7 @@ def recwarn() -> Generator["WarningsRecorder", None, None]:
|
|||
See http://docs.python.org/library/warnings.html for information
|
||||
on warning categories.
|
||||
"""
|
||||
wrec = WarningsRecorder()
|
||||
wrec = WarningsRecorder(_ispytest=True)
|
||||
with wrec:
|
||||
warnings.simplefilter("default")
|
||||
yield wrec
|
||||
|
@ -144,14 +145,14 @@ def warns(
|
|||
msg += ", ".join(sorted(kwargs))
|
||||
msg += "\nUse context-manager form instead?"
|
||||
raise TypeError(msg)
|
||||
return WarningsChecker(expected_warning, match_expr=match)
|
||||
return WarningsChecker(expected_warning, match_expr=match, _ispytest=True)
|
||||
else:
|
||||
func = args[0]
|
||||
if not callable(func):
|
||||
raise TypeError(
|
||||
"{!r} object (type: {}) must be callable".format(func, type(func))
|
||||
)
|
||||
with WarningsChecker(expected_warning):
|
||||
with WarningsChecker(expected_warning, _ispytest=True):
|
||||
return func(*args[1:], **kwargs)
|
||||
|
||||
|
||||
|
@ -161,7 +162,8 @@ class WarningsRecorder(warnings.catch_warnings):
|
|||
Adapted from `warnings.catch_warnings`.
|
||||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, *, _ispytest: bool = False) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
# Type ignored due to the way typeshed handles warnings.catch_warnings.
|
||||
super().__init__(record=True) # type: ignore[call-arg]
|
||||
self._entered = False
|
||||
|
@ -234,8 +236,11 @@ class WarningsChecker(WarningsRecorder):
|
|||
Union[Type[Warning], Tuple[Type[Warning], ...]]
|
||||
] = None,
|
||||
match_expr: Optional[Union[str, Pattern[str]]] = None,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
super().__init__()
|
||||
check_ispytest(_ispytest)
|
||||
super().__init__(_ispytest=True)
|
||||
|
||||
msg = "exceptions must be derived from Warning, not %s"
|
||||
if expected_warning is None:
|
||||
|
|
|
@ -14,37 +14,56 @@ from .pathlib import make_numbered_dir
|
|||
from .pathlib import make_numbered_dir_with_cleanup
|
||||
from _pytest.compat import final
|
||||
from _pytest.config import Config
|
||||
from _pytest.deprecated import check_ispytest
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
from _pytest.monkeypatch import MonkeyPatch
|
||||
|
||||
|
||||
@final
|
||||
@attr.s
|
||||
@attr.s(init=False)
|
||||
class TempPathFactory:
|
||||
"""Factory for temporary directories under the common base temp directory.
|
||||
|
||||
The base directory can be configured using the ``--basetemp`` option.
|
||||
"""
|
||||
|
||||
_given_basetemp = attr.ib(
|
||||
type=Optional[Path],
|
||||
# Use os.path.abspath() to get absolute path instead of resolve() as it
|
||||
# does not work the same in all platforms (see #4427).
|
||||
# Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012).
|
||||
# Ignore type because of https://github.com/python/mypy/issues/6172.
|
||||
converter=attr.converters.optional(
|
||||
lambda p: Path(os.path.abspath(str(p))) # type: ignore
|
||||
),
|
||||
)
|
||||
_given_basetemp = attr.ib(type=Optional[Path])
|
||||
_trace = attr.ib()
|
||||
_basetemp = attr.ib(type=Optional[Path], default=None)
|
||||
_basetemp = attr.ib(type=Optional[Path])
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
given_basetemp: Optional[Path],
|
||||
trace,
|
||||
basetemp: Optional[Path] = None,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
if given_basetemp is None:
|
||||
self._given_basetemp = None
|
||||
else:
|
||||
# Use os.path.abspath() to get absolute path instead of resolve() as it
|
||||
# does not work the same in all platforms (see #4427).
|
||||
# Path.absolute() exists, but it is not public (see https://bugs.python.org/issue25012).
|
||||
self._given_basetemp = Path(os.path.abspath(str(given_basetemp)))
|
||||
self._trace = trace
|
||||
self._basetemp = basetemp
|
||||
|
||||
@classmethod
|
||||
def from_config(cls, config: Config) -> "TempPathFactory":
|
||||
"""Create a factory according to pytest configuration."""
|
||||
def from_config(
|
||||
cls, config: Config, *, _ispytest: bool = False,
|
||||
) -> "TempPathFactory":
|
||||
"""Create a factory according to pytest configuration.
|
||||
|
||||
:meta private:
|
||||
"""
|
||||
check_ispytest(_ispytest)
|
||||
return cls(
|
||||
given_basetemp=config.option.basetemp, trace=config.trace.get("tmpdir")
|
||||
given_basetemp=config.option.basetemp,
|
||||
trace=config.trace.get("tmpdir"),
|
||||
_ispytest=True,
|
||||
)
|
||||
|
||||
def _ensure_relative_to_basetemp(self, basename: str) -> str:
|
||||
|
@ -104,13 +123,19 @@ class TempPathFactory:
|
|||
|
||||
|
||||
@final
|
||||
@attr.s
|
||||
@attr.s(init=False)
|
||||
class TempdirFactory:
|
||||
"""Backward comptibility wrapper that implements :class:``py.path.local``
|
||||
for :class:``TempPathFactory``."""
|
||||
|
||||
_tmppath_factory = attr.ib(type=TempPathFactory)
|
||||
|
||||
def __init__(
|
||||
self, tmppath_factory: TempPathFactory, *, _ispytest: bool = False
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self._tmppath_factory = tmppath_factory
|
||||
|
||||
def mktemp(self, basename: str, numbered: bool = True) -> py.path.local:
|
||||
"""Same as :meth:`TempPathFactory.mktemp`, but returns a ``py.path.local`` object."""
|
||||
return py.path.local(self._tmppath_factory.mktemp(basename, numbered).resolve())
|
||||
|
@ -139,8 +164,8 @@ def pytest_configure(config: Config) -> None:
|
|||
to the tmpdir_factory session fixture.
|
||||
"""
|
||||
mp = MonkeyPatch()
|
||||
tmppath_handler = TempPathFactory.from_config(config)
|
||||
t = TempdirFactory(tmppath_handler)
|
||||
tmppath_handler = TempPathFactory.from_config(config, _ispytest=True)
|
||||
t = TempdirFactory(tmppath_handler, _ispytest=True)
|
||||
config._cleanup.append(mp.undo)
|
||||
mp.setattr(config, "_tmp_path_factory", tmppath_handler, raising=False)
|
||||
mp.setattr(config, "_tmpdirhandler", t, raising=False)
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
from . import collect
|
||||
from _pytest import __version__
|
||||
from _pytest.assertion import register_assert_rewrite
|
||||
from _pytest.cacheprovider import Cache
|
||||
from _pytest.capture import CaptureFixture
|
||||
from _pytest.config import cmdline
|
||||
from _pytest.config import console_main
|
||||
from _pytest.config import ExitCode
|
||||
|
@ -14,8 +16,10 @@ from _pytest.debugging import pytestPDB as __pytestPDB
|
|||
from _pytest.fixtures import _fillfuncargs
|
||||
from _pytest.fixtures import fixture
|
||||
from _pytest.fixtures import FixtureLookupError
|
||||
from _pytest.fixtures import FixtureRequest
|
||||
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_GEN as mark
|
||||
from _pytest.mark import param
|
||||
|
@ -28,6 +32,8 @@ from _pytest.outcomes import fail
|
|||
from _pytest.outcomes import importorskip
|
||||
from _pytest.outcomes import skip
|
||||
from _pytest.outcomes import xfail
|
||||
from _pytest.pytester import Pytester
|
||||
from _pytest.pytester import Testdir
|
||||
from _pytest.python import Class
|
||||
from _pytest.python import Function
|
||||
from _pytest.python import Instance
|
||||
|
@ -36,7 +42,10 @@ from _pytest.python import Package
|
|||
from _pytest.python_api import approx
|
||||
from _pytest.python_api import raises
|
||||
from _pytest.recwarn import deprecated_call
|
||||
from _pytest.recwarn import WarningsRecorder
|
||||
from _pytest.recwarn import warns
|
||||
from _pytest.tmpdir import TempdirFactory
|
||||
from _pytest.tmpdir import TempPathFactory
|
||||
from _pytest.warning_types import PytestAssertRewriteWarning
|
||||
from _pytest.warning_types import PytestCacheWarning
|
||||
from _pytest.warning_types import PytestCollectionWarning
|
||||
|
@ -53,6 +62,8 @@ __all__ = [
|
|||
"__version__",
|
||||
"_fillfuncargs",
|
||||
"approx",
|
||||
"Cache",
|
||||
"CaptureFixture",
|
||||
"Class",
|
||||
"cmdline",
|
||||
"collect",
|
||||
|
@ -65,6 +76,7 @@ __all__ = [
|
|||
"File",
|
||||
"fixture",
|
||||
"FixtureLookupError",
|
||||
"FixtureRequest",
|
||||
"freeze_includes",
|
||||
"Function",
|
||||
"hookimpl",
|
||||
|
@ -72,6 +84,7 @@ __all__ = [
|
|||
"importorskip",
|
||||
"Instance",
|
||||
"Item",
|
||||
"LogCaptureFixture",
|
||||
"main",
|
||||
"mark",
|
||||
"Module",
|
||||
|
@ -84,6 +97,7 @@ __all__ = [
|
|||
"PytestConfigWarning",
|
||||
"PytestDeprecationWarning",
|
||||
"PytestExperimentalApiWarning",
|
||||
"Pytester",
|
||||
"PytestUnhandledCoroutineWarning",
|
||||
"PytestUnknownMarkWarning",
|
||||
"PytestWarning",
|
||||
|
@ -92,7 +106,11 @@ __all__ = [
|
|||
"Session",
|
||||
"set_trace",
|
||||
"skip",
|
||||
"TempPathFactory",
|
||||
"Testdir",
|
||||
"TempdirFactory",
|
||||
"UsageError",
|
||||
"WarningsRecorder",
|
||||
"warns",
|
||||
"xfail",
|
||||
"yield_fixture",
|
||||
|
|
|
@ -123,3 +123,17 @@ def test_yield_fixture_is_deprecated() -> None:
|
|||
@pytest.yield_fixture
|
||||
def fix():
|
||||
assert False
|
||||
|
||||
|
||||
def test_private_is_deprecated() -> None:
|
||||
class PrivateInit:
|
||||
def __init__(self, foo: int, *, _ispytest: bool = False) -> None:
|
||||
deprecated.check_ispytest(_ispytest)
|
||||
|
||||
with pytest.warns(
|
||||
pytest.PytestDeprecationWarning, match="private pytest class or function"
|
||||
):
|
||||
PrivateInit(10)
|
||||
|
||||
# Doesn't warn.
|
||||
PrivateInit(10, _ispytest=True)
|
||||
|
|
|
@ -621,7 +621,7 @@ class TestRequestBasic:
|
|||
def test_func(something): pass
|
||||
"""
|
||||
)
|
||||
req = fixtures.FixtureRequest(item)
|
||||
req = fixtures.FixtureRequest(item, _ispytest=True)
|
||||
assert req.function == item.obj
|
||||
assert req.keywords == item.keywords
|
||||
assert hasattr(req.module, "test_func")
|
||||
|
@ -661,7 +661,9 @@ class TestRequestBasic:
|
|||
)
|
||||
(item1,) = testdir.genitems([modcol])
|
||||
assert item1.name == "test_method"
|
||||
arg2fixturedefs = fixtures.FixtureRequest(item1)._arg2fixturedefs
|
||||
arg2fixturedefs = fixtures.FixtureRequest(
|
||||
item1, _ispytest=True
|
||||
)._arg2fixturedefs
|
||||
assert len(arg2fixturedefs) == 1
|
||||
assert arg2fixturedefs["something"][0].argname == "something"
|
||||
|
||||
|
@ -910,7 +912,7 @@ class TestRequestBasic:
|
|||
def test_request_getmodulepath(self, testdir):
|
||||
modcol = testdir.getmodulecol("def test_somefunc(): pass")
|
||||
(item,) = testdir.genitems([modcol])
|
||||
req = fixtures.FixtureRequest(item)
|
||||
req = fixtures.FixtureRequest(item, _ispytest=True)
|
||||
assert req.fspath == modcol.fspath
|
||||
|
||||
def test_request_fixturenames(self, testdir):
|
||||
|
@ -1052,7 +1054,7 @@ class TestRequestMarking:
|
|||
pass
|
||||
"""
|
||||
)
|
||||
req1 = fixtures.FixtureRequest(item1)
|
||||
req1 = fixtures.FixtureRequest(item1, _ispytest=True)
|
||||
assert "xfail" not in item1.keywords
|
||||
req1.applymarker(pytest.mark.xfail)
|
||||
assert "xfail" in item1.keywords
|
||||
|
@ -3882,7 +3884,7 @@ class TestScopeOrdering:
|
|||
"""
|
||||
)
|
||||
items, _ = testdir.inline_genitems()
|
||||
request = FixtureRequest(items[0])
|
||||
request = FixtureRequest(items[0], _ispytest=True)
|
||||
assert request.fixturenames == "m1 f1".split()
|
||||
|
||||
def test_func_closure_with_native_fixtures(self, testdir, monkeypatch) -> None:
|
||||
|
@ -3928,7 +3930,7 @@ class TestScopeOrdering:
|
|||
"""
|
||||
)
|
||||
items, _ = testdir.inline_genitems()
|
||||
request = FixtureRequest(items[0])
|
||||
request = FixtureRequest(items[0], _ispytest=True)
|
||||
# order of fixtures based on their scope and position in the parameter list
|
||||
assert (
|
||||
request.fixturenames == "s1 my_tmpdir_factory p1 m1 f1 f2 my_tmpdir".split()
|
||||
|
@ -3954,7 +3956,7 @@ class TestScopeOrdering:
|
|||
"""
|
||||
)
|
||||
items, _ = testdir.inline_genitems()
|
||||
request = FixtureRequest(items[0])
|
||||
request = FixtureRequest(items[0], _ispytest=True)
|
||||
assert request.fixturenames == "m1 f1".split()
|
||||
|
||||
def test_func_closure_scopes_reordered(self, testdir):
|
||||
|
@ -3987,7 +3989,7 @@ class TestScopeOrdering:
|
|||
"""
|
||||
)
|
||||
items, _ = testdir.inline_genitems()
|
||||
request = FixtureRequest(items[0])
|
||||
request = FixtureRequest(items[0], _ispytest=True)
|
||||
assert request.fixturenames == "s1 m1 c1 f2 f1".split()
|
||||
|
||||
def test_func_closure_same_scope_closer_root_first(self, testdir):
|
||||
|
@ -4027,7 +4029,7 @@ class TestScopeOrdering:
|
|||
}
|
||||
)
|
||||
items, _ = testdir.inline_genitems()
|
||||
request = FixtureRequest(items[0])
|
||||
request = FixtureRequest(items[0], _ispytest=True)
|
||||
assert request.fixturenames == "p_sub m_conf m_sub m_test f1".split()
|
||||
|
||||
def test_func_closure_all_scopes_complex(self, testdir):
|
||||
|
@ -4071,7 +4073,7 @@ class TestScopeOrdering:
|
|||
"""
|
||||
)
|
||||
items, _ = testdir.inline_genitems()
|
||||
request = FixtureRequest(items[0])
|
||||
request = FixtureRequest(items[0], _ispytest=True)
|
||||
assert request.fixturenames == "s1 p1 m1 m2 c1 f2 f1".split()
|
||||
|
||||
def test_multiple_packages(self, testdir):
|
||||
|
|
|
@ -1156,7 +1156,7 @@ def test_gitignore(testdir):
|
|||
from _pytest.cacheprovider import Cache
|
||||
|
||||
config = testdir.parseconfig()
|
||||
cache = Cache.for_config(config)
|
||||
cache = Cache.for_config(config, _ispytest=True)
|
||||
cache.set("foo", "bar")
|
||||
msg = "# Created by pytest automatically.\n*\n"
|
||||
gitignore_path = cache._cachedir.joinpath(".gitignore")
|
||||
|
@ -1178,7 +1178,7 @@ def test_does_not_create_boilerplate_in_existing_dirs(testdir):
|
|||
"""
|
||||
)
|
||||
config = testdir.parseconfig()
|
||||
cache = Cache.for_config(config)
|
||||
cache = Cache.for_config(config, _ispytest=True)
|
||||
cache.set("foo", "bar")
|
||||
|
||||
assert os.path.isdir("v") # cache contents
|
||||
|
@ -1192,7 +1192,7 @@ def test_cachedir_tag(testdir):
|
|||
from _pytest.cacheprovider import CACHEDIR_TAG_CONTENT
|
||||
|
||||
config = testdir.parseconfig()
|
||||
cache = Cache.for_config(config)
|
||||
cache = Cache.for_config(config, _ispytest=True)
|
||||
cache.set("foo", "bar")
|
||||
cachedir_tag_path = cache._cachedir.joinpath("CACHEDIR.TAG")
|
||||
assert cachedir_tag_path.read_bytes() == CACHEDIR_TAG_CONTENT
|
||||
|
|
|
@ -29,7 +29,7 @@ def test_recwarn_functional(pytester: Pytester) -> None:
|
|||
|
||||
class TestWarningsRecorderChecker:
|
||||
def test_recording(self) -> None:
|
||||
rec = WarningsRecorder()
|
||||
rec = WarningsRecorder(_ispytest=True)
|
||||
with rec:
|
||||
assert not rec.list
|
||||
warnings.warn_explicit("hello", UserWarning, "xyz", 13)
|
||||
|
@ -46,7 +46,7 @@ class TestWarningsRecorderChecker:
|
|||
|
||||
def test_warn_stacklevel(self) -> None:
|
||||
"""#4243"""
|
||||
rec = WarningsRecorder()
|
||||
rec = WarningsRecorder(_ispytest=True)
|
||||
with rec:
|
||||
warnings.warn("test", DeprecationWarning, 2)
|
||||
|
||||
|
@ -54,21 +54,21 @@ class TestWarningsRecorderChecker:
|
|||
from _pytest.recwarn import WarningsChecker
|
||||
|
||||
with pytest.raises(TypeError):
|
||||
WarningsChecker(5) # type: ignore
|
||||
WarningsChecker(5, _ispytest=True) # type: ignore[arg-type]
|
||||
with pytest.raises(TypeError):
|
||||
WarningsChecker(("hi", RuntimeWarning)) # type: ignore
|
||||
WarningsChecker(("hi", RuntimeWarning), _ispytest=True) # type: ignore[arg-type]
|
||||
with pytest.raises(TypeError):
|
||||
WarningsChecker([DeprecationWarning, RuntimeWarning]) # type: ignore
|
||||
WarningsChecker([DeprecationWarning, RuntimeWarning], _ispytest=True) # type: ignore[arg-type]
|
||||
|
||||
def test_invalid_enter_exit(self) -> None:
|
||||
# wrap this test in WarningsRecorder to ensure warning state gets reset
|
||||
with WarningsRecorder():
|
||||
with WarningsRecorder(_ispytest=True):
|
||||
with pytest.raises(RuntimeError):
|
||||
rec = WarningsRecorder()
|
||||
rec = WarningsRecorder(_ispytest=True)
|
||||
rec.__exit__(None, None, None) # can't exit before entering
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
rec = WarningsRecorder()
|
||||
rec = WarningsRecorder(_ispytest=True)
|
||||
with rec:
|
||||
with rec:
|
||||
pass # can't enter twice
|
||||
|
|
|
@ -49,7 +49,9 @@ class FakeConfig:
|
|||
class TestTempdirHandler:
|
||||
def test_mktemp(self, tmp_path):
|
||||
config = cast(Config, FakeConfig(tmp_path))
|
||||
t = TempdirFactory(TempPathFactory.from_config(config))
|
||||
t = TempdirFactory(
|
||||
TempPathFactory.from_config(config, _ispytest=True), _ispytest=True
|
||||
)
|
||||
tmp = t.mktemp("world")
|
||||
assert tmp.relto(t.getbasetemp()) == "world0"
|
||||
tmp = t.mktemp("this")
|
||||
|
@ -62,7 +64,7 @@ class TestTempdirHandler:
|
|||
"""#4425"""
|
||||
monkeypatch.chdir(tmp_path)
|
||||
config = cast(Config, FakeConfig("hello"))
|
||||
t = TempPathFactory.from_config(config)
|
||||
t = TempPathFactory.from_config(config, _ispytest=True)
|
||||
assert t.getbasetemp().resolve() == (tmp_path / "hello").resolve()
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue