Some py.path.local -> pathlib.Path
- Some conftest related functions - _confcutdir - Allow arbitrary os.PathLike[str] in gethookproxy.
This commit is contained in:
parent
902739cfc3
commit
ed658d6829
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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")[
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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})"),
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue