From a129dc330a5c5085abe0309462a6f0ca93a8b2a8 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sun, 12 Jan 2020 22:49:05 +0100 Subject: [PATCH 1/3] typing for getcfg and determine_setup --- src/_pytest/config/__init__.py | 1 + src/_pytest/config/findpaths.py | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index b5684823bcb..305ee39edcc 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) 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..206ee7e4b9e 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 @@ -22,7 +23,13 @@ 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], + Union[py.iniconfig.SectionWrapper, Dict, None], +]: """ Search the list of arguments for a valid ini-file for pytest, and return a tuple of (rootdir, inifile, cfg-dict). @@ -116,7 +123,7 @@ 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, py.path.local, Union[py.iniconfig.SectionWrapper, Dict]]: dirs = get_dirs_from_args(args) if inifile: iniconfig = py.iniconfig.IniConfig(inifile) From 3796ae0f6f4f1740fc447d40800fb2b65549244c Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 17 Jan 2020 09:09:44 +0100 Subject: [PATCH 2/3] Use py.iniconfig._SectionWrapper --- src/_pytest/config/__init__.py | 2 +- src/_pytest/config/findpaths.py | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/_pytest/config/__init__.py b/src/_pytest/config/__init__.py index 305ee39edcc..6be50f6f7c8 100644 --- a/src/_pytest/config/__init__.py +++ b/src/_pytest/config/__init__.py @@ -1093,7 +1093,7 @@ def _getini(self, name: str) -> Any: return "" return [] if type == "pathlist": - assert isinstance(self.inicfg, py.iniconfig.SectionWrapper) + 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 206ee7e4b9e..919f5ab4a5e 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -15,6 +15,8 @@ if TYPE_CHECKING: from . import Config # noqa: F401 + from py.iniconfig import _SectionWrapper # noqa: F401 + def exists(path, ignore=EnvironmentError): try: @@ -24,11 +26,11 @@ def exists(path, ignore=EnvironmentError): def getcfg( - args: Iterable[py.path.local], config: Optional[Config] = None + args: Iterable[py.path.local], config: Optional["Config"] = None ) -> Tuple[ Optional[py.path.local], Optional[py.path.local], - Union[py.iniconfig.SectionWrapper, Dict, None], + Union["_SectionWrapper", Dict, None], ]: """ Search the list of arguments for a valid ini-file for pytest, @@ -123,7 +125,7 @@ def determine_setup( args: List[str], rootdir_cmd_arg: Optional[str] = None, config: Optional["Config"] = None, -) -> Tuple[py.path.local, py.path.local, Union[py.iniconfig.SectionWrapper, Dict]]: +) -> Tuple[py.path.local, py.path.local, Union["_SectionWrapper", Dict]]: dirs = get_dirs_from_args(args) if inifile: iniconfig = py.iniconfig.IniConfig(inifile) From 4faac8a6ed2b88dafa67e64adc92ca7be4aec82e Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Tue, 25 Feb 2020 00:03:35 +0100 Subject: [PATCH 3/3] getcfg: do not return empty dict, fix types --- src/_pytest/config/findpaths.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index 919f5ab4a5e..91ef894094e 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -28,9 +28,7 @@ def exists(path, ignore=EnvironmentError): def getcfg( args: Iterable[py.path.local], config: Optional["Config"] = None ) -> Tuple[ - Optional[py.path.local], - Optional[py.path.local], - Union["_SectionWrapper", Dict, None], + Optional[py.path.local], Optional[py.path.local], Optional["_SectionWrapper"], ]: """ Search the list of arguments for a valid ini-file for pytest, @@ -49,7 +47,7 @@ def getcfg( 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)) @@ -68,7 +66,7 @@ def getcfg( return base, p, iniconfig["pytest"] elif inibasename == "pytest.ini": # allowed to be empty - return base, p, {} + return base, p, None return None, None, None @@ -125,11 +123,11 @@ def determine_setup( args: List[str], rootdir_cmd_arg: Optional[str] = None, config: Optional["Config"] = None, -) -> Tuple[py.path.local, py.path.local, Union["_SectionWrapper", Dict]]: +) -> 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: @@ -137,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: @@ -173,4 +170,4 @@ def determine_setup( rootdir ) ) - return rootdir, inifile, inicfg or {} + return rootdir, ret_inifile, inicfg or {}