Skip to content

Commit

Permalink
Replace some usages of config.{rootdir,inifile} with config.{rootpath…
Browse files Browse the repository at this point in the history
…,inipath}
  • Loading branch information
bluetech committed Aug 25, 2020
1 parent 7c1ce06 commit 63bcb99
Show file tree
Hide file tree
Showing 10 changed files with 116 additions and 99 deletions.
6 changes: 3 additions & 3 deletions src/_pytest/cacheprovider.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def clear_cache(cls, cachedir: Path) -> None:

@staticmethod
def cache_dir_from_config(config: Config) -> Path:
return resolve_from_str(config.getini("cache_dir"), config.rootdir)
return resolve_from_str(config.getini("cache_dir"), config.rootpath)

def warn(self, fmt: str, **args: object) -> None:
import warnings
Expand Down Expand Up @@ -264,7 +264,7 @@ def __init__(self, config: Config) -> None:

def get_last_failed_paths(self) -> Set[Path]:
"""Return a set with all Paths()s of the previously failed nodeids."""
rootpath = Path(str(self.config.rootdir))
rootpath = self.config.rootpath
result = {rootpath / nodeid.split("::")[0] for nodeid in self.lastfailed}
return {x for x in result if x.exists()}

Expand Down Expand Up @@ -495,7 +495,7 @@ def pytest_report_header(config: Config) -> Optional[str]:
# starting with .., ../.. if sensible

try:
displaypath = cachedir.relative_to(str(config.rootdir))
displaypath = cachedir.relative_to(config.rootpath)
except ValueError:
displaypath = cachedir
return "cachedir: {}".format(displaypath)
Expand Down
30 changes: 15 additions & 15 deletions src/_pytest/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
from _pytest.compat import TYPE_CHECKING
from _pytest.outcomes import fail
from _pytest.outcomes import Skipped
from _pytest.pathlib import bestrelpath
from _pytest.pathlib import import_path
from _pytest.pathlib import ImportMode
from _pytest.pathlib import Path
Expand Down Expand Up @@ -1008,9 +1009,9 @@ def notify_exception(

def cwd_relative_nodeid(self, nodeid: str) -> str:
# nodeid's are relative to the rootpath, compute relative to cwd.
if self.invocation_dir != self.rootdir:
fullpath = self.rootdir.join(nodeid)
nodeid = self.invocation_dir.bestrelpath(fullpath)
if self.invocation_params.dir != self.rootpath:
fullpath = self.rootpath / nodeid
nodeid = bestrelpath(self.invocation_params.dir, fullpath)
return nodeid

@classmethod
Expand Down Expand Up @@ -1048,8 +1049,8 @@ def _initini(self, args: Sequence[str]) -> None:
self.rootpath = rootpath
self.inipath = inipath
self.inicfg = inicfg
self._parser.extra_info["rootdir"] = self.rootdir
self._parser.extra_info["inifile"] = self.inifile
self._parser.extra_info["rootdir"] = str(self.rootpath)
self._parser.extra_info["inifile"] = str(self.inipath)
self._parser.addini("addopts", "extra command line options", "args")
self._parser.addini("minversion", "minimally required pytest version")
self._parser.addini(
Expand Down Expand Up @@ -1138,9 +1139,8 @@ def _preparse(self, args: List[str], addopts: bool = True) -> None:
args, namespace=copy.copy(self.option)
)
self._validate_plugins()
if self.known_args_namespace.confcutdir is None and self.inifile:
confcutdir = py.path.local(self.inifile).dirname
self.known_args_namespace.confcutdir = confcutdir
if self.known_args_namespace.confcutdir is None and self.inipath:
self.known_args_namespace.confcutdir = str(self.inipath.parent)
try:
self.hook.pytest_load_initial_conftests(
early_config=self, args=args, parser=self._parser
Expand Down Expand Up @@ -1172,13 +1172,13 @@ def _checkversion(self) -> None:

if not isinstance(minver, str):
raise pytest.UsageError(
"%s: 'minversion' must be a single value" % self.inifile
"%s: 'minversion' must be a single value" % self.inipath
)

if Version(minver) > Version(pytest.__version__):
raise pytest.UsageError(
"%s: 'minversion' requires pytest-%s, actual pytest-%s'"
% (self.inifile, minver, pytest.__version__,)
% (self.inipath, minver, pytest.__version__,)
)

def _validate_keys(self) -> None:
Expand Down Expand Up @@ -1248,10 +1248,10 @@ def parse(self, args: List[str], addopts: bool = True) -> None:
args, self.option, namespace=self.option
)
if not args:
if self.invocation_dir == self.rootdir:
if self.invocation_params.dir == self.rootpath:
args = self.getini("testpaths")
if not args:
args = [str(self.invocation_dir)]
args = [str(self.invocation_params.dir)]
self.args = args
except PrintHelp:
pass
Expand Down Expand Up @@ -1311,10 +1311,10 @@ def _getini(self, name: str):
#
if type == "pathlist":
# TODO: This assert is probably not valid in all cases.
assert self.inifile is not None
dp = py.path.local(self.inifile).dirpath()
assert self.inipath is not None
dp = self.inipath.parent
input_values = shlex.split(value) if isinstance(value, str) else value
return [dp.join(x, abs=True) for x in input_values]
return [py.path.local(str(dp / x)) for x in input_values]
elif type == "args":
return shlex.split(value) if isinstance(value, str) else value
elif type == "linelist":
Expand Down
12 changes: 9 additions & 3 deletions src/_pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
from _pytest.mark import ParameterSet
from _pytest.outcomes import fail
from _pytest.outcomes import TEST_OUTCOME
from _pytest.pathlib import absolutepath

if TYPE_CHECKING:
from typing import Deque
Expand Down Expand Up @@ -1450,7 +1451,7 @@ def getfixtureinfo(
def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None:
nodeid = None
try:
p = py.path.local(plugin.__file__) # type: ignore[attr-defined]
p = absolutepath(plugin.__file__) # type: ignore[attr-defined]
except AttributeError:
pass
else:
Expand All @@ -1459,8 +1460,13 @@ def pytest_plugin_registered(self, plugin: _PluggyPlugin) -> None:
# Construct the base nodeid which is later used to check
# what fixtures are visible for particular tests (as denoted
# by their test id).
if p.basename.startswith("conftest.py"):
nodeid = p.dirpath().relto(self.config.rootdir)
if p.name.startswith("conftest.py"):
try:
nodeid = str(p.parent.relative_to(self.config.rootpath))
except ValueError:
nodeid = ""
if nodeid == ".":
nodeid = ""
if os.sep != nodes.SEP:
nodeid = nodeid.replace(os.sep, nodes.SEP)

Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ def set_log_path(self, fname: str) -> None:
fpath = Path(fname)

if not fpath.is_absolute():
fpath = Path(str(self._config.rootdir), fpath)
fpath = self._config.rootpath / fpath

if not fpath.parent.exists():
fpath.parent.mkdir(exist_ok=True, parents=True)
Expand Down
27 changes: 15 additions & 12 deletions src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from _pytest.fixtures import FixtureManager
from _pytest.outcomes import exit
from _pytest.pathlib import absolutepath
from _pytest.pathlib import bestrelpath
from _pytest.pathlib import Path
from _pytest.pathlib import visit
from _pytest.reports import CollectReport
Expand Down Expand Up @@ -417,11 +418,11 @@ class Failed(Exception):


@attr.s
class _bestrelpath_cache(Dict[py.path.local, str]):
path = attr.ib(type=py.path.local)
class _bestrelpath_cache(Dict[Path, str]):
path = attr.ib(type=Path)

def __missing__(self, path: py.path.local) -> str:
r = self.path.bestrelpath(path) # type: str
def __missing__(self, path: Path) -> str:
r = bestrelpath(self.path, path)
self[path] = r
return r

Expand All @@ -436,8 +437,8 @@ class Session(nodes.FSCollector):
exitstatus = None # type: Union[int, ExitCode]

def __init__(self, config: Config) -> None:
nodes.FSCollector.__init__(
self, config.rootdir, parent=None, config=config, session=self, nodeid=""
super().__init__(
config.rootdir, parent=None, config=config, session=self, nodeid=""
)
self.testsfailed = 0
self.testscollected = 0
Expand All @@ -462,8 +463,8 @@ def __init__(self, config: Config) -> None:
self._collection_pkg_roots = {} # type: Dict[str, Package]

self._bestrelpathcache = _bestrelpath_cache(
config.rootdir
) # type: Dict[py.path.local, str]
config.rootpath
) # type: Dict[Path, str]

self.config.pluginmanager.register(self, name="session")

Expand All @@ -481,7 +482,7 @@ def __repr__(self) -> str:
self.testscollected,
)

def _node_location_to_relpath(self, node_path: py.path.local) -> str:
def _node_location_to_relpath(self, node_path: Path) -> str:
# bestrelpath is a quite slow function.
return self._bestrelpathcache[node_path]

Expand Down Expand Up @@ -589,7 +590,9 @@ def _perform_collect( # noqa: F811
self.items = items = [] # type: List[nodes.Item]
for arg in args:
fspath, parts = resolve_collection_argument(
self.config.invocation_dir, arg, as_pypath=self.config.option.pyargs
self.config.invocation_params.dir,
arg,
as_pypath=self.config.option.pyargs,
)
self._initial_parts.append((fspath, parts))
initialpaths.append(fspath)
Expand Down Expand Up @@ -800,7 +803,7 @@ def search_pypath(module_name: str) -> str:


def resolve_collection_argument(
invocation_dir: py.path.local, arg: str, *, as_pypath: bool = False
invocation_path: Path, arg: str, *, as_pypath: bool = False
) -> Tuple[py.path.local, List[str]]:
"""Parse path arguments optionally containing selection parts and return (fspath, names).
Expand All @@ -827,7 +830,7 @@ def resolve_collection_argument(
strpath, *parts = str(arg).split("::")
if as_pypath:
strpath = search_pypath(strpath)
fspath = Path(str(invocation_dir), strpath)
fspath = invocation_path / strpath
fspath = absolutepath(fspath)
if not fspath.exists():
msg = (
Expand Down
8 changes: 3 additions & 5 deletions src/_pytest/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
from _pytest.mark.structures import MarkDecorator
from _pytest.mark.structures import NodeKeywords
from _pytest.outcomes import fail
from _pytest.pathlib import absolutepath
from _pytest.pathlib import Path
from _pytest.store import Store

Expand Down Expand Up @@ -402,7 +403,7 @@ def _repr_failure_py(
# It will be better to just always display paths relative to invocation_dir, but
# this requires a lot of plumbing (#6428).
try:
abspath = Path(os.getcwd()) != Path(str(self.config.invocation_dir))
abspath = Path(os.getcwd()) != self.config.invocation_params.dir
except OSError:
abspath = True

Expand Down Expand Up @@ -633,10 +634,7 @@ def reportinfo(self) -> Tuple[Union[py.path.local, str], Optional[int], str]:
@cached_property
def location(self) -> Tuple[str, Optional[int], str]:
location = self.reportinfo()
if isinstance(location[0], py.path.local):
fspath = location[0]
else:
fspath = py.path.local(location[0])
fspath = absolutepath(str(location[0]))
relfspath = self.session._node_location_to_relpath(fspath)
assert type(location[2]) is str
return (relfspath, location[1], location[2])
3 changes: 1 addition & 2 deletions src/_pytest/pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,7 @@ def make_numbered_dir_with_cleanup(
raise e


def resolve_from_str(input: str, root: py.path.local) -> Path:
rootpath = Path(root)
def resolve_from_str(input: str, rootpath: Path) -> Path:
input = expanduser(input)
input = expandvars(input)
if isabs(input):
Expand Down
36 changes: 19 additions & 17 deletions src/_pytest/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
from _pytest.config.argparsing import Parser
from _pytest.nodes import Item
from _pytest.nodes import Node
from _pytest.pathlib import absolutepath
from _pytest.pathlib import bestrelpath
from _pytest.pathlib import Path
from _pytest.reports import BaseReport
from _pytest.reports import CollectReport
from _pytest.reports import TestReport
Expand Down Expand Up @@ -297,9 +300,9 @@ def get_location(self, config: Config) -> Optional[str]:
if self.fslocation:
if isinstance(self.fslocation, tuple) and len(self.fslocation) >= 2:
filename, linenum = self.fslocation[:2]
relpath = py.path.local(filename).relto(config.invocation_dir)
if not relpath:
relpath = str(filename)
relpath = bestrelpath(
config.invocation_params.dir, absolutepath(filename)
)
return "{}:{}".format(relpath, linenum)
else:
return str(self.fslocation)
Expand All @@ -319,11 +322,12 @@ def __init__(self, config: Config, file: Optional[TextIO] = None) -> None:
self._main_color = None # type: Optional[str]
self._known_types = None # type: Optional[List[str]]
self.startdir = config.invocation_dir
self.startpath = config.invocation_params.dir
if file is None:
file = sys.stdout
self._tw = _pytest.config.create_terminal_writer(config, file)
self._screen_width = self._tw.fullwidth
self.currentfspath = None # type: Any
self.currentfspath = None # type: Union[None, Path, str, int]
self.reportchars = getreportopt(config)
self.hasmarkup = self._tw.hasmarkup
self.isatty = file.isatty()
Expand Down Expand Up @@ -385,19 +389,17 @@ def hasopt(self, char: str) -> bool:
return char in self.reportchars

def write_fspath_result(self, nodeid: str, res, **markup: bool) -> None:
fspath = self.config.rootdir.join(nodeid.split("::")[0])
# NOTE: explicitly check for None to work around py bug, and for less
# overhead in general (https://github.com/pytest-dev/py/pull/207).
fspath = self.config.rootpath / nodeid.split("::")[0]
if self.currentfspath is None or fspath != self.currentfspath:
if self.currentfspath is not None and self._show_progress_info:
self._write_progress_information_filling_space()
self.currentfspath = fspath
relfspath = self.startdir.bestrelpath(fspath)
relfspath = bestrelpath(self.startpath, fspath)
self._tw.line()
self._tw.write(relfspath + " ")
self._tw.write(res, flush=True, **markup)

def write_ensure_prefix(self, prefix, extra: str = "", **kwargs) -> None:
def write_ensure_prefix(self, prefix: str, extra: str = "", **kwargs) -> None:
if self.currentfspath != prefix:
self._tw.line()
self.currentfspath = prefix
Expand Down Expand Up @@ -709,14 +711,14 @@ def _write_report_lines_from_hooks(
self.write_line(line)

def pytest_report_header(self, config: Config) -> List[str]:
line = "rootdir: %s" % config.rootdir
line = "rootdir: %s" % config.rootpath

if config.inifile:
line += ", configfile: " + config.rootdir.bestrelpath(config.inifile)
if config.inipath:
line += ", configfile: " + bestrelpath(config.rootpath, config.inipath)

testpaths = config.getini("testpaths")
if testpaths and config.args == testpaths:
rel_paths = [config.rootdir.bestrelpath(x) for x in testpaths]
rel_paths = [bestrelpath(config.rootpath, x) for x in testpaths]
line += ", testpaths: {}".format(", ".join(rel_paths))
result = [line]

Expand Down Expand Up @@ -860,7 +862,7 @@ def mkrel(nodeid):
if self.verbosity >= 2 and nodeid.split("::")[0] != fspath.replace(
"\\", nodes.SEP
):
res += " <- " + self.startdir.bestrelpath(fspath)
res += " <- " + bestrelpath(self.startpath, fspath)
else:
res = "[location]"
return res + " "
Expand Down Expand Up @@ -1102,7 +1104,7 @@ def show_xpassed(lines: List[str]) -> None:

def show_skipped(lines: List[str]) -> None:
skipped = self.stats.get("skipped", []) # type: List[CollectReport]
fskips = _folded_skips(self.startdir, skipped) if skipped else []
fskips = _folded_skips(self.startpath, skipped) if skipped else []
if not fskips:
return
verbose_word = skipped[0]._get_verbose_word(self.config)
Expand Down Expand Up @@ -1230,7 +1232,7 @@ def _get_line_with_reprcrash_message(


def _folded_skips(
startdir: py.path.local, skipped: Sequence[CollectReport],
startpath: Path, skipped: Sequence[CollectReport],
) -> List[Tuple[int, str, Optional[int], str]]:
d = {} # type: Dict[Tuple[str, Optional[int], str], List[CollectReport]]
for event in skipped:
Expand All @@ -1239,7 +1241,7 @@ def _folded_skips(
assert len(event.longrepr) == 3, (event, event.longrepr)
fspath, lineno, reason = event.longrepr
# For consistency, report all fspaths in relative form.
fspath = startdir.bestrelpath(py.path.local(fspath))
fspath = bestrelpath(startpath, Path(fspath))
keywords = getattr(event, "keywords", {})
# Folding reports with global pytestmark variable.
# This is a workaround, because for now we cannot identify the scope of a skip marker
Expand Down

0 comments on commit 63bcb99

Please sign in to comment.