diff options
Diffstat (limited to 'src/tox/config/cli')
-rw-r--r-- | src/tox/config/cli/env_var.py | 6 | ||||
-rw-r--r-- | src/tox/config/cli/for_docs.py | 7 | ||||
-rw-r--r-- | src/tox/config/cli/ini.py | 18 | ||||
-rw-r--r-- | src/tox/config/cli/parse.py | 23 | ||||
-rw-r--r-- | src/tox/config/cli/parser.py | 53 |
5 files changed, 68 insertions, 39 deletions
diff --git a/src/tox/config/cli/env_var.py b/src/tox/config/cli/env_var.py index 6e46c6b4..6e5de1be 100644 --- a/src/tox/config/cli/env_var.py +++ b/src/tox/config/cli/env_var.py @@ -1,3 +1,6 @@ +""" +Provides configuration values from the the environment variables. +""" import logging import os @@ -18,12 +21,11 @@ def get_env_var(key, of_type): environ_key = fmt.format(key_upper) if environ_key in os.environ: value = os.environ[environ_key] - # noinspection PyBroadException try: source = f"env var {environ_key}" of_type = CONVERT.to(raw=value, of_type=of_type) return of_type, source - except Exception as exception: + except Exception as exception: # noqa logging.warning( "env var %s=%r cannot be transformed to %r because %r", environ_key, diff --git a/src/tox/config/cli/for_docs.py b/src/tox/config/cli/for_docs.py index 95f6393f..d830034a 100644 --- a/src/tox/config/cli/for_docs.py +++ b/src/tox/config/cli/for_docs.py @@ -1,3 +1,6 @@ -from .parse import _get_core_parser +""" +This module exports the parser for the Sphinx doc generator. +""" +from .parse import _get_parser -parser = _get_core_parser() +parser = _get_parser() diff --git a/src/tox/config/cli/ini.py b/src/tox/config/cli/ini.py index 1a92c5f4..dc407c00 100644 --- a/src/tox/config/cli/ini.py +++ b/src/tox/config/cli/ini.py @@ -1,3 +1,6 @@ +""" +Provides configuration values from tox.ini files. +""" import logging import os from pathlib import Path @@ -27,14 +30,12 @@ class IniConfig: self.config_file = self.config_file.absolute() try: self.ini = Ini(self.config_file) - # noinspection PyProtectedMember - self.has_tox_section = cast(IniLoader, self.ini.core)._section is not None + self.has_tox_section = cast(IniLoader, self.ini.core)._section is not None # noqa except Exception as exception: logging.error("failed to read config file %s because %r", config_file, exception) self.has_config_file = None def get(self, key, of_type): - # noinspection PyBroadException cache_key = key, of_type if cache_key in self._cache: result = self._cache[cache_key] @@ -45,14 +46,8 @@ class IniConfig: result = value, source except KeyError: # just not found result = None - except Exception as exception: - logging.warning( - "%s key %s as type %r failed with %r", - self.config_file, - key, - of_type, - exception, - ) + except Exception as exception: # noqa + logging.warning("%s key %s as type %r failed with %r", self.config_file, key, of_type, exception) result = None self._cache[cache_key] = result return result @@ -62,6 +57,7 @@ class IniConfig: @property def epilog(self): + # text to show within the parsers epilog return ( f"{os.linesep}config file {str(self.config_file)!r} {self.STATE[self.has_config_file]} " f"(change{'d' if self.is_env_var else ''} via env var {self.TOX_CONFIG_FILE_ENV_VAR})" diff --git a/src/tox/config/cli/parse.py b/src/tox/config/cli/parse.py index 5ba8c5f1..a03f3a50 100644 --- a/src/tox/config/cli/parse.py +++ b/src/tox/config/cli/parse.py @@ -1,3 +1,7 @@ +""" +This module pulls together this package: create and parse CLI arguments for tox. +""" + from typing import Dict, List, Tuple from tox.report import setup_report @@ -7,13 +11,14 @@ from .parser import Handler, Parsed, ToxParser def get_options(*args) -> Tuple[Parsed, List[str], Dict[str, Handler]]: guess_verbosity = _get_base(args) - handlers, parsed, unknown = _get_core(args) + handlers, parsed, unknown = _get_all(args) if guess_verbosity != parsed.verbosity: setup_report(parsed.verbosity, parsed.is_colored) # pragma: no cover return parsed, unknown, handlers def _get_base(args): + """First just load the base options (verbosity+color) to setup the logging framework.""" tox_parser = ToxParser.base() parsed, unknown = tox_parser.parse(args) guess_verbosity = parsed.verbosity @@ -21,18 +26,22 @@ def _get_base(args): return guess_verbosity -def _get_core(args): - tox_parser = _get_core_parser() +def _get_all(args): + """Parse all the options.""" + tox_parser = _get_parser() parsed, unknown = tox_parser.parse(args) handlers = {k: p for k, (_, p) in tox_parser.handlers.items()} return handlers, parsed, unknown -def _get_core_parser(): - tox_parser = ToxParser.core() - # noinspection PyUnresolvedReferences - from tox.plugin.manager import MANAGER +def _get_parser(): + tox_parser = ToxParser.core() # load the core options + # plus options setup by plugins + from tox.plugin.manager import MANAGER # noqa MANAGER.tox_add_option(tox_parser) tox_parser.fix_defaults() return tox_parser + + +__all__ = ("get_options",) diff --git a/src/tox/config/cli/parser.py b/src/tox/config/cli/parser.py index 6339149d..23a08785 100644 --- a/src/tox/config/cli/parser.py +++ b/src/tox/config/cli/parser.py @@ -1,22 +1,37 @@ +""" +Customize argparse logic for tox (also contains the base options). +""" + import argparse import logging import os import sys -from argparse import SUPPRESS, Action, ArgumentDefaultsHelpFormatter, ArgumentParser, Namespace +from argparse import ( + SUPPRESS, + Action, + ArgumentDefaultsHelpFormatter, + ArgumentParser, + Namespace, +) from itertools import chain from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Type, TypeVar from tox.config.source.ini import StrConvert -from tox.plugin.util import NAME +from tox.plugin import NAME from tox.session.state import State from .env_var import get_env_var from .ini import IniConfig +if sys.version_info >= (3, 8): + from typing import Literal +else: + from typing_extensions import Literal # noqa + class ArgumentParserWithEnvAndConfig(ArgumentParser): """ - Custom option parser which updates its defaults by checking the configuration files and environmental variables + Argument parser which updates its defaults by checking the configuration files and environmental variables. """ def __init__(self, *args: Any, **kwargs: Any) -> None: @@ -47,10 +62,6 @@ class ArgumentParserWithEnvAndConfig(ArgumentParser): if of_type is None: if isinstance(action, argparse._StoreAction) and action.choices: # noqa loc = locals() - if sys.version_info >= (3, 8): - from typing import Literal # noqa - else: - from typing_extensions import Literal # noqa loc["Literal"] = Literal as_literal = f"Literal[{', '.join(repr(i) for i in action.choices)}]" of_type = eval(as_literal, globals(), loc) @@ -64,12 +75,16 @@ class ArgumentParserWithEnvAndConfig(ArgumentParser): class HelpFormatter(ArgumentDefaultsHelpFormatter): + """ + A help formatter that provides the default value and the source it comes from. + """ + def __init__(self, prog: str) -> None: super().__init__(prog, max_help_position=42, width=240) def _get_help_string(self, action: Action) -> str: - # noinspection PyProtectedMember - text = super()._get_help_string(action) + + text = super()._get_help_string(action) # noqa if hasattr(action, "default_source"): default = " (default: %(default)s)" if text.endswith(default): @@ -77,6 +92,12 @@ class HelpFormatter(ArgumentDefaultsHelpFormatter): return text +Handler = Callable[[State], Optional[int]] + + +ToxParserT = TypeVar("ToxParserT", bound="ToxParser") + + class Parsed(Namespace): @property def verbosity(self) -> int: @@ -87,18 +108,14 @@ class Parsed(Namespace): return self.colored == "yes" -Handler = Callable[[State], Optional[int]] - - -ToxParserT = TypeVar("ToxParserT", bound="ToxParser") - - class ToxParser(ArgumentParserWithEnvAndConfig): + """Argument parser for tox.""" + def __init__(self, *args: Any, root: bool = False, add_cmd: bool = False, **kwargs: Any) -> None: super().__init__(*args, **kwargs) if root is True: self._add_base_options() - self.handlers = {} # type:Dict[str, Tuple[Any, Handler]] + self.handlers: Dict[str, Tuple[Any, Handler]] = {} if add_cmd is True: self._cmd = self.add_subparsers(title="command", help="tox command to execute", dest="command") self._cmd.required = False @@ -130,6 +147,7 @@ class ToxParser(ArgumentParserWithEnvAndConfig): return cls(prog=NAME, formatter_class=HelpFormatter, add_cmd=True, root=True) def _add_base_options(self) -> None: + """Argument options that always make sense.""" from tox.report import LEVELS level_map = "|".join("{} - {}".format(c, logging.getLevelName(l)) for c, l in sorted(list(LEVELS.items()))) @@ -163,7 +181,8 @@ class ToxParser(ArgumentParserWithEnvAndConfig): return result, unknown def _inject_default_cmd(self, args): - # we need to inject the command if not present and reorganize args left of the command + # if the users specifies no command we imply he wants run, however for this to work we need to inject it onto + # the argument parsers left side if self._cmd is None: # no commands yet so must be all global, nothing to fix return args _global = { |