diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index bd9e2883f..0df4ffa01 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -50,9 +50,11 @@ from _pytest.compat import final from _pytest.compat import importlib_metadata from _pytest.outcomes import fail from _pytest.outcomes import Skipped +from _pytest.pathlib import absolutepath from _pytest.pathlib import bestrelpath from _pytest.pathlib import import_path from _pytest.pathlib import ImportMode +from _pytest.pathlib import resolve_package_path from _pytest.store import Store from _pytest.warning_types import PytestConfigWarning @@ -102,9 +104,7 @@ class ExitCode(enum.IntEnum): class ConftestImportFailure(Exception): def __init__( - self, - path: py.path.local, - excinfo: Tuple[Type[Exception], Exception, TracebackType], + self, path: Path, excinfo: Tuple[Type[Exception], Exception, TracebackType], ) -> None: super().__init__(path, excinfo) self.path = path @@ -342,9 +342,9 @@ class PytestPluginManager(PluginManager): self._conftest_plugins: Set[types.ModuleType] = set() # State related to local conftest plugins. - self._dirpath2confmods: Dict[py.path.local, List[types.ModuleType]] = {} + self._dirpath2confmods: Dict[Path, List[types.ModuleType]] = {} self._conftestpath2mod: Dict[Path, types.ModuleType] = {} - self._confcutdir: Optional[py.path.local] = None + self._confcutdir: Optional[Path] = None self._noconftest = False self._duplicatepaths: Set[py.path.local] = set() @@ -479,9 +479,9 @@ class PytestPluginManager(PluginManager): All builtin and 3rd party plugins will have been loaded, however, so common options will not confuse our logic here. """ - current = py.path.local() + current = Path.cwd() self._confcutdir = ( - current.join(namespace.confcutdir, abs=True) + absolutepath(current / namespace.confcutdir) if namespace.confcutdir else None ) @@ -495,7 +495,7 @@ class PytestPluginManager(PluginManager): i = path.find("::") if i != -1: path = path[:i] - anchor = current.join(path, abs=1) + anchor = absolutepath(current / path) if anchor.exists(): # we found some file object self._try_load_conftest(anchor, namespace.importmode) foundanchor = True @@ -503,24 +503,24 @@ class PytestPluginManager(PluginManager): self._try_load_conftest(current, namespace.importmode) def _try_load_conftest( - self, anchor: py.path.local, importmode: Union[str, ImportMode] + self, anchor: Path, importmode: Union[str, ImportMode] ) -> None: self._getconftestmodules(anchor, importmode) # let's also consider test* subdirs - if anchor.check(dir=1): - for x in anchor.listdir("test*"): - if x.check(dir=1): + if anchor.is_dir(): + for x in anchor.glob("test*"): + if x.is_dir(): self._getconftestmodules(x, importmode) @lru_cache(maxsize=128) def _getconftestmodules( - self, path: py.path.local, importmode: Union[str, ImportMode], + self, path: Path, importmode: Union[str, ImportMode], ) -> List[types.ModuleType]: if self._noconftest: return [] - if path.isfile(): - directory = path.dirpath() + if path.is_file(): + directory = path.parent else: directory = path @@ -528,18 +528,18 @@ class PytestPluginManager(PluginManager): # and allow users to opt into looking into the rootdir parent # directories instead of requiring to specify confcutdir. clist = [] - for parent in directory.parts(): - if self._confcutdir and self._confcutdir.relto(parent): + for parent in reversed((directory, *directory.parents)): + if self._confcutdir and parent in self._confcutdir.parents: continue - conftestpath = parent.join("conftest.py") - if conftestpath.isfile(): + conftestpath = parent / "conftest.py" + if conftestpath.is_file(): mod = self._importconftest(conftestpath, importmode) clist.append(mod) self._dirpath2confmods[directory] = clist return clist def _rget_with_confmod( - self, name: str, path: py.path.local, importmode: Union[str, ImportMode], + self, name: str, path: Path, importmode: Union[str, ImportMode], ) -> Tuple[types.ModuleType, Any]: modules = self._getconftestmodules(path, importmode) for mod in reversed(modules): @@ -550,21 +550,21 @@ class PytestPluginManager(PluginManager): raise KeyError(name) def _importconftest( - self, conftestpath: py.path.local, importmode: Union[str, ImportMode], + self, conftestpath: Path, importmode: Union[str, ImportMode], ) -> types.ModuleType: # Use a resolved Path object as key to avoid loading the same conftest # twice with build systems that create build directories containing # symlinks to actual files. # Using Path().resolve() is better than py.path.realpath because # it resolves to the correct path/drive in case-insensitive file systems (#5792) - key = Path(str(conftestpath)).resolve() + key = conftestpath.resolve() with contextlib.suppress(KeyError): return self._conftestpath2mod[key] - pkgpath = conftestpath.pypkgpath() + pkgpath = resolve_package_path(conftestpath) if pkgpath is None: - _ensure_removed_sysmodule(conftestpath.purebasename) + _ensure_removed_sysmodule(conftestpath.stem) try: mod = import_path(conftestpath, mode=importmode) @@ -577,10 +577,10 @@ class PytestPluginManager(PluginManager): self._conftest_plugins.add(mod) self._conftestpath2mod[key] = mod - dirpath = conftestpath.dirpath() + dirpath = conftestpath.parent if dirpath in self._dirpath2confmods: for path, mods in self._dirpath2confmods.items(): - if path and path.relto(dirpath) or path == dirpath: + if path and dirpath in path.parents or path == dirpath: assert mod not in mods mods.append(mod) self.trace(f"loading conftestmodule {mod!r}") @@ -588,7 +588,7 @@ class PytestPluginManager(PluginManager): return mod def _check_non_top_pytest_plugins( - self, mod: types.ModuleType, conftestpath: py.path.local, + self, mod: types.ModuleType, conftestpath: Path, ) -> None: if ( hasattr(mod, "pytest_plugins") @@ -1412,21 +1412,23 @@ class Config: assert type in [None, "string"] return value - def _getconftest_pathlist( - self, name: str, path: py.path.local - ) -> Optional[List[py.path.local]]: + def _getconftest_pathlist(self, name: str, path: Path) -> Optional[List[Path]]: try: mod, relroots = self.pluginmanager._rget_with_confmod( name, path, self.getoption("importmode") ) except KeyError: return None - modpath = py.path.local(mod.__file__).dirpath() - values: List[py.path.local] = [] + modpath = Path(mod.__file__).parent + values: List[Path] = [] for relroot in relroots: - if not isinstance(relroot, py.path.local): + if isinstance(relroot, Path): + pass + elif isinstance(relroot, py.path.local): + relroot = Path(relroot) + else: relroot = relroot.replace("/", os.sep) - relroot = modpath.join(relroot, abs=True) + relroot = absolutepath(modpath / relroot) values.append(relroot) return values diff --git a/src/_pytest/doctest.py b/src/_pytest/doctest.py index 64e8f0e0e..d0b6b4c41 100644 --- a/src/_pytest/doctest.py +++ b/src/_pytest/doctest.py @@ -7,6 +7,7 @@ import traceback import types import warnings from contextlib import contextmanager +from pathlib import Path from typing import Any from typing import Callable from typing import Dict @@ -525,7 +526,7 @@ class DoctestModule(pytest.Module): if self.fspath.basename == "conftest.py": module = self.config.pluginmanager._importconftest( - self.fspath, self.config.getoption("importmode") + Path(self.fspath), self.config.getoption("importmode") ) else: try: diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 41a33d449..eab3c9afd 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -371,22 +371,23 @@ def _in_venv(path: py.path.local) -> bool: def pytest_ignore_collect(path: py.path.local, config: Config) -> Optional[bool]: - ignore_paths = config._getconftest_pathlist("collect_ignore", path=path.dirpath()) + path_ = Path(path) + ignore_paths = config._getconftest_pathlist("collect_ignore", path=path_.parent) ignore_paths = ignore_paths or [] excludeopt = config.getoption("ignore") if excludeopt: - ignore_paths.extend([py.path.local(x) for x in excludeopt]) + ignore_paths.extend(absolutepath(x) for x in excludeopt) - if py.path.local(path) in ignore_paths: + if path_ in ignore_paths: return True ignore_globs = config._getconftest_pathlist( - "collect_ignore_glob", path=path.dirpath() + "collect_ignore_glob", path=path_.parent ) ignore_globs = ignore_globs or [] excludeglobopt = config.getoption("ignore_glob") if excludeglobopt: - ignore_globs.extend([py.path.local(x) for x in excludeglobopt]) + ignore_globs.extend(absolutepath(x) for x in excludeglobopt) if any(fnmatch.fnmatch(str(path), str(glob)) for glob in ignore_globs): return True @@ -512,12 +513,12 @@ class Session(nodes.FSCollector): def isinitpath(self, path: py.path.local) -> bool: return path in self._initialpaths - def gethookproxy(self, fspath: py.path.local): + def gethookproxy(self, fspath: "os.PathLike[str]"): # Check if we have the common case of running # hooks with all conftest.py files. pm = self.config.pluginmanager my_conftestmodules = pm._getconftestmodules( - fspath, self.config.getoption("importmode") + Path(fspath), self.config.getoption("importmode") ) remove_mods = pm._conftest_plugins.difference(my_conftestmodules) if remove_mods: @@ -668,8 +669,9 @@ class Session(nodes.FSCollector): # No point in finding packages when collecting doctests. if not self.config.getoption("doctestmodules", False): pm = self.config.pluginmanager + confcutdir = py.path.local(pm._confcutdir) if pm._confcutdir else None for parent in reversed(argpath.parts()): - if pm._confcutdir and pm._confcutdir.relto(parent): + if confcutdir and confcutdir.relto(parent): break if parent.isdir(): diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 27434fb6a..98bd581b9 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -520,7 +520,7 @@ class FSCollector(Collector): """The public constructor.""" return super().from_parent(parent=parent, fspath=fspath, **kw) - def gethookproxy(self, fspath: py.path.local): + def gethookproxy(self, fspath: "os.PathLike[str]"): warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2) return self.session.gethookproxy(fspath) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index e48e7531c..407f924a5 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -653,7 +653,7 @@ class Package(Module): func = partial(_call_with_optional_argument, teardown_module, self.obj) self.addfinalizer(func) - def gethookproxy(self, fspath: py.path.local): + def gethookproxy(self, fspath: "os.PathLike[str]"): warnings.warn(FSCOLLECTOR_GETHOOKPROXY_ISINITPATH, stacklevel=2) return self.session.gethookproxy(fspath) diff --git a/testing/python/fixtures.py b/testing/python/fixtures.py index 94547dd24..ac62de608 100644 --- a/testing/python/fixtures.py +++ b/testing/python/fixtures.py @@ -8,6 +8,7 @@ from _pytest.compat import getfuncargnames from _pytest.config import ExitCode from _pytest.fixtures import FixtureRequest from _pytest.pytester import get_public_names +from _pytest.pytester import Pytester from _pytest.pytester import Testdir @@ -1961,8 +1962,10 @@ class TestAutouseManagement: reprec = testdir.inline_run("-v", "-s") reprec.assertoutcome(passed=4) - def test_class_function_parametrization_finalization(self, testdir): - p = testdir.makeconftest( + def test_class_function_parametrization_finalization( + self, pytester: Pytester + ) -> None: + p = pytester.makeconftest( """ import pytest import pprint @@ -1984,7 +1987,7 @@ class TestAutouseManagement: request.addfinalizer(fin) """ ) - testdir.makepyfile( + pytester.makepyfile( """ import pytest @@ -1996,8 +1999,7 @@ class TestAutouseManagement: pass """ ) - confcut = f"--confcutdir={testdir.tmpdir}" - reprec = testdir.inline_run("-v", "-s", confcut) + reprec = pytester.inline_run("-v", "-s", "--confcutdir", pytester.path) reprec.assertoutcome(passed=8) config = reprec.getcalls("pytest_unconfigure")[0].config values = config.pluginmanager._getconftestmodules(p, importmode="prepend")[ diff --git a/testing/test_collection.py b/testing/test_collection.py index 1138c2bd6..862c1aba8 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -364,7 +364,9 @@ class TestCustomConftests: def test_collectignore_exclude_on_option(self, pytester: Pytester) -> None: pytester.makeconftest( """ - collect_ignore = ['hello', 'test_world.py'] + import py + from pathlib import Path + collect_ignore = [py.path.local('hello'), 'test_world.py', Path('bye')] def pytest_addoption(parser): parser.addoption("--XX", action="store_true", default=False) def pytest_configure(config): diff --git a/testing/test_config.py b/testing/test_config.py index b931797d4..eacc9c9eb 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -574,16 +574,16 @@ class TestConfigAPI: config.getvalue("x") assert config.getoption("x", 1) == 1 - def test_getconftest_pathlist(self, pytester: Pytester, tmpdir) -> None: - somepath = tmpdir.join("x", "y", "z") - p = tmpdir.join("conftest.py") - p.write("pathlist = ['.', %r]" % str(somepath)) + def test_getconftest_pathlist(self, pytester: Pytester, tmp_path: Path) -> None: + somepath = tmp_path.joinpath("x", "y", "z") + p = tmp_path.joinpath("conftest.py") + p.write_text(f"pathlist = ['.', {str(somepath)!r}]") config = pytester.parseconfigure(p) - assert config._getconftest_pathlist("notexist", path=tmpdir) is None - pl = config._getconftest_pathlist("pathlist", path=tmpdir) or [] + assert config._getconftest_pathlist("notexist", path=tmp_path) is None + pl = config._getconftest_pathlist("pathlist", path=tmp_path) or [] print(pl) assert len(pl) == 2 - assert pl[0] == tmpdir + assert pl[0] == tmp_path assert pl[1] == somepath @pytest.mark.parametrize("maybe_type", ["not passed", "None", '"string"']) @@ -1935,10 +1935,10 @@ class TestPytestPluginsVariable: assert msg not in res.stdout.str() -def test_conftest_import_error_repr(tmpdir: py.path.local) -> None: +def test_conftest_import_error_repr(tmp_path: Path) -> None: """`ConftestImportFailure` should use a short error message and readable path to the failed conftest.py file.""" - path = tmpdir.join("foo/conftest.py") + path = tmp_path.joinpath("foo/conftest.py") with pytest.raises( ConftestImportFailure, match=re.escape(f"RuntimeError: some error (from {path})"), diff --git a/testing/test_conftest.py b/testing/test_conftest.py index 638321728..36e83191b 100644 --- a/testing/test_conftest.py +++ b/testing/test_conftest.py @@ -4,6 +4,7 @@ import textwrap from pathlib import Path from typing import cast from typing import Dict +from typing import Generator from typing import List from typing import Optional @@ -15,7 +16,7 @@ from _pytest.config import PytestPluginManager from _pytest.monkeypatch import MonkeyPatch from _pytest.pathlib import symlink_or_skip from _pytest.pytester import Pytester -from _pytest.pytester import Testdir +from _pytest.tmpdir import TempPathFactory def ConftestWithSetinitial(path) -> PytestPluginManager: @@ -25,12 +26,12 @@ def ConftestWithSetinitial(path) -> PytestPluginManager: def conftest_setinitial( - conftest: PytestPluginManager, args, confcutdir: Optional[py.path.local] = None + conftest: PytestPluginManager, args, confcutdir: Optional["os.PathLike[str]"] = None ) -> None: class Namespace: def __init__(self) -> None: self.file_or_dir = args - self.confcutdir = str(confcutdir) + self.confcutdir = os.fspath(confcutdir) if confcutdir is not None else None self.noconftest = False self.pyargs = False self.importmode = "prepend" @@ -42,54 +43,58 @@ def conftest_setinitial( @pytest.mark.usefixtures("_sys_snapshot") class TestConftestValueAccessGlobal: @pytest.fixture(scope="module", params=["global", "inpackage"]) - def basedir(self, request, tmpdir_factory): - tmpdir = tmpdir_factory.mktemp("basedir", numbered=True) - tmpdir.ensure("adir/conftest.py").write("a=1 ; Directory = 3") - tmpdir.ensure("adir/b/conftest.py").write("b=2 ; a = 1.5") + def basedir( + self, request, tmp_path_factory: TempPathFactory + ) -> Generator[Path, None, None]: + tmpdir = tmp_path_factory.mktemp("basedir", numbered=True) + tmpdir.joinpath("adir/b").mkdir(parents=True) + tmpdir.joinpath("adir/conftest.py").write_text("a=1 ; Directory = 3") + tmpdir.joinpath("adir/b/conftest.py").write_text("b=2 ; a = 1.5") if request.param == "inpackage": - tmpdir.ensure("adir/__init__.py") - tmpdir.ensure("adir/b/__init__.py") + tmpdir.joinpath("adir/__init__.py").touch() + tmpdir.joinpath("adir/b/__init__.py").touch() yield tmpdir - def test_basic_init(self, basedir): + def test_basic_init(self, basedir: Path) -> None: conftest = PytestPluginManager() - p = basedir.join("adir") + p = basedir / "adir" assert conftest._rget_with_confmod("a", p, importmode="prepend")[1] == 1 - def test_immediate_initialiation_and_incremental_are_the_same(self, basedir): + def test_immediate_initialiation_and_incremental_are_the_same( + self, basedir: Path + ) -> None: conftest = PytestPluginManager() assert not len(conftest._dirpath2confmods) conftest._getconftestmodules(basedir, importmode="prepend") snap1 = len(conftest._dirpath2confmods) assert snap1 == 1 - conftest._getconftestmodules(basedir.join("adir"), importmode="prepend") + conftest._getconftestmodules(basedir / "adir", importmode="prepend") assert len(conftest._dirpath2confmods) == snap1 + 1 - conftest._getconftestmodules(basedir.join("b"), importmode="prepend") + conftest._getconftestmodules(basedir / "b", importmode="prepend") assert len(conftest._dirpath2confmods) == snap1 + 2 - def test_value_access_not_existing(self, basedir): + def test_value_access_not_existing(self, basedir: Path) -> None: conftest = ConftestWithSetinitial(basedir) with pytest.raises(KeyError): conftest._rget_with_confmod("a", basedir, importmode="prepend") - def test_value_access_by_path(self, basedir): + def test_value_access_by_path(self, basedir: Path) -> None: conftest = ConftestWithSetinitial(basedir) - adir = basedir.join("adir") + adir = basedir / "adir" assert conftest._rget_with_confmod("a", adir, importmode="prepend")[1] == 1 assert ( - conftest._rget_with_confmod("a", adir.join("b"), importmode="prepend")[1] - == 1.5 + conftest._rget_with_confmod("a", adir / "b", importmode="prepend")[1] == 1.5 ) - def test_value_access_with_confmod(self, basedir): - startdir = basedir.join("adir", "b") - startdir.ensure("xx", dir=True) + def test_value_access_with_confmod(self, basedir: Path) -> None: + startdir = basedir / "adir" / "b" + startdir.joinpath("xx").mkdir() conftest = ConftestWithSetinitial(startdir) mod, value = conftest._rget_with_confmod("a", startdir, importmode="prepend") assert value == 1.5 path = py.path.local(mod.__file__) - assert path.dirpath() == basedir.join("adir", "b") + assert path.dirpath() == basedir / "adir" / "b" assert path.purebasename.startswith("conftest") @@ -102,12 +107,12 @@ def test_conftest_in_nonpkg_with_init(tmp_path: Path, _sys_snapshot) -> None: ConftestWithSetinitial(tmp_path.joinpath("adir-1.0", "b")) -def test_doubledash_considered(testdir: Testdir) -> None: - conf = testdir.mkdir("--option") - conf.join("conftest.py").ensure() +def test_doubledash_considered(pytester: Pytester) -> None: + conf = pytester.mkdir("--option") + conf.joinpath("conftest.py").touch() conftest = PytestPluginManager() - conftest_setinitial(conftest, [conf.basename, conf.basename]) - values = conftest._getconftestmodules(py.path.local(conf), importmode="prepend") + conftest_setinitial(conftest, [conf.name, conf.name]) + values = conftest._getconftestmodules(conf, importmode="prepend") assert len(values) == 1 @@ -127,15 +132,18 @@ def test_conftest_global_import(pytester: Pytester) -> None: pytester.makeconftest("x=3") p = pytester.makepyfile( """ - import py, pytest + from pathlib import Path + import pytest from _pytest.config import PytestPluginManager conf = PytestPluginManager() - mod = conf._importconftest(py.path.local("conftest.py"), importmode="prepend") + mod = conf._importconftest(Path("conftest.py"), importmode="prepend") assert mod.x == 3 import conftest assert conftest is mod, (conftest, mod) - subconf = py.path.local().ensure("sub", "conftest.py") - subconf.write("y=4") + sub = Path("sub") + sub.mkdir() + subconf = sub / "conftest.py" + subconf.write_text("y=4") mod2 = conf._importconftest(subconf, importmode="prepend") assert mod != mod2 assert mod2.y == 4 @@ -147,19 +155,19 @@ def test_conftest_global_import(pytester: Pytester) -> None: assert res.ret == 0 -def test_conftestcutdir(testdir: Testdir) -> None: - conf = testdir.makeconftest("") - p = testdir.mkdir("x") +def test_conftestcutdir(pytester: Pytester) -> None: + conf = pytester.makeconftest("") + p = pytester.mkdir("x") conftest = PytestPluginManager() - conftest_setinitial(conftest, [testdir.tmpdir], confcutdir=p) + conftest_setinitial(conftest, [pytester.path], confcutdir=p) values = conftest._getconftestmodules(p, importmode="prepend") assert len(values) == 0 - values = conftest._getconftestmodules(conf.dirpath(), importmode="prepend") + values = conftest._getconftestmodules(conf.parent, importmode="prepend") assert len(values) == 0 assert Path(conf) not in conftest._conftestpath2mod # but we can still import a conftest directly conftest._importconftest(conf, importmode="prepend") - values = conftest._getconftestmodules(conf.dirpath(), importmode="prepend") + values = conftest._getconftestmodules(conf.parent, importmode="prepend") assert values[0].__file__.startswith(str(conf)) # and all sub paths get updated properly values = conftest._getconftestmodules(p, importmode="prepend") @@ -170,10 +178,8 @@ def test_conftestcutdir(testdir: Testdir) -> None: def test_conftestcutdir_inplace_considered(pytester: Pytester) -> None: conf = pytester.makeconftest("") conftest = PytestPluginManager() - conftest_setinitial(conftest, [conf.parent], confcutdir=py.path.local(conf.parent)) - values = conftest._getconftestmodules( - py.path.local(conf.parent), importmode="prepend" - ) + conftest_setinitial(conftest, [conf.parent], confcutdir=conf.parent) + values = conftest._getconftestmodules(conf.parent, importmode="prepend") assert len(values) == 1 assert values[0].__file__.startswith(str(conf)) @@ -184,7 +190,7 @@ def test_setinitial_conftest_subdirs(pytester: Pytester, name: str) -> None: subconftest = sub.joinpath("conftest.py") subconftest.touch() conftest = PytestPluginManager() - conftest_setinitial(conftest, [sub.parent], confcutdir=py.path.local(pytester.path)) + conftest_setinitial(conftest, [sub.parent], confcutdir=pytester.path) key = subconftest.resolve() if name not in ("whatever", ".dotdir"): assert key in conftest._conftestpath2mod @@ -337,22 +343,19 @@ def test_conftest_existing_junitxml(pytester: Pytester) -> None: result.stdout.fnmatch_lines(["*--xyz*"]) -def test_conftest_import_order(testdir: Testdir, monkeypatch: MonkeyPatch) -> None: - ct1 = testdir.makeconftest("") - sub = testdir.mkdir("sub") - ct2 = sub.join("conftest.py") - ct2.write("") +def test_conftest_import_order(pytester: Pytester, monkeypatch: MonkeyPatch) -> None: + ct1 = pytester.makeconftest("") + sub = pytester.mkdir("sub") + ct2 = sub / "conftest.py" + ct2.write_text("") def impct(p, importmode): return p conftest = PytestPluginManager() - conftest._confcutdir = testdir.tmpdir + conftest._confcutdir = pytester.path monkeypatch.setattr(conftest, "_importconftest", impct) - mods = cast( - List[py.path.local], - conftest._getconftestmodules(py.path.local(sub), importmode="prepend"), - ) + mods = cast(List[Path], conftest._getconftestmodules(sub, importmode="prepend")) expected = [ct1, ct2] assert mods == expected diff --git a/testing/test_pluginmanager.py b/testing/test_pluginmanager.py index 2099f5ae1..89f10a7db 100644 --- a/testing/test_pluginmanager.py +++ b/testing/test_pluginmanager.py @@ -8,6 +8,7 @@ from _pytest.config import ExitCode from _pytest.config import PytestPluginManager from _pytest.config.exceptions import UsageError from _pytest.main import Session +from _pytest.pytester import Pytester @pytest.fixture @@ -16,14 +17,16 @@ def pytestpm() -> PytestPluginManager: class TestPytestPluginInteractions: - def test_addhooks_conftestplugin(self, testdir, _config_for_test): - testdir.makepyfile( + def test_addhooks_conftestplugin( + self, pytester: Pytester, _config_for_test + ) -> None: + pytester.makepyfile( newhooks=""" def pytest_myhook(xyz): "new hook" """ ) - conf = testdir.makeconftest( + conf = pytester.makeconftest( """ import newhooks def pytest_addhooks(pluginmanager): @@ -54,10 +57,10 @@ class TestPytestPluginInteractions: assert res.ret != 0 res.stderr.fnmatch_lines(["*did not find*sys*"]) - def test_do_option_postinitialize(self, testdir): - config = testdir.parseconfigure() + def test_do_option_postinitialize(self, pytester: Pytester) -> None: + config = pytester.parseconfigure() assert not hasattr(config.option, "test123") - p = testdir.makepyfile( + p = pytester.makepyfile( """ def pytest_addoption(parser): parser.addoption('--test123', action="store_true", @@ -120,20 +123,20 @@ class TestPytestPluginInteractions: finally: undo() - def test_hook_proxy(self, testdir): + def test_hook_proxy(self, pytester: Pytester) -> None: """Test the gethookproxy function(#2016)""" - config = testdir.parseconfig() + config = pytester.parseconfig() session = Session.from_config(config) - testdir.makepyfile(**{"tests/conftest.py": "", "tests/subdir/conftest.py": ""}) + pytester.makepyfile(**{"tests/conftest.py": "", "tests/subdir/conftest.py": ""}) - conftest1 = testdir.tmpdir.join("tests/conftest.py") - conftest2 = testdir.tmpdir.join("tests/subdir/conftest.py") + conftest1 = pytester.path.joinpath("tests/conftest.py") + conftest2 = pytester.path.joinpath("tests/subdir/conftest.py") config.pluginmanager._importconftest(conftest1, importmode="prepend") - ihook_a = session.gethookproxy(testdir.tmpdir.join("tests")) + ihook_a = session.gethookproxy(pytester.path / "tests") assert ihook_a is not None config.pluginmanager._importconftest(conftest2, importmode="prepend") - ihook_b = session.gethookproxy(testdir.tmpdir.join("tests")) + ihook_b = session.gethookproxy(pytester.path / "tests") assert ihook_a is not ihook_b def test_hook_with_addoption(self, testdir):