def validate_basetemp(path: str) -> str: # GH 7119 msg = "basetemp must not be empty, the current working directory or any parent directory of it" # empty path if not path: raise argparse.ArgumentTypeError(msg) def is_ancestor(base: Path, query: Path) -> bool: """ return True if query is an ancestor of base, else False.""" if base == query: return True for parent in base.parents: if parent == query: return True return False # check if path is an ancestor of cwd if is_ancestor(Path.cwd(), Path(path).absolute()): raise argparse.ArgumentTypeError(msg) # check symlinks for ancestors if is_ancestor(Path.cwd().resolve(), Path(path).resolve()): raise argparse.ArgumentTypeError(msg) return path
def __init__( self, pluginmanager: PytestPluginManager, *, invocation_params: Optional[InvocationParams] = None ) -> None: from .argparsing import Parser, FILE_OR_DIR if invocation_params is None: invocation_params = self.InvocationParams( args=(), plugins=None, dir=Path.cwd() ) self.option = argparse.Namespace() """Access to command line option as attributes. :type: argparse.Namespace """ self.invocation_params = invocation_params _a = FILE_OR_DIR self._parser = Parser( usage="%(prog)s [options] [{}] [{}] [...]".format(_a, _a), processopt=self._processopt, ) self.pluginmanager = pluginmanager """The plugin manager handles plugin registration and hook invocation. :type: PytestPluginManager. """ self.trace = self.pluginmanager.trace.root.get("config") self.hook = self.pluginmanager.hook self._inicache = {} # type: Dict[str, Any] self._override_ini = () # type: Sequence[str] self._opt2dest = {} # type: Dict[str, str] self._cleanup = [] # type: List[Callable[[], None]] # A place where plugins can store information on the config for their # own use. Currently only intended for internal plugins. self._store = Store() self.pluginmanager.register(self, "pytestconfig") self._configured = False self.hook.pytest_addoption.call_historic( kwargs=dict(parser=self._parser, pluginmanager=self.pluginmanager) ) if TYPE_CHECKING: from _pytest.cacheprovider import Cache self.cache = None # type: Optional[Cache]
def get_config(args=None, plugins=None): # subsequent calls to main will create a fresh instance pluginmanager = PytestPluginManager() config = Config( pluginmanager, invocation_params=Config.InvocationParams(args=args or (), plugins=plugins, dir=Path.cwd()), ) if args is not None: # Handle any "-p no:plugin" args. pluginmanager.consider_preparse(args, exclude_only=True) for spec in default_plugins: pluginmanager.import_plugin(spec) return config
def determine_setup( inifile: Optional[str], args: Sequence[str], rootdir_cmd_arg: Optional[str] = None, config: Optional["Config"] = None, ) -> Tuple[Path, Optional[Path], Dict[str, Union[str, List[str]]]]: rootdir = None dirs = get_dirs_from_args(args) if inifile: inipath_ = absolutepath(inifile) inipath = inipath_ # type: Optional[Path] 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, inipath, inicfg = locate_config([ancestor]) if rootdir is None and rootdir_cmd_arg is None: for possible_rootdir in itertools.chain( (ancestor, ), reversed(ancestor.parents)): if (possible_rootdir / "setup.py").is_file(): rootdir = possible_rootdir break else: if dirs != [ancestor]: rootdir, inipath, inicfg = locate_config(dirs) if rootdir is None: if config is not None: cwd = config.invocation_params.dir else: cwd = Path.cwd() rootdir = get_common_ancestor([cwd, ancestor]) is_fs_root = os.path.splitdrive(str(rootdir))[1] == "/" if is_fs_root: rootdir = ancestor if rootdir_cmd_arg: rootdir = absolutepath(os.path.expandvars(rootdir_cmd_arg)) if not rootdir.is_dir(): raise UsageError( "Directory '{}' not found. Check your '--rootdir' option.". format(rootdir)) assert rootdir is not None return rootdir, inipath, inicfg or {}
def get_common_ancestor(paths: Iterable[Path]) -> Path: common_ancestor = None # type: Optional[Path] for path in paths: if not path.exists(): continue if common_ancestor is None: common_ancestor = path else: if common_ancestor in path.parents or path == common_ancestor: continue elif path in common_ancestor.parents: common_ancestor = path else: shared = commonpath(path, common_ancestor) if shared is not None: common_ancestor = shared if common_ancestor is None: common_ancestor = Path.cwd() elif common_ancestor.is_file(): common_ancestor = common_ancestor.parent return common_ancestor
def locate_config( args: Iterable[Path], ) -> Tuple[Optional[Path], Optional[Path], Dict[str, Union[str, List[str]]], ]: """Search in the list of arguments for a valid ini-file for pytest, and return a tuple of (rootdir, inifile, cfg-dict).""" config_names = [ "pytest.ini", "pyproject.toml", "tox.ini", "setup.cfg", ] args = [x for x in args if not str(x).startswith("-")] if not args: args = [Path.cwd()] for arg in args: argpath = absolutepath(arg) for base in itertools.chain((argpath, ), reversed(argpath.parents)): for config_name in config_names: p = base / config_name if p.is_file(): ini_config = load_config_dict_from_file(p) if ini_config is not None: return base, p, ini_config return None, None, {}