diff options
| author | Bernát Gábor <bgabor8@bloomberg.net> | 2020-02-04 14:51:00 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-02-04 14:51:00 +0000 |
| commit | 7a5d03fe15f1d467f7b224c528b95eccc080b2c1 (patch) | |
| tree | 7d1ccccac7eb588221fd3aa26c9d9227293ba179 /src | |
| parent | 786c3d0addb5d6b155dc73f8bd444bde00877045 (diff) | |
| download | virtualenv-7a5d03fe15f1d467f7b224c528b95eccc080b2c1.tar.gz | |
rewrite the documentation (#1519)
Diffstat (limited to 'src')
| -rw-r--r-- | src/virtualenv/activation/activator.py | 29 | ||||
| -rw-r--r-- | src/virtualenv/config/cli/parser.py | 6 | ||||
| -rw-r--r-- | src/virtualenv/create/creator.py | 40 | ||||
| -rw-r--r-- | src/virtualenv/discovery/builtin.py | 2 | ||||
| -rw-r--r-- | src/virtualenv/discovery/discover.py | 25 | ||||
| -rw-r--r-- | src/virtualenv/run/__init__.py | 42 | ||||
| -rw-r--r-- | src/virtualenv/run/plugin/activators.py | 2 | ||||
| -rw-r--r-- | src/virtualenv/run/plugin/base.py | 3 | ||||
| -rw-r--r-- | src/virtualenv/run/plugin/creators.py | 8 | ||||
| -rw-r--r-- | src/virtualenv/run/plugin/discovery.py | 10 | ||||
| -rw-r--r-- | src/virtualenv/run/plugin/seeders.py | 13 | ||||
| -rw-r--r-- | src/virtualenv/seed/embed/base_embed.py | 8 | ||||
| -rw-r--r-- | src/virtualenv/seed/embed/pip_invoke.py | 2 | ||||
| -rw-r--r-- | src/virtualenv/seed/none.py | 15 | ||||
| -rw-r--r-- | src/virtualenv/seed/seeder.py | 19 | ||||
| -rw-r--r-- | src/virtualenv/seed/via_app_data/via_app_data.py | 4 |
16 files changed, 163 insertions, 65 deletions
diff --git a/src/virtualenv/activation/activator.py b/src/virtualenv/activation/activator.py index 7e69aa7..728fa7e 100644 --- a/src/virtualenv/activation/activator.py +++ b/src/virtualenv/activation/activator.py @@ -7,17 +7,38 @@ import six @six.add_metaclass(ABCMeta) class Activator(object): + """Generates an activate script for the virtual environment""" + def __init__(self, options): - self.flag_prompt = options.prompt + """Create a new activator generator. - @classmethod - def add_parser_arguments(cls, parser, interpreter): - """add activator options""" + :param options: the parsed options as defined within :meth:`add_parser_arguments` + """ + self.flag_prompt = options.prompt @classmethod def supports(cls, interpreter): + """Check if the activation script is supported in the given interpreter. + + :param interpreter: the interpreter we need to support + :return: ``True`` if supported, ``False`` otherwise + """ return True + @classmethod + def add_parser_arguments(cls, parser, interpreter): + """ + Add CLI arguments for this activation script. + + :param parser: the CLI parser + :param interpreter: the interpreter this virtual environment is based of + """ + @abstractmethod def generate(self, creator): + """Generate the activate script for the given creator. + + :param creator: the creator (based of :class:`virtualenv.create.creator.Creator`) we used to create this \ + virtual environment + """ raise NotImplementedError diff --git a/src/virtualenv/config/cli/parser.py b/src/virtualenv/config/cli/parser.py index e817a42..67c63fb 100644 --- a/src/virtualenv/config/cli/parser.py +++ b/src/virtualenv/config/cli/parser.py @@ -20,6 +20,10 @@ class VirtualEnvConfigParser(ArgumentParser): kwargs["prog"] = "virtualenv" super(VirtualEnvConfigParser, self).__init__(*args, **kwargs) self._fixed = set() + self._elements = None + self._verbosity = None + self._options = None + self._interpreter = None def _fix_defaults(self): for action in self._actions: @@ -52,7 +56,7 @@ class VirtualEnvConfigParser(ArgumentParser): class HelpFormatter(ArgumentDefaultsHelpFormatter): def __init__(self, prog): - super(HelpFormatter, self).__init__(prog, max_help_position=37, width=240) + super(HelpFormatter, self).__init__(prog, max_help_position=35, width=240) def _get_help_string(self, action): # noinspection PyProtectedMember diff --git a/src/virtualenv/create/creator.py b/src/virtualenv/create/creator.py index 11e0deb..7965bd0 100644 --- a/src/virtualenv/create/creator.py +++ b/src/virtualenv/create/creator.py @@ -28,7 +28,14 @@ DEBUG_SCRIPT = HERE / "debug.py" @add_metaclass(ABCMeta) class Creator(object): + """A class that given a python Interpreter creates a virtual environment""" + def __init__(self, options, interpreter): + """Construct a new virtual environment creator. + + :param options: the CLI option as parsed from :meth:`add_parser_arguments` + :param interpreter: the interpreter to create virtual environment from + """ self.interpreter = interpreter self._debug = None self.dest = Path(options.dest) @@ -48,7 +55,23 @@ class Creator(object): ] @classmethod + def can_create(cls, interpreter): + """Determine if we can create a virtual environment. + + :param interpreter: the interpreter in question + :return: ``None`` if we can't create, any other object otherwise that will be forwarded to \ + :meth:`add_parser_arguments` + """ + return True + + @classmethod def add_parser_arguments(cls, parser, interpreter, meta): + """Add CLI arguments for the creator. + + :param parser: the CLI parser + :param interpreter: the interpreter we're asked to create virtual environment for + :param meta: value as returned by :meth:`can_create` + """ parser.add_argument( "dest", help="directory to create virtualenv at", type=cls.validate_dest, default="venv", nargs="?", ) @@ -60,6 +83,11 @@ class Creator(object): default=False, ) + @abstractmethod + def create(self): + """Perform the virtual environment creation.""" + raise NotImplementedError + @classmethod def validate_dest(cls, raw_value): """No path separator in the path, valid chars and must be write-able""" @@ -132,15 +160,6 @@ class Creator(object): self.create() self.set_pyenv_cfg() - @abstractmethod - def create(self): - raise NotImplementedError - - @classmethod - def can_create(cls, interpreter): - """Default is that we can""" - return True - def set_pyenv_cfg(self): self.pyenv_cfg.content = OrderedDict() self.pyenv_cfg["home"] = self.interpreter.system_exec_prefix @@ -150,6 +169,9 @@ class Creator(object): @property def debug(self): + """ + :return: debug information about the virtual environment (only valid after :meth:`create` has run) + """ if self._debug is None and self.exe is not None: self._debug = get_env_debug_info(self.exe, self.debug_script()) return self._debug diff --git a/src/virtualenv/discovery/builtin.py b/src/virtualenv/discovery/builtin.py index e4e0ea0..c5f4883 100644 --- a/src/virtualenv/discovery/builtin.py +++ b/src/virtualenv/discovery/builtin.py @@ -15,7 +15,7 @@ from .py_spec import PythonSpec class Builtin(Discover): def __init__(self, options): - super(Builtin, self).__init__() + super(Builtin, self).__init__(options) self.python_spec = options.python @classmethod diff --git a/src/virtualenv/discovery/discover.py b/src/virtualenv/discovery/discover.py index 13e258f..17d404e 100644 --- a/src/virtualenv/discovery/discover.py +++ b/src/virtualenv/discovery/discover.py @@ -7,20 +7,39 @@ import six @six.add_metaclass(ABCMeta) class Discover(object): - def __init__(self): - self._has_run = False - self._interpreter = None + """Discover and provide the requested Python interpreter""" @classmethod def add_parser_arguments(cls, parser): + """Add CLI arguments for this discovery mechanisms. + + :param parser: the CLI parser + """ raise NotImplementedError + # noinspection PyUnusedLocal + def __init__(self, options): + """Create a new discovery mechanism. + + :param options: the parsed options as defined within :meth:`add_parser_arguments` + """ + self._has_run = False + self._interpreter = None + @abstractmethod def run(self): + """Discovers an interpreter. + + + :return: the interpreter ready to use for virtual environment creation + """ raise NotImplementedError @property def interpreter(self): + """ + :return: the interpreter as returned by :meth:`run`, cached + """ if self._has_run is False: self._interpreter = self.run() self._has_run = True diff --git a/src/virtualenv/run/__init__.py b/src/virtualenv/run/__init__.py index 45a9662..7d0776b 100644 --- a/src/virtualenv/run/__init__.py +++ b/src/virtualenv/run/__init__.py @@ -23,41 +23,53 @@ def run_via_cli(args): return session +# noinspection PyProtectedMember def session_via_cli(args): + parser = build_parser(args) + parser.parse_args(args, namespace=parser._options) + creator, seeder, activators = tuple(e.create(parser._options) for e in parser._elements) # create types + session = Session(parser._verbosity, parser._interpreter, creator, seeder, activators) + return session + + +# noinspection PyProtectedMember +def build_parser(args=None): parser = VirtualEnvConfigParser() add_version_flag(parser) - options, verbosity = _do_report_setup(parser, args) - discover = get_discover(parser, args, options) - interpreter = discover.interpreter + parser._options, parser._verbosity = _do_report_setup(parser, args) + discover = get_discover(parser, args, parser._options) + parser._interpreter = interpreter = discover.interpreter if interpreter is None: raise RuntimeError("failed to find interpreter for {}".format(discover)) - elements = [ + parser._elements = [ CreatorSelector(interpreter, parser), SeederSelector(interpreter, parser), ActivationSelector(interpreter, parser), ] - parser.parse_known_args(args, namespace=options) - for element in elements: - element.handle_selected_arg_parse(options) + parser.parse_known_args(args, namespace=parser._options) + for element in parser._elements: + element.handle_selected_arg_parse(parser._options) parser.enable_help() - parser.parse_args(args, namespace=options) - creator, seeder, activators = tuple(e.create(options) for e in elements) # create types - session = Session(verbosity, interpreter, creator, seeder, activators) - return session + return parser def add_version_flag(parser): import virtualenv parser.add_argument( - "--version", action="version", version="%(prog)s {} from {}".format(__version__, virtualenv.__file__) + "--version", + action="version", + version="%(prog)s {} from {}".format(__version__, virtualenv.__file__), + help="display the version of the virtualenv package and it's location, then exit", ) def _do_report_setup(parser, args): - level_map = ", ".join("{}:{}".format(c, logging.getLevelName(l)) for c, l in sorted(list(LEVELS.items()))) - msg = "verbosity = verbose - quiet, default {}, count mapping = {{{}}}" - verbosity_group = parser.add_argument_group(msg.format(logging.getLevelName(LEVELS[3]), level_map)) + level_map = ", ".join("{}={}".format(logging.getLevelName(l), c) for c, l in sorted(list(LEVELS.items()))) + msg = "verbosity = verbose - quiet, default {}, mapping => {}" + verbosity_group = parser.add_argument_group( + title="verbosity", description=msg.format(logging.getLevelName(LEVELS[3]), level_map) + ) verbosity = verbosity_group.add_mutually_exclusive_group() verbosity.add_argument("-v", "--verbose", action="count", dest="verbose", help="increase verbosity", default=2) verbosity.add_argument("-q", "--quiet", action="count", dest="quiet", help="decrease verbosity", default=0) diff --git a/src/virtualenv/run/plugin/activators.py b/src/virtualenv/run/plugin/activators.py index 8fb5a6b..69b3050 100644 --- a/src/virtualenv/run/plugin/activators.py +++ b/src/virtualenv/run/plugin/activators.py @@ -13,11 +13,11 @@ class ActivationSelector(ComponentBuilder): (k, v) for k, v in self.options("virtualenv.activate").items() if v.supports(interpreter) ) super(ActivationSelector, self).__init__(interpreter, parser, "activators", possible) + self.parser.description = "options for activation scripts" self.active = None def add_selector_arg_parse(self, name, choices): self.default = ",".join(choices) - self.parser.add_argument( "--{}".format(name), default=self.default, diff --git a/src/virtualenv/run/plugin/base.py b/src/virtualenv/run/plugin/base.py index e3230e7..8aa4206 100644 --- a/src/virtualenv/run/plugin/base.py +++ b/src/virtualenv/run/plugin/base.py @@ -30,7 +30,7 @@ class ComponentBuilder(PluginLoader): self.name = name self._impl_class = None self.possible = possible - self.parser = parser.add_argument_group("{} options".format(name)) + self.parser = parser.add_argument_group(title=name) self.add_selector_arg_parse(name, list(self.possible)) @classmethod @@ -51,6 +51,7 @@ class ComponentBuilder(PluginLoader): return selected def populate_selected_argparse(self, selected): + self.parser.description = "options for {} {}".format(self.name, selected) self._impl_class.add_parser_arguments(self.parser, self.interpreter) def create(self, options): diff --git a/src/virtualenv/run/plugin/creators.py b/src/virtualenv/run/plugin/creators.py index 946b87a..7c8132d 100644 --- a/src/virtualenv/run/plugin/creators.py +++ b/src/virtualenv/run/plugin/creators.py @@ -40,17 +40,23 @@ class CreatorSelector(ComponentBuilder): def add_selector_arg_parse(self, name, choices): # prefer the built-in venv if present, otherwise fallback to first defined type choices = sorted(choices, key=lambda a: 0 if a == "builtin" else 1) + default_value = self._get_default(choices) self.parser.add_argument( "--{}".format(name), choices=choices, - default=next(iter(choices)), + default=default_value, required=False, help="create environment via{}".format( "" if self.builtin_key is None else " (builtin = {})".format(self.builtin_key) ), ) + @staticmethod + def _get_default(choices): + return next(iter(choices)) + def populate_selected_argparse(self, selected): + self.parser.description = "options for {} {}".format(self.name, selected) self._impl_class.add_parser_arguments(self.parser, self.interpreter, self.key_to_meta[selected]) def create(self, options): diff --git a/src/virtualenv/run/plugin/discovery.py b/src/virtualenv/run/plugin/discovery.py index aaed452..8890150 100644 --- a/src/virtualenv/run/plugin/discovery.py +++ b/src/virtualenv/run/plugin/discovery.py @@ -9,10 +9,12 @@ class Discovery(PluginLoader): def get_discover(parser, args, options): discover_types = Discovery.entry_points_for("virtualenv.discovery") - discovery_parser = parser.add_argument_group("target interpreter identifier") + discovery_parser = parser.add_argument_group( + title="discovery", description="discover and provide a target interpreter" + ) discovery_parser.add_argument( "--discovery", - choices=list(discover_types.keys()), + choices=_get_default_discovery(discover_types), default=next(i for i in discover_types.keys()), required=False, help="interpreter discovery method", @@ -23,3 +25,7 @@ def get_discover(parser, args, options): options, _ = parser.parse_known_args(args, namespace=options) discover = discover_class(options) return discover + + +def _get_default_discovery(discover_types): + return list(discover_types.keys()) diff --git a/src/virtualenv/run/plugin/seeders.py b/src/virtualenv/run/plugin/seeders.py index 2bd7070..26a3385 100644 --- a/src/virtualenv/run/plugin/seeders.py +++ b/src/virtualenv/run/plugin/seeders.py @@ -12,20 +12,19 @@ class SeederSelector(ComponentBuilder): self.parser.add_argument( "--{}".format(name), choices=choices, - default="app-data", + default=self._get_default(), required=False, help="seed packages install method", ) self.parser.add_argument( - "--without-pip", - help="if set forces the none seeder, used for compatibility with venv", - action="store_true", - dest="without_pip", + "--no-seed", "--without-pip", help="do not install seed packages", action="store_true", dest="no_seed", ) + @staticmethod + def _get_default(): + return "app-data" + def handle_selected_arg_parse(self, options): - if options.without_pip is True: - setattr(options, self.name, "none") return super(SeederSelector, self).handle_selected_arg_parse(options) def create(self, options): diff --git a/src/virtualenv/seed/embed/base_embed.py b/src/virtualenv/seed/embed/base_embed.py index 28490b8..b93fff6 100644 --- a/src/virtualenv/seed/embed/base_embed.py +++ b/src/virtualenv/seed/embed/base_embed.py @@ -14,7 +14,7 @@ class BaseEmbed(Seeder): packages = ["pip", "setuptools", "wheel"] def __init__(self, options): - super(BaseEmbed, self).__init__(options, enabled=options.without_pip is False) + super(BaseEmbed, self).__init__(options, enabled=options.no_seed is False) self.download = options.download self.extra_search_dir = [i.resolve() for i in options.extra_search_dir if i.exists()] @@ -41,7 +41,7 @@ class BaseEmbed(Seeder): "--download", dest="download", action="store_true", - help="download latest {} from PyPI".format("/".join(cls.packages)), + help="pass to enable download of the latest {} from PyPI".format("/".join(cls.packages)), default=False, ) group.add_argument( @@ -49,7 +49,7 @@ class BaseEmbed(Seeder): "--never-download", dest="download", action="store_false", - help="download latest {} from PyPI".format("/".join(cls.packages)), + help="pass to disable download of the latest {} from PyPI".format("/".join(cls.packages)), default=True, ) parser.add_argument( @@ -57,7 +57,7 @@ class BaseEmbed(Seeder): metavar="d", type=Path, nargs="+", - help="a location containing wheels candidates to install from", + help="a path containing wheels the seeder may also use beside bundled (can be set 1+ times)", default=[], ) for package in cls.packages: diff --git a/src/virtualenv/seed/embed/pip_invoke.py b/src/virtualenv/seed/embed/pip_invoke.py index 0e9ac8c..4b35ee5 100644 --- a/src/virtualenv/seed/embed/pip_invoke.py +++ b/src/virtualenv/seed/embed/pip_invoke.py @@ -21,6 +21,8 @@ class PipInvoke(BaseEmbed): super(PipInvoke, self).__init__(options) def run(self, creator): + if not self.enabled: + return with self.get_pip_install_cmd(creator.exe, creator.interpreter.version_release_str) as cmd: with pip_wheel_env_run(creator.interpreter.version_release_str) as env: logging.debug("pip seed by running: %s", LogCmd(cmd, env)) diff --git a/src/virtualenv/seed/none.py b/src/virtualenv/seed/none.py deleted file mode 100644 index 0bd12e4..0000000 --- a/src/virtualenv/seed/none.py +++ /dev/null @@ -1,15 +0,0 @@ -from __future__ import absolute_import, unicode_literals - -from virtualenv.seed.seeder import Seeder - - -class NoneSeeder(Seeder): - def __init__(self, options): - super(NoneSeeder, self).__init__(options, False) - - @classmethod - def add_parser_arguments(cls, parser, interpreter): - pass - - def run(self, creator): - pass diff --git a/src/virtualenv/seed/seeder.py b/src/virtualenv/seed/seeder.py index a679f03..52b065d 100644 --- a/src/virtualenv/seed/seeder.py +++ b/src/virtualenv/seed/seeder.py @@ -7,13 +7,32 @@ import six @six.add_metaclass(ABCMeta) class Seeder(object): + """A seeder will install some seed packages into a virtual environment.""" + + # noinspection PyUnusedLocal def __init__(self, options, enabled): + """ + + :param options: the parsed options as defined within :meth:`add_parser_arguments` + :param enabled: a flag weather the seeder is enabled or not + """ self.enabled = enabled @classmethod def add_parser_arguments(cls, parser, interpreter): + """ + Add CLI arguments for this seed mechanisms. + + :param parser: the CLI parser + :param interpreter: the interpreter this virtual environment is based of + """ raise NotImplementedError @abstractmethod def run(self, creator): + """Perform the seed operation. + + :param creator: the creator (based of :class:`virtualenv.create.creator.Creator`) we used to create this \ + virtual environment + """ raise NotImplementedError diff --git a/src/virtualenv/seed/via_app_data/via_app_data.py b/src/virtualenv/seed/via_app_data/via_app_data.py index c0e28e5..069a9c1 100644 --- a/src/virtualenv/seed/via_app_data/via_app_data.py +++ b/src/virtualenv/seed/via_app_data/via_app_data.py @@ -30,11 +30,13 @@ class FromAppData(BaseEmbed): "--clear-app-data", dest="clear_app_data", action="store_true", - help="clear the app data folder", + help="clear the app data folder of seed images ({})".format((default_data_dir() / "seed-v1").path), default=False, ) def run(self, creator): + if not self.enabled: + return base_cache = self.app_data_dir / creator.interpreter.version_release_str with self._get_seed_wheels(creator, base_cache) as name_to_whl: pip_version = name_to_whl["pip"].stem.split("-")[1] |
