diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index b5684823bcb..6be50f6f7c8 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1093,6 +1093,7 @@ def _getini(self, name: str) -> Any: return "" return [] if type == "pathlist": + assert isinstance(self.inicfg, py.iniconfig._SectionWrapper), self.inicfg dp = py.path.local(self.inicfg.config.path).dirpath() values = [] for relpath in shlex.split(value): diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index fb84160c1ff..91ef894094e 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -1,9 +1,10 @@ import os -from typing import Any +from typing import Dict from typing import Iterable from typing import List from typing import Optional from typing import Tuple +from typing import Union import py @@ -14,6 +15,8 @@ if TYPE_CHECKING: from . import Config # noqa: F401 + from py.iniconfig import _SectionWrapper # noqa: F401 + def exists(path, ignore=EnvironmentError): try: @@ -22,7 +25,11 @@ def exists(path, ignore=EnvironmentError): return False -def getcfg(args, config=None): +def getcfg( + args: Iterable[py.path.local], config: Optional["Config"] = None +) -> Tuple[ + Optional[py.path.local], Optional[py.path.local], Optional["_SectionWrapper"], +]: """ Search the list of arguments for a valid ini-file for pytest, and return a tuple of (rootdir, inifile, cfg-dict). @@ -40,7 +47,7 @@ def getcfg(args, config=None): p = base.join(inibasename) if exists(p): try: - iniconfig = py.iniconfig.IniConfig(p) + iniconfig = py.iniconfig.IniConfig(str(p)) except py.iniconfig.ParseError as exc: raise UsageError(str(exc)) @@ -59,7 +66,7 @@ def getcfg(args, config=None): return base, p, iniconfig["pytest"] elif inibasename == "pytest.ini": # allowed to be empty - return base, p, {} + return base, p, None return None, None, None @@ -116,11 +123,11 @@ def determine_setup( args: List[str], rootdir_cmd_arg: Optional[str] = None, config: Optional["Config"] = None, -) -> Tuple[py.path.local, Optional[str], Any]: +) -> Tuple[py.path.local, Optional[py.path.local], Union["_SectionWrapper", Dict]]: dirs = get_dirs_from_args(args) if inifile: iniconfig = py.iniconfig.IniConfig(inifile) - is_cfg_file = str(inifile).endswith(".cfg") + is_cfg_file = inifile.endswith(".cfg") sections = ["tool:pytest", "pytest"] if is_cfg_file else ["pytest"] for section in sections: try: @@ -128,26 +135,25 @@ def determine_setup( section ] # type: Optional[py.iniconfig._SectionWrapper] if is_cfg_file and section == "pytest" and config is not None: - fail( - CFG_PYTEST_SECTION.format(filename=str(inifile)), pytrace=False - ) + fail(CFG_PYTEST_SECTION.format(filename=inifile), pytrace=False) break except KeyError: inicfg = None if rootdir_cmd_arg is None: rootdir = get_common_ancestor(dirs) + ret_inifile = py.path.local(inifile) # type: Optional[py.path.local] else: ancestor = get_common_ancestor(dirs) - rootdir, inifile, inicfg = getcfg([ancestor], config=config) - if rootdir is None and rootdir_cmd_arg is None: + possible_rootdir, ret_inifile, inicfg = getcfg([ancestor], config=config) + if possible_rootdir is None and rootdir_cmd_arg is None: for possible_rootdir in ancestor.parts(reverse=True): if possible_rootdir.join("setup.py").exists(): rootdir = possible_rootdir break else: if dirs != [ancestor]: - rootdir, inifile, inicfg = getcfg(dirs, config=config) - if rootdir is None: + possible_rootdir, ret_inifile, inicfg = getcfg(dirs, config=config) + if possible_rootdir is None: if config is not None: cwd = config.invocation_dir else: @@ -164,4 +170,4 @@ def determine_setup( rootdir ) ) - return rootdir, inifile, inicfg or {} + return rootdir, ret_inifile, inicfg or {}