diff --git a/src/_pytest/assertion/rewrite.py b/src/_pytest/assertion/rewrite.py index cec0c5501..e77b1b0b8 100644 --- a/src/_pytest/assertion/rewrite.py +++ b/src/_pytest/assertion/rewrite.py @@ -23,6 +23,8 @@ from typing import Set from typing import Tuple from typing import Union +import py + from _pytest._io.saferepr import saferepr from _pytest._version import version from _pytest.assertion import util @@ -177,10 +179,10 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader) """ if self.session is not None and not self._session_paths_checked: self._session_paths_checked = True - for path in self.session._initialpaths: + for initial_path in self.session._initialpaths: # Make something as c:/projects/my_project/path.py -> # ['c:', 'projects', 'my_project', 'path.py'] - parts = str(path).split(os.path.sep) + parts = str(initial_path).split(os.path.sep) # add 'path' to basenames to be checked. self._basenames_to_check_rewrite.add(os.path.splitext(parts[-1])[0]) @@ -213,7 +215,7 @@ class AssertionRewritingHook(importlib.abc.MetaPathFinder, importlib.abc.Loader) return True if self.session is not None: - if self.session.isinitpath(fn): + if self.session.isinitpath(py.path.local(fn)): state.trace( "matched test file (was specified on cmdline): {!r}".format(fn) ) diff --git a/src/_pytest/cacheprovider.py b/src/_pytest/cacheprovider.py index 305a122e9..967272ca6 100755 --- a/src/_pytest/cacheprovider.py +++ b/src/_pytest/cacheprovider.py @@ -495,7 +495,7 @@ def pytest_report_header(config: Config) -> Optional[str]: # starting with .., ../.. if sensible try: - displaypath = cachedir.relative_to(config.rootdir) + displaypath = cachedir.relative_to(str(config.rootdir)) except ValueError: displaypath = cachedir return "cachedir: {}".format(displaypath) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 2ae9ac849..e154f162b 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -308,10 +308,9 @@ class PytestPluginManager(PluginManager): self._dirpath2confmods = {} # type: Dict[Any, List[object]] # Maps a py.path.local to a module object. self._conftestpath2mod = {} # type: Dict[Any, object] - self._confcutdir = None + self._confcutdir = None # type: Optional[py.path.local] self._noconftest = False - # Set of py.path.local's. - self._duplicatepaths = set() # type: Set[Any] + self._duplicatepaths = set() # type: Set[py.path.local] self.add_hookspecs(_pytest.hookspec) self.register(self) @@ -945,13 +944,12 @@ class Config: ns, unknown_args = self._parser.parse_known_and_unknown_args( args, namespace=copy.copy(self.option) ) - r = determine_setup( + self.rootdir, self.inifile, self.inicfg = determine_setup( ns.inifilename, ns.file_or_dir + unknown_args, rootdir_cmd_arg=ns.rootdir or None, config=self, ) - self.rootdir, self.inifile, self.inicfg = r self._parser.extra_info["rootdir"] = self.rootdir self._parser.extra_info["inifile"] = self.inifile self._parser.addini("addopts", "extra command line options", "args") @@ -1162,6 +1160,8 @@ class Config: # in this case, we already have a list ready to use # 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() input_values = shlex.split(value) if isinstance(value, str) else value return [dp.join(x, abs=True) for x in input_values] diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index 796fa9b0a..ae8c5f47f 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -63,7 +63,7 @@ def load_config_dict_from_file( elif filepath.ext == ".toml": import toml - config = toml.load(filepath) + config = toml.load(str(filepath)) result = config.get("tool", {}).get("pytest", {}).get("ini_options", None) if result is not None: @@ -161,16 +161,18 @@ def determine_setup( args: List[str], rootdir_cmd_arg: Optional[str] = None, config: Optional["Config"] = None, -) -> Tuple[py.path.local, Optional[str], Dict[str, Union[str, List[str]]]]: +) -> Tuple[py.path.local, Optional[py.path.local], Dict[str, Union[str, List[str]]]]: rootdir = None dirs = get_dirs_from_args(args) if inifile: - inicfg = load_config_dict_from_file(py.path.local(inifile)) or {} + inipath_ = py.path.local(inifile) + inipath = inipath_ # type: Optional[py.path.local] + inicfg = load_config_dict_from_file(inipath_) or {} if rootdir_cmd_arg is None: rootdir = get_common_ancestor(dirs) else: ancestor = get_common_ancestor(dirs) - rootdir, inifile, inicfg = locate_config([ancestor]) + rootdir, inipath, inicfg = locate_config([ancestor]) if rootdir is None and rootdir_cmd_arg is None: for possible_rootdir in ancestor.parts(reverse=True): if possible_rootdir.join("setup.py").exists(): @@ -178,7 +180,7 @@ def determine_setup( break else: if dirs != [ancestor]: - rootdir, inifile, inicfg = locate_config(dirs) + rootdir, inipath, inicfg = locate_config(dirs) if rootdir is None: if config is not None: cwd = config.invocation_dir @@ -196,4 +198,5 @@ def determine_setup( rootdir ) ) - return rootdir, inifile, inicfg or {} + assert rootdir is not None + return rootdir, inipath, inicfg or {} diff --git a/src/_pytest/logging.py b/src/_pytest/logging.py index ef90c94e8..04bf74b6c 100644 --- a/src/_pytest/logging.py +++ b/src/_pytest/logging.py @@ -586,7 +586,7 @@ class LoggingPlugin: fpath = Path(fname) if not fpath.is_absolute(): - fpath = Path(self._config.rootdir, fpath) + fpath = Path(str(self._config.rootdir), fpath) if not fpath.parent.exists(): fpath.parent.mkdir(exist_ok=True, parents=True) diff --git a/src/_pytest/main.py b/src/_pytest/main.py index a95f2f2e7..096df12dc 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -439,7 +439,7 @@ class Session(nodes.FSCollector): ) # type: Dict[Tuple[Type[nodes.Collector], str], CollectReport] # Dirnames of pkgs with dunder-init files. - self._collection_pkg_roots = {} # type: Dict[py.path.local, Package] + self._collection_pkg_roots = {} # type: Dict[str, Package] self._bestrelpathcache = _bestrelpath_cache( config.rootdir @@ -601,7 +601,7 @@ class Session(nodes.FSCollector): col = self._collectfile(pkginit, handle_dupes=False) if col: if isinstance(col[0], Package): - self._collection_pkg_roots[parent] = col[0] + self._collection_pkg_roots[str(parent)] = col[0] # always store a list in the cache, matchnodes expects it self._collection_node_cache1[col[0].fspath] = [col[0]] @@ -623,8 +623,8 @@ class Session(nodes.FSCollector): for x in self._collectfile(pkginit): yield x if isinstance(x, Package): - self._collection_pkg_roots[dirpath] = x - if dirpath in self._collection_pkg_roots: + self._collection_pkg_roots[str(dirpath)] = x + if str(dirpath) in self._collection_pkg_roots: # Do not collect packages here. continue diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 3757e0b27..c6c77f529 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -393,7 +393,7 @@ class Node(metaclass=NodeMeta): # 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(self.config.invocation_dir) + abspath = Path(os.getcwd()) != Path(str(self.config.invocation_dir)) except OSError: abspath = True diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 4b716c616..c52771057 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -656,7 +656,7 @@ class Package(Module): parts_ = parts(path.strpath) if any( - pkg_prefix in parts_ and pkg_prefix.join("__init__.py") != path + str(pkg_prefix) in parts_ and pkg_prefix.join("__init__.py") != path for pkg_prefix in pkg_prefixes ): continue @@ -1332,7 +1332,7 @@ def _show_fixtures_per_test(config, session): def get_best_relpath(func): loc = getlocation(func, curdir) - return curdir.bestrelpath(loc) + return curdir.bestrelpath(py.path.local(loc)) def write_fixture(fixture_def): argname = fixture_def.argname @@ -1406,7 +1406,7 @@ def _showfixtures_main(config: Config, session: Session) -> None: ( len(fixturedef.baseid), fixturedef.func.__module__, - curdir.bestrelpath(loc), + curdir.bestrelpath(py.path.local(loc)), fixturedef.argname, fixturedef, ) diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index e89776109..8c2a30739 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -380,9 +380,9 @@ class TerminalReporter: if self.currentfspath is not None and self._show_progress_info: self._write_progress_information_filling_space() self.currentfspath = fspath - fspath = self.startdir.bestrelpath(fspath) + relfspath = self.startdir.bestrelpath(fspath) self._tw.line() - self._tw.write(fspath + " ") + self._tw.write(relfspath + " ") self._tw.write(res, flush=True, **markup) def write_ensure_prefix(self, prefix, extra: str = "", **kwargs) -> None: diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 7dfd588a0..686fe1b98 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -580,8 +580,9 @@ class TestInvocationVariants: assert res.ret == 0 res.stdout.fnmatch_lines(["*1 passed*"]) - def test_equivalence_pytest_pytest(self): - assert pytest.main == py.test.cmdline.main + def test_equivalence_pytest_pydottest(self) -> None: + # Type ignored because `py.test` is not and will not be typed. + assert pytest.main == py.test.cmdline.main # type: ignore[attr-defined] def test_invoke_with_invalid_type(self): with pytest.raises( diff --git a/testing/test_config.py b/testing/test_config.py index 31dfd9fa3..fc128dd25 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -629,13 +629,14 @@ class TestConfigFromdictargs: ) with cwd.ensure(dir=True).as_cwd(): config = Config.fromdictargs(option_dict, ()) + inipath = py.path.local(inifile) assert config.args == [str(cwd)] assert config.option.inifilename == inifile assert config.option.capture == "no" # this indicates this is the file used for getting configuration values - assert config.inifile == inifile + assert config.inifile == inipath assert config.inicfg.get("name") == "value" assert config.inicfg.get("should_not_be_set") is None