Eliminado venv y www del repositorio, agrege un requirements igual
This commit is contained in:
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -4,13 +4,19 @@
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
from itertools import chain
|
||||
|
||||
from pip._internal.cli.main_parser import create_main_parser
|
||||
from pip._internal.commands import commands_dict, get_summaries
|
||||
from pip._internal.commands import commands_dict, create_command
|
||||
from pip._internal.utils.misc import get_installed_distributions
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Any, Iterable, List, Optional
|
||||
|
||||
|
||||
def autocomplete():
|
||||
# type: () -> None
|
||||
"""Entry Point for completion of main and subcommand options.
|
||||
"""
|
||||
# Don't complete if user hasn't sourced bash_completion file.
|
||||
@@ -23,17 +29,18 @@ def autocomplete():
|
||||
except IndexError:
|
||||
current = ''
|
||||
|
||||
subcommands = [cmd for cmd, summary in get_summaries()]
|
||||
options = []
|
||||
# subcommand
|
||||
try:
|
||||
subcommand_name = [w for w in cwords if w in subcommands][0]
|
||||
except IndexError:
|
||||
subcommand_name = None
|
||||
|
||||
parser = create_main_parser()
|
||||
subcommands = list(commands_dict)
|
||||
options = []
|
||||
|
||||
# subcommand
|
||||
subcommand_name = None # type: Optional[str]
|
||||
for word in cwords:
|
||||
if word in subcommands:
|
||||
subcommand_name = word
|
||||
break
|
||||
# subcommand options
|
||||
if subcommand_name:
|
||||
if subcommand_name is not None:
|
||||
# special case: 'help' subcommand has no options
|
||||
if subcommand_name == 'help':
|
||||
sys.exit(1)
|
||||
@@ -54,7 +61,7 @@ def autocomplete():
|
||||
print(dist)
|
||||
sys.exit(1)
|
||||
|
||||
subcommand = commands_dict[subcommand_name]()
|
||||
subcommand = create_command(subcommand_name)
|
||||
|
||||
for opt in subcommand.parser.option_list_all:
|
||||
if opt.help != optparse.SUPPRESS_HELP:
|
||||
@@ -73,8 +80,8 @@ def autocomplete():
|
||||
# get completion files and directories if ``completion_type`` is
|
||||
# ``<file>``, ``<dir>`` or ``<path>``
|
||||
if completion_type:
|
||||
options = auto_complete_paths(current, completion_type)
|
||||
options = ((opt, 0) for opt in options)
|
||||
paths = auto_complete_paths(current, completion_type)
|
||||
options = [(path, 0) for path in paths]
|
||||
for option in options:
|
||||
opt_label = option[0]
|
||||
# append '=' to options which require args
|
||||
@@ -86,22 +93,25 @@ def autocomplete():
|
||||
|
||||
opts = [i.option_list for i in parser.option_groups]
|
||||
opts.append(parser.option_list)
|
||||
opts = (o for it in opts for o in it)
|
||||
flattened_opts = chain.from_iterable(opts)
|
||||
if current.startswith('-'):
|
||||
for opt in opts:
|
||||
for opt in flattened_opts:
|
||||
if opt.help != optparse.SUPPRESS_HELP:
|
||||
subcommands += opt._long_opts + opt._short_opts
|
||||
else:
|
||||
# get completion type given cwords and all available options
|
||||
completion_type = get_path_completion_type(cwords, cword, opts)
|
||||
completion_type = get_path_completion_type(cwords, cword,
|
||||
flattened_opts)
|
||||
if completion_type:
|
||||
subcommands = auto_complete_paths(current, completion_type)
|
||||
subcommands = list(auto_complete_paths(current,
|
||||
completion_type))
|
||||
|
||||
print(' '.join([x for x in subcommands if x.startswith(current)]))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_path_completion_type(cwords, cword, opts):
|
||||
# type: (List[str], int, Iterable[Any]) -> Optional[str]
|
||||
"""Get the type of path completion (``file``, ``dir``, ``path`` or None)
|
||||
|
||||
:param cwords: same as the environmental variable ``COMP_WORDS``
|
||||
@@ -110,7 +120,7 @@ def get_path_completion_type(cwords, cword, opts):
|
||||
:return: path completion type (``file``, ``dir``, ``path`` or None)
|
||||
"""
|
||||
if cword < 2 or not cwords[cword - 2].startswith('-'):
|
||||
return
|
||||
return None
|
||||
for opt in opts:
|
||||
if opt.help == optparse.SUPPRESS_HELP:
|
||||
continue
|
||||
@@ -120,9 +130,11 @@ def get_path_completion_type(cwords, cword, opts):
|
||||
x in ('path', 'file', 'dir')
|
||||
for x in opt.metavar.split('/')):
|
||||
return opt.metavar
|
||||
return None
|
||||
|
||||
|
||||
def auto_complete_paths(current, completion_type):
|
||||
# type: (str, str) -> Iterable[str]
|
||||
"""If ``completion_type`` is ``file`` or ``path``, list all regular files
|
||||
and directories starting with ``current``; otherwise only list directories
|
||||
starting with ``current``.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""Base Command class, and related routines"""
|
||||
|
||||
from __future__ import absolute_import, print_function
|
||||
|
||||
import logging
|
||||
@@ -10,65 +11,75 @@ import sys
|
||||
import traceback
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.cmdoptions import make_search_scope
|
||||
from pip._internal.cli.command_context import CommandContextMixIn
|
||||
from pip._internal.cli.parser import (
|
||||
ConfigOptionParser, UpdatingDefaultsHelpFormatter,
|
||||
ConfigOptionParser,
|
||||
UpdatingDefaultsHelpFormatter,
|
||||
)
|
||||
from pip._internal.cli.status_codes import (
|
||||
ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR,
|
||||
ERROR,
|
||||
PREVIOUS_BUILD_DIR_ERROR,
|
||||
UNKNOWN_ERROR,
|
||||
VIRTUALENV_NOT_FOUND,
|
||||
)
|
||||
from pip._internal.download import PipSession
|
||||
from pip._internal.exceptions import (
|
||||
BadCommand, CommandError, InstallationError, PreviousBuildDirError,
|
||||
BadCommand,
|
||||
CommandError,
|
||||
InstallationError,
|
||||
NetworkConnectionError,
|
||||
PreviousBuildDirError,
|
||||
SubProcessError,
|
||||
UninstallationError,
|
||||
)
|
||||
from pip._internal.index import PackageFinder
|
||||
from pip._internal.models.selection_prefs import SelectionPreferences
|
||||
from pip._internal.models.target_python import TargetPython
|
||||
from pip._internal.req.constructors import (
|
||||
install_req_from_editable, install_req_from_line,
|
||||
)
|
||||
from pip._internal.req.req_file import parse_requirements
|
||||
from pip._internal.utils.deprecation import deprecated
|
||||
from pip._internal.utils.filesystem import check_path_owner
|
||||
from pip._internal.utils.logging import BrokenStdoutLoggingError, setup_logging
|
||||
from pip._internal.utils.misc import get_prog, normalize_path
|
||||
from pip._internal.utils.outdated import pip_version_check
|
||||
from pip._internal.utils.temp_dir import (
|
||||
global_tempdir_manager,
|
||||
tempdir_registry,
|
||||
)
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
from pip._internal.utils.virtualenv import running_under_virtualenv
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Optional, List, Tuple, Any
|
||||
from typing import List, Optional, Tuple, Any
|
||||
from optparse import Values
|
||||
from pip._internal.cache import WheelCache
|
||||
from pip._internal.req.req_set import RequirementSet
|
||||
|
||||
from pip._internal.utils.temp_dir import (
|
||||
TempDirectoryTypeRegistry as TempDirRegistry
|
||||
)
|
||||
|
||||
__all__ = ['Command']
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Command(object):
|
||||
name = None # type: Optional[str]
|
||||
usage = None # type: Optional[str]
|
||||
class Command(CommandContextMixIn):
|
||||
usage = None # type: str
|
||||
ignore_require_venv = False # type: bool
|
||||
|
||||
def __init__(self, isolated=False):
|
||||
# type: (bool) -> None
|
||||
def __init__(self, name, summary, isolated=False):
|
||||
# type: (str, str, bool) -> None
|
||||
super(Command, self).__init__()
|
||||
parser_kw = {
|
||||
'usage': self.usage,
|
||||
'prog': '%s %s' % (get_prog(), self.name),
|
||||
'prog': '{} {}'.format(get_prog(), name),
|
||||
'formatter': UpdatingDefaultsHelpFormatter(),
|
||||
'add_help_option': False,
|
||||
'name': self.name,
|
||||
'name': name,
|
||||
'description': self.__doc__,
|
||||
'isolated': isolated,
|
||||
}
|
||||
|
||||
self.name = name
|
||||
self.summary = summary
|
||||
self.parser = ConfigOptionParser(**parser_kw)
|
||||
|
||||
self.tempdir_registry = None # type: Optional[TempDirRegistry]
|
||||
|
||||
# Commands should add options to this option group
|
||||
optgroup_name = '%s Options' % self.name.capitalize()
|
||||
optgroup_name = '{} Options'.format(self.name.capitalize())
|
||||
self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name)
|
||||
|
||||
# Add the general options
|
||||
@@ -78,69 +89,49 @@ class Command(object):
|
||||
)
|
||||
self.parser.add_option_group(gen_opts)
|
||||
|
||||
self.add_options()
|
||||
|
||||
def add_options(self):
|
||||
# type: () -> None
|
||||
pass
|
||||
|
||||
def handle_pip_version_check(self, options):
|
||||
# type: (Values) -> None
|
||||
"""
|
||||
This is a no-op so that commands by default do not do the pip version
|
||||
check.
|
||||
"""
|
||||
# Make sure we do the pip version check if the index_group options
|
||||
# are present.
|
||||
assert not hasattr(options, 'no_index')
|
||||
|
||||
def run(self, options, args):
|
||||
# type: (Values, List[Any]) -> Any
|
||||
# type: (Values, List[Any]) -> int
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def _get_index_urls(cls, options):
|
||||
"""Return a list of index urls from user-provided options."""
|
||||
index_urls = []
|
||||
if not getattr(options, "no_index", False):
|
||||
url = getattr(options, "index_url", None)
|
||||
if url:
|
||||
index_urls.append(url)
|
||||
urls = getattr(options, "extra_index_urls", None)
|
||||
if urls:
|
||||
index_urls.extend(urls)
|
||||
# Return None rather than an empty list
|
||||
return index_urls or None
|
||||
|
||||
def _build_session(self, options, retries=None, timeout=None):
|
||||
# type: (Values, Optional[int], Optional[int]) -> PipSession
|
||||
session = PipSession(
|
||||
cache=(
|
||||
normalize_path(os.path.join(options.cache_dir, "http"))
|
||||
if options.cache_dir else None
|
||||
),
|
||||
retries=retries if retries is not None else options.retries,
|
||||
insecure_hosts=options.trusted_hosts,
|
||||
index_urls=self._get_index_urls(options),
|
||||
)
|
||||
|
||||
# Handle custom ca-bundles from the user
|
||||
if options.cert:
|
||||
session.verify = options.cert
|
||||
|
||||
# Handle SSL client certificate
|
||||
if options.client_cert:
|
||||
session.cert = options.client_cert
|
||||
|
||||
# Handle timeouts
|
||||
if options.timeout or timeout:
|
||||
session.timeout = (
|
||||
timeout if timeout is not None else options.timeout
|
||||
)
|
||||
|
||||
# Handle configured proxies
|
||||
if options.proxy:
|
||||
session.proxies = {
|
||||
"http": options.proxy,
|
||||
"https": options.proxy,
|
||||
}
|
||||
|
||||
# Determine if we can prompt the user for authentication or not
|
||||
session.auth.prompting = not options.no_input
|
||||
|
||||
return session
|
||||
|
||||
def parse_args(self, args):
|
||||
# type: (List[str]) -> Tuple
|
||||
# type: (List[str]) -> Tuple[Any, Any]
|
||||
# factored out for testability
|
||||
return self.parser.parse_args(args)
|
||||
|
||||
def main(self, args):
|
||||
# type: (List[str]) -> int
|
||||
try:
|
||||
with self.main_context():
|
||||
return self._main(args)
|
||||
finally:
|
||||
logging.shutdown()
|
||||
|
||||
def _main(self, args):
|
||||
# type: (List[str]) -> int
|
||||
# We must initialize this before the tempdir manager, otherwise the
|
||||
# configuration would not be accessible by the time we clean up the
|
||||
# tempdir manager.
|
||||
self.tempdir_registry = self.enter_context(tempdir_registry())
|
||||
# Intentionally set as early as possible so globally-managed temporary
|
||||
# directories are available to the rest of the code.
|
||||
self.enter_context(global_tempdir_manager())
|
||||
|
||||
options, args = self.parse_args(args)
|
||||
|
||||
# Set verbosity so that it can be used elsewhere.
|
||||
@@ -152,19 +143,34 @@ class Command(object):
|
||||
user_log_file=options.log,
|
||||
)
|
||||
|
||||
if sys.version_info[:2] == (2, 7):
|
||||
if (
|
||||
sys.version_info[:2] == (2, 7) and
|
||||
not options.no_python_version_warning
|
||||
):
|
||||
message = (
|
||||
"A future version of pip will drop support for Python 2.7. "
|
||||
"More details about Python 2 support in pip, can be found at "
|
||||
"pip 21.0 will drop support for Python 2.7 in January 2021. "
|
||||
"More details about Python 2 support in pip can be found at "
|
||||
"https://pip.pypa.io/en/latest/development/release-process/#python-2-support" # noqa
|
||||
)
|
||||
if platform.python_implementation() == "CPython":
|
||||
message = (
|
||||
"Python 2.7 will reach the end of its life on January "
|
||||
"Python 2.7 reached the end of its life on January "
|
||||
"1st, 2020. Please upgrade your Python as Python 2.7 "
|
||||
"won't be maintained after that date. "
|
||||
"is no longer maintained. "
|
||||
) + message
|
||||
deprecated(message, replacement=None, gone_in=None)
|
||||
deprecated(message, replacement=None, gone_in="21.0")
|
||||
|
||||
if (
|
||||
sys.version_info[:2] == (3, 5) and
|
||||
not options.no_python_version_warning
|
||||
):
|
||||
message = (
|
||||
"Python 3.5 reached the end of its life on September "
|
||||
"13th, 2020. Please upgrade your Python as Python 3.5 "
|
||||
"is no longer maintained. pip 21.0 will drop support "
|
||||
"for Python 3.5 in January 2021."
|
||||
)
|
||||
deprecated(message, replacement=None, gone_in="21.0")
|
||||
|
||||
# TODO: Try to get these passing down from the command?
|
||||
# without resorting to os.environ to hold these.
|
||||
@@ -184,18 +190,51 @@ class Command(object):
|
||||
)
|
||||
sys.exit(VIRTUALENV_NOT_FOUND)
|
||||
|
||||
if options.cache_dir:
|
||||
options.cache_dir = normalize_path(options.cache_dir)
|
||||
if not check_path_owner(options.cache_dir):
|
||||
logger.warning(
|
||||
"The directory '%s' or its parent directory is not owned "
|
||||
"or is not writable by the current user. The cache "
|
||||
"has been disabled. Check the permissions and owner of "
|
||||
"that directory. If executing pip with sudo, you may want "
|
||||
"sudo's -H flag.",
|
||||
options.cache_dir,
|
||||
)
|
||||
options.cache_dir = None
|
||||
|
||||
if getattr(options, "build_dir", None):
|
||||
deprecated(
|
||||
reason=(
|
||||
"The -b/--build/--build-dir/--build-directory "
|
||||
"option is deprecated."
|
||||
),
|
||||
replacement=(
|
||||
"use the TMPDIR/TEMP/TMP environment variable, "
|
||||
"possibly combined with --no-clean"
|
||||
),
|
||||
gone_in="20.3",
|
||||
issue=8333,
|
||||
)
|
||||
|
||||
if 'resolver' in options.unstable_features:
|
||||
logger.critical(
|
||||
"--unstable-feature=resolver is no longer supported, and "
|
||||
"has been replaced with --use-feature=2020-resolver instead."
|
||||
)
|
||||
sys.exit(ERROR)
|
||||
|
||||
try:
|
||||
status = self.run(options, args)
|
||||
# FIXME: all commands should return an exit status
|
||||
# and when it is done, isinstance is not needed anymore
|
||||
if isinstance(status, int):
|
||||
return status
|
||||
assert isinstance(status, int)
|
||||
return status
|
||||
except PreviousBuildDirError as exc:
|
||||
logger.critical(str(exc))
|
||||
logger.debug('Exception information:', exc_info=True)
|
||||
|
||||
return PREVIOUS_BUILD_DIR_ERROR
|
||||
except (InstallationError, UninstallationError, BadCommand) as exc:
|
||||
except (InstallationError, UninstallationError, BadCommand,
|
||||
SubProcessError, NetworkConnectionError) as exc:
|
||||
logger.critical(str(exc))
|
||||
logger.debug('Exception information:', exc_info=True)
|
||||
|
||||
@@ -223,124 +262,4 @@ class Command(object):
|
||||
|
||||
return UNKNOWN_ERROR
|
||||
finally:
|
||||
allow_version_check = (
|
||||
# Does this command have the index_group options?
|
||||
hasattr(options, "no_index") and
|
||||
# Is this command allowed to perform this check?
|
||||
not (options.disable_pip_version_check or options.no_index)
|
||||
)
|
||||
# Check if we're using the latest version of pip available
|
||||
if allow_version_check:
|
||||
session = self._build_session(
|
||||
options,
|
||||
retries=0,
|
||||
timeout=min(5, options.timeout)
|
||||
)
|
||||
with session:
|
||||
pip_version_check(session, options)
|
||||
|
||||
# Shutdown the logging module
|
||||
logging.shutdown()
|
||||
|
||||
return SUCCESS
|
||||
|
||||
|
||||
class RequirementCommand(Command):
|
||||
|
||||
@staticmethod
|
||||
def populate_requirement_set(requirement_set, # type: RequirementSet
|
||||
args, # type: List[str]
|
||||
options, # type: Values
|
||||
finder, # type: PackageFinder
|
||||
session, # type: PipSession
|
||||
name, # type: str
|
||||
wheel_cache # type: Optional[WheelCache]
|
||||
):
|
||||
# type: (...) -> None
|
||||
"""
|
||||
Marshal cmd line args into a requirement set.
|
||||
"""
|
||||
# NOTE: As a side-effect, options.require_hashes and
|
||||
# requirement_set.require_hashes may be updated
|
||||
|
||||
for filename in options.constraints:
|
||||
for req_to_add in parse_requirements(
|
||||
filename,
|
||||
constraint=True, finder=finder, options=options,
|
||||
session=session, wheel_cache=wheel_cache):
|
||||
req_to_add.is_direct = True
|
||||
requirement_set.add_requirement(req_to_add)
|
||||
|
||||
for req in args:
|
||||
req_to_add = install_req_from_line(
|
||||
req, None, isolated=options.isolated_mode,
|
||||
use_pep517=options.use_pep517,
|
||||
wheel_cache=wheel_cache
|
||||
)
|
||||
req_to_add.is_direct = True
|
||||
requirement_set.add_requirement(req_to_add)
|
||||
|
||||
for req in options.editables:
|
||||
req_to_add = install_req_from_editable(
|
||||
req,
|
||||
isolated=options.isolated_mode,
|
||||
use_pep517=options.use_pep517,
|
||||
wheel_cache=wheel_cache
|
||||
)
|
||||
req_to_add.is_direct = True
|
||||
requirement_set.add_requirement(req_to_add)
|
||||
|
||||
for filename in options.requirements:
|
||||
for req_to_add in parse_requirements(
|
||||
filename,
|
||||
finder=finder, options=options, session=session,
|
||||
wheel_cache=wheel_cache,
|
||||
use_pep517=options.use_pep517):
|
||||
req_to_add.is_direct = True
|
||||
requirement_set.add_requirement(req_to_add)
|
||||
# If --require-hashes was a line in a requirements file, tell
|
||||
# RequirementSet about it:
|
||||
requirement_set.require_hashes = options.require_hashes
|
||||
|
||||
if not (args or options.editables or options.requirements):
|
||||
opts = {'name': name}
|
||||
if options.find_links:
|
||||
raise CommandError(
|
||||
'You must give at least one requirement to %(name)s '
|
||||
'(maybe you meant "pip %(name)s %(links)s"?)' %
|
||||
dict(opts, links=' '.join(options.find_links)))
|
||||
else:
|
||||
raise CommandError(
|
||||
'You must give at least one requirement to %(name)s '
|
||||
'(see "pip help %(name)s")' % opts)
|
||||
|
||||
def _build_package_finder(
|
||||
self,
|
||||
options, # type: Values
|
||||
session, # type: PipSession
|
||||
target_python=None, # type: Optional[TargetPython]
|
||||
ignore_requires_python=None, # type: Optional[bool]
|
||||
):
|
||||
# type: (...) -> PackageFinder
|
||||
"""
|
||||
Create a package finder appropriate to this requirement command.
|
||||
|
||||
:param ignore_requires_python: Whether to ignore incompatible
|
||||
"Requires-Python" values in links. Defaults to False.
|
||||
"""
|
||||
search_scope = make_search_scope(options)
|
||||
selection_prefs = SelectionPreferences(
|
||||
allow_yanked=True,
|
||||
format_control=options.format_control,
|
||||
allow_all_prereleases=options.pre,
|
||||
prefer_binary=options.prefer_binary,
|
||||
ignore_requires_python=ignore_requires_python,
|
||||
)
|
||||
|
||||
return PackageFinder.create(
|
||||
search_scope=search_scope,
|
||||
selection_prefs=selection_prefs,
|
||||
trusted_hosts=options.trusted_hosts,
|
||||
session=session,
|
||||
target_python=target_python,
|
||||
)
|
||||
self.handle_pip_version_check(options)
|
||||
|
||||
@@ -5,11 +5,14 @@ The principle here is to define options once, but *not* instantiate them
|
||||
globally. One reason being that options with action='append' can carry state
|
||||
between parses. pip parses general options twice internally, and shouldn't
|
||||
pass on state. To be consistent, all options will follow this design.
|
||||
|
||||
"""
|
||||
|
||||
# The following comment should be removed at some point in the future.
|
||||
# mypy: strict-optional=False
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import os
|
||||
import textwrap
|
||||
import warnings
|
||||
from distutils.util import strtobool
|
||||
@@ -17,26 +20,23 @@ from functools import partial
|
||||
from optparse import SUPPRESS_HELP, Option, OptionGroup
|
||||
from textwrap import dedent
|
||||
|
||||
from pip._internal.cli.progress_bars import BAR_TYPES
|
||||
from pip._internal.exceptions import CommandError
|
||||
from pip._internal.locations import USER_CACHE_DIR, get_src_prefix
|
||||
from pip._internal.models.format_control import FormatControl
|
||||
from pip._internal.models.index import PyPI
|
||||
from pip._internal.models.search_scope import SearchScope
|
||||
from pip._internal.models.target_python import TargetPython
|
||||
from pip._internal.utils.hashes import STRONG_HASHES
|
||||
from pip._internal.utils.misc import redact_password_from_url
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
from pip._internal.utils.ui import BAR_TYPES
|
||||
|
||||
if MYPY_CHECK_RUNNING:
|
||||
from typing import Any, Callable, Dict, Optional, Tuple
|
||||
from optparse import OptionParser, Values
|
||||
from pip._internal.cli.parser import ConfigOptionParser
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def raise_option_error(parser, option, msg):
|
||||
# type: (OptionParser, Option, str) -> None
|
||||
"""
|
||||
Raise an option parsing error using parser.error().
|
||||
|
||||
@@ -75,14 +75,15 @@ def check_install_build_global(options, check_options=None):
|
||||
check_options = options
|
||||
|
||||
def getname(n):
|
||||
# type: (str) -> Optional[Any]
|
||||
return getattr(check_options, n, None)
|
||||
names = ["build_options", "global_options", "install_options"]
|
||||
if any(map(getname, names)):
|
||||
control = options.format_control
|
||||
control.disallow_binaries()
|
||||
warnings.warn(
|
||||
'Disabling all use of wheels due to the use of --build-options '
|
||||
'/ --global-options / --install-options.', stacklevel=2,
|
||||
'Disabling all use of wheels due to the use of --build-option '
|
||||
'/ --global-option / --install-option.', stacklevel=2,
|
||||
)
|
||||
|
||||
|
||||
@@ -126,6 +127,17 @@ def check_dist_restriction(options, check_target=False):
|
||||
)
|
||||
|
||||
|
||||
def _path_option_check(option, opt, value):
|
||||
# type: (Option, str, str) -> str
|
||||
return os.path.expanduser(value)
|
||||
|
||||
|
||||
class PipOption(Option):
|
||||
TYPES = Option.TYPES + ("path",)
|
||||
TYPE_CHECKER = Option.TYPE_CHECKER.copy()
|
||||
TYPE_CHECKER["path"] = _path_option_check
|
||||
|
||||
|
||||
###########
|
||||
# options #
|
||||
###########
|
||||
@@ -213,10 +225,11 @@ progress_bar = partial(
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
log = partial(
|
||||
Option,
|
||||
PipOption,
|
||||
"--log", "--log-file", "--local-log",
|
||||
dest="log",
|
||||
metavar="path",
|
||||
type="path",
|
||||
help="Path to a verbose appending log."
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
@@ -227,7 +240,7 @@ no_input = partial(
|
||||
dest='no_input',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help=SUPPRESS_HELP
|
||||
help="Disable prompting for input."
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
proxy = partial(
|
||||
@@ -259,16 +272,6 @@ timeout = partial(
|
||||
help='Set the socket timeout (default %default seconds).',
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
skip_requirements_regex = partial(
|
||||
Option,
|
||||
# A regex to be used to skip requirements
|
||||
'--skip-requirements-regex',
|
||||
dest='skip_requirements_regex',
|
||||
type='str',
|
||||
default='',
|
||||
help=SUPPRESS_HELP,
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
def exists_action():
|
||||
# type: () -> Option
|
||||
@@ -287,19 +290,19 @@ def exists_action():
|
||||
|
||||
|
||||
cert = partial(
|
||||
Option,
|
||||
PipOption,
|
||||
'--cert',
|
||||
dest='cert',
|
||||
type='str',
|
||||
type='path',
|
||||
metavar='path',
|
||||
help="Path to alternate CA bundle.",
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
client_cert = partial(
|
||||
Option,
|
||||
PipOption,
|
||||
'--client-cert',
|
||||
dest='client_cert',
|
||||
type='str',
|
||||
type='path',
|
||||
default=None,
|
||||
metavar='path',
|
||||
help="Path to SSL client certificate, a single file containing the "
|
||||
@@ -320,6 +323,7 @@ index_url = partial(
|
||||
|
||||
|
||||
def extra_index_url():
|
||||
# type: () -> Option
|
||||
return Option(
|
||||
'--extra-index-url',
|
||||
dest='extra_index_urls',
|
||||
@@ -350,36 +354,14 @@ def find_links():
|
||||
action='append',
|
||||
default=[],
|
||||
metavar='url',
|
||||
help="If a url or path to an html file, then parse for links to "
|
||||
"archives. If a local path or file:// url that's a directory, "
|
||||
"then look for archives in the directory listing.",
|
||||
help="If a URL or path to an html file, then parse for links to "
|
||||
"archives such as sdist (.tar.gz) or wheel (.whl) files. "
|
||||
"If a local path or file:// URL that's a directory, "
|
||||
"then look for archives in the directory listing. "
|
||||
"Links to VCS project URLs are not supported.",
|
||||
)
|
||||
|
||||
|
||||
def make_search_scope(options, suppress_no_index=False):
|
||||
# type: (Values, bool) -> SearchScope
|
||||
"""
|
||||
:param suppress_no_index: Whether to ignore the --no-index option
|
||||
when constructing the SearchScope object.
|
||||
"""
|
||||
index_urls = [options.index_url] + options.extra_index_urls
|
||||
if options.no_index and not suppress_no_index:
|
||||
logger.debug(
|
||||
'Ignoring indexes: %s',
|
||||
','.join(redact_password_from_url(url) for url in index_urls),
|
||||
)
|
||||
index_urls = []
|
||||
|
||||
# Make sure find_links is a list before passing to create().
|
||||
find_links = options.find_links or []
|
||||
|
||||
search_scope = SearchScope.create(
|
||||
find_links=find_links, index_urls=index_urls,
|
||||
)
|
||||
|
||||
return search_scope
|
||||
|
||||
|
||||
def trusted_host():
|
||||
# type: () -> Option
|
||||
return Option(
|
||||
@@ -388,8 +370,8 @@ def trusted_host():
|
||||
action="append",
|
||||
metavar="HOSTNAME",
|
||||
default=[],
|
||||
help="Mark this host as trusted, even though it does not have valid "
|
||||
"or any HTTPS.",
|
||||
help="Mark this host or host:port pair as trusted, even though it "
|
||||
"does not have valid or any HTTPS.",
|
||||
)
|
||||
|
||||
|
||||
@@ -432,12 +414,21 @@ def editable():
|
||||
)
|
||||
|
||||
|
||||
def _handle_src(option, opt_str, value, parser):
|
||||
# type: (Option, str, str, OptionParser) -> None
|
||||
value = os.path.abspath(value)
|
||||
setattr(parser.values, option.dest, value)
|
||||
|
||||
|
||||
src = partial(
|
||||
Option,
|
||||
PipOption,
|
||||
'--src', '--source', '--source-dir', '--source-directory',
|
||||
dest='src_dir',
|
||||
type='path',
|
||||
metavar='dir',
|
||||
default=get_src_prefix(),
|
||||
action='callback',
|
||||
callback=_handle_src,
|
||||
help='Directory to check out editable projects into. '
|
||||
'The default in a virtualenv is "<venv path>/src". '
|
||||
'The default for global installs is "<current dir>/src".'
|
||||
@@ -473,12 +464,12 @@ def no_binary():
|
||||
"--no-binary", dest="format_control", action="callback",
|
||||
callback=_handle_no_binary, type="str",
|
||||
default=format_control,
|
||||
help="Do not use binary packages. Can be supplied multiple times, and "
|
||||
"each time adds to the existing value. Accepts either :all: to "
|
||||
"disable all binary packages, :none: to empty the set, or one or "
|
||||
"more package names with commas between them. Note that some "
|
||||
"packages are tricky to compile and may fail to install when "
|
||||
"this option is used on them.",
|
||||
help='Do not use binary packages. Can be supplied multiple times, and '
|
||||
'each time adds to the existing value. Accepts either ":all:" to '
|
||||
'disable all binary packages, ":none:" to empty the set (notice '
|
||||
'the colons), or one or more package names with commas between '
|
||||
'them (no colons). Note that some packages are tricky to compile '
|
||||
'and may fail to install when this option is used on them.',
|
||||
)
|
||||
|
||||
|
||||
@@ -489,12 +480,12 @@ def only_binary():
|
||||
"--only-binary", dest="format_control", action="callback",
|
||||
callback=_handle_only_binary, type="str",
|
||||
default=format_control,
|
||||
help="Do not use source packages. Can be supplied multiple times, and "
|
||||
"each time adds to the existing value. Accepts either :all: to "
|
||||
"disable all source packages, :none: to empty the set, or one or "
|
||||
"more package names with commas between them. Packages without "
|
||||
"binary distributions will fail to install when this option is "
|
||||
"used on them.",
|
||||
help='Do not use source packages. Can be supplied multiple times, and '
|
||||
'each time adds to the existing value. Accepts either ":all:" to '
|
||||
'disable all source packages, ":none:" to empty the set, or one '
|
||||
'or more package names with commas between them. Packages '
|
||||
'without binary distributions will fail to install when this '
|
||||
'option is used on them.',
|
||||
)
|
||||
|
||||
|
||||
@@ -636,11 +627,12 @@ def prefer_binary():
|
||||
|
||||
|
||||
cache_dir = partial(
|
||||
Option,
|
||||
PipOption,
|
||||
"--cache-dir",
|
||||
dest="cache_dir",
|
||||
default=USER_CACHE_DIR,
|
||||
metavar="dir",
|
||||
type='path',
|
||||
help="Store the cache data in <dir>."
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
@@ -691,12 +683,24 @@ no_deps = partial(
|
||||
help="Don't install package dependencies.",
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
def _handle_build_dir(option, opt, value, parser):
|
||||
# type: (Option, str, str, OptionParser) -> None
|
||||
if value:
|
||||
value = os.path.abspath(value)
|
||||
setattr(parser.values, option.dest, value)
|
||||
|
||||
|
||||
build_dir = partial(
|
||||
Option,
|
||||
PipOption,
|
||||
'-b', '--build', '--build-dir', '--build-directory',
|
||||
dest='build_dir',
|
||||
type='path',
|
||||
metavar='dir',
|
||||
help='Directory to unpack packages into and build in. Note that '
|
||||
action='callback',
|
||||
callback=_handle_build_dir,
|
||||
help='(DEPRECATED) '
|
||||
'Directory to unpack packages into and build in. Note that '
|
||||
'an initial build still takes place in a temporary directory. '
|
||||
'The location of temporary directories can be controlled by setting '
|
||||
'the TMPDIR environment variable (TEMP on Windows) appropriately. '
|
||||
@@ -818,16 +822,6 @@ disable_pip_version_check = partial(
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
# Deprecated, Remove later
|
||||
always_unzip = partial(
|
||||
Option,
|
||||
'-Z', '--always-unzip',
|
||||
dest='always_unzip',
|
||||
action='store_true',
|
||||
help=SUPPRESS_HELP,
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
def _handle_merge_hash(option, opt_str, value, parser):
|
||||
# type: (Option, str, str, OptionParser) -> None
|
||||
"""Given a value spelled "algo:digest", append the digest to a list
|
||||
@@ -837,12 +831,12 @@ def _handle_merge_hash(option, opt_str, value, parser):
|
||||
try:
|
||||
algo, digest = value.split(':', 1)
|
||||
except ValueError:
|
||||
parser.error('Arguments to %s must be a hash name '
|
||||
'followed by a value, like --hash=sha256:abcde...' %
|
||||
opt_str)
|
||||
parser.error('Arguments to {} must be a hash name ' # noqa
|
||||
'followed by a value, like --hash=sha256:'
|
||||
'abcde...'.format(opt_str))
|
||||
if algo not in STRONG_HASHES:
|
||||
parser.error('Allowed hash algorithms for %s are %s.' %
|
||||
(opt_str, ', '.join(STRONG_HASHES)))
|
||||
parser.error('Allowed hash algorithms for {} are {}.'.format( # noqa
|
||||
opt_str, ', '.join(STRONG_HASHES)))
|
||||
parser.values.hashes.setdefault(algo, []).append(digest)
|
||||
|
||||
|
||||
@@ -873,9 +867,10 @@ require_hashes = partial(
|
||||
|
||||
|
||||
list_path = partial(
|
||||
Option,
|
||||
PipOption,
|
||||
'--path',
|
||||
dest='path',
|
||||
type='path',
|
||||
action='append',
|
||||
help='Restrict to the specified installation path for listing '
|
||||
'packages (can be used multiple times).'
|
||||
@@ -890,6 +885,52 @@ def check_list_path_option(options):
|
||||
)
|
||||
|
||||
|
||||
no_python_version_warning = partial(
|
||||
Option,
|
||||
'--no-python-version-warning',
|
||||
dest='no_python_version_warning',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help='Silence deprecation warnings for upcoming unsupported Pythons.',
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
unstable_feature = partial(
|
||||
Option,
|
||||
'--unstable-feature',
|
||||
dest='unstable_features',
|
||||
metavar='feature',
|
||||
action='append',
|
||||
default=[],
|
||||
choices=['resolver'],
|
||||
help=SUPPRESS_HELP, # TODO: drop this in pip 20.3
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
use_new_feature = partial(
|
||||
Option,
|
||||
'--use-feature',
|
||||
dest='features_enabled',
|
||||
metavar='feature',
|
||||
action='append',
|
||||
default=[],
|
||||
choices=['2020-resolver', 'fast-deps'],
|
||||
help='Enable new functionality, that may be backward incompatible.',
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
use_deprecated_feature = partial(
|
||||
Option,
|
||||
'--use-deprecated',
|
||||
dest='deprecated_features_enabled',
|
||||
metavar='feature',
|
||||
action='append',
|
||||
default=[],
|
||||
choices=[],
|
||||
help=(
|
||||
'Enable deprecated functionality, that will be removed in the future.'
|
||||
),
|
||||
) # type: Callable[..., Option]
|
||||
|
||||
|
||||
##########
|
||||
# groups #
|
||||
##########
|
||||
@@ -908,7 +949,6 @@ general_group = {
|
||||
proxy,
|
||||
retries,
|
||||
timeout,
|
||||
skip_requirements_regex,
|
||||
exists_action,
|
||||
trusted_host,
|
||||
cert,
|
||||
@@ -917,6 +957,10 @@ general_group = {
|
||||
no_cache,
|
||||
disable_pip_version_check,
|
||||
no_color,
|
||||
no_python_version_warning,
|
||||
unstable_feature,
|
||||
use_new_feature,
|
||||
use_deprecated_feature,
|
||||
]
|
||||
} # type: Dict[str, Any]
|
||||
|
||||
|
||||
@@ -6,11 +6,10 @@ import sys
|
||||
|
||||
from pip._internal.cli import cmdoptions
|
||||
from pip._internal.cli.parser import (
|
||||
ConfigOptionParser, UpdatingDefaultsHelpFormatter,
|
||||
)
|
||||
from pip._internal.commands import (
|
||||
commands_dict, get_similar_commands, get_summaries,
|
||||
ConfigOptionParser,
|
||||
UpdatingDefaultsHelpFormatter,
|
||||
)
|
||||
from pip._internal.commands import commands_dict, get_similar_commands
|
||||
from pip._internal.exceptions import CommandError
|
||||
from pip._internal.utils.misc import get_pip_version, get_prog
|
||||
from pip._internal.utils.typing import MYPY_CHECK_RUNNING
|
||||
@@ -48,8 +47,10 @@ def create_main_parser():
|
||||
parser.main = True # type: ignore
|
||||
|
||||
# create command listing for description
|
||||
command_summaries = get_summaries()
|
||||
description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries]
|
||||
description = [''] + [
|
||||
'{name:27} {command_info.summary}'.format(**locals())
|
||||
for name, command_info in commands_dict.items()
|
||||
]
|
||||
parser.description = '\n'.join(description)
|
||||
|
||||
return parser
|
||||
@@ -85,9 +86,9 @@ def parse_command(args):
|
||||
if cmd_name not in commands_dict:
|
||||
guess = get_similar_commands(cmd_name)
|
||||
|
||||
msg = ['unknown command "%s"' % cmd_name]
|
||||
msg = ['unknown command "{}"'.format(cmd_name)]
|
||||
if guess:
|
||||
msg.append('maybe you meant "%s"' % guess)
|
||||
msg.append('maybe you meant "{}"'.format(guess))
|
||||
|
||||
raise CommandError(' - '.join(msg))
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
"""Base option parser setup"""
|
||||
|
||||
# The following comment should be removed at some point in the future.
|
||||
# mypy: disallow-untyped-defs=False
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
@@ -27,14 +31,14 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
||||
optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs)
|
||||
|
||||
def format_option_strings(self, option):
|
||||
return self._format_option_strings(option, ' <%s>', ', ')
|
||||
return self._format_option_strings(option)
|
||||
|
||||
def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '):
|
||||
def _format_option_strings(self, option, mvarfmt=' <{}>', optsep=', '):
|
||||
"""
|
||||
Return a comma-separated list of option strings and metavars.
|
||||
|
||||
:param option: tuple of (short opt, long opt), e.g: ('-f', '--format')
|
||||
:param mvarfmt: metavar format string - evaluated as mvarfmt % metavar
|
||||
:param mvarfmt: metavar format string
|
||||
:param optsep: separator
|
||||
"""
|
||||
opts = []
|
||||
@@ -48,7 +52,7 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
||||
|
||||
if option.takes_value():
|
||||
metavar = option.metavar or option.dest.lower()
|
||||
opts.append(mvarfmt % metavar.lower())
|
||||
opts.append(mvarfmt.format(metavar.lower()))
|
||||
|
||||
return ''.join(opts)
|
||||
|
||||
@@ -62,7 +66,8 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
||||
Ensure there is only one newline between usage and the first heading
|
||||
if there is no description.
|
||||
"""
|
||||
msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ")
|
||||
msg = '\nUsage: {}\n'.format(
|
||||
self.indent_lines(textwrap.dedent(usage), " "))
|
||||
return msg
|
||||
|
||||
def format_description(self, description):
|
||||
@@ -78,7 +83,7 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
|
||||
description = description.rstrip()
|
||||
# dedent, then reindent
|
||||
description = self.indent_lines(textwrap.dedent(description), " ")
|
||||
description = '%s:\n%s\n' % (label, description)
|
||||
description = '{}:\n{}\n'.format(label, description)
|
||||
return description
|
||||
else:
|
||||
return ''
|
||||
@@ -146,7 +151,7 @@ class ConfigOptionParser(CustomOptionParser):
|
||||
try:
|
||||
return option.check_value(key, val)
|
||||
except optparse.OptionValueError as exc:
|
||||
print("An error occurred during configuration: %s" % exc)
|
||||
print("An error occurred during configuration: {}".format(exc))
|
||||
sys.exit(3)
|
||||
|
||||
def _get_ordered_configuration_items(self):
|
||||
@@ -245,7 +250,7 @@ class ConfigOptionParser(CustomOptionParser):
|
||||
|
||||
def error(self, msg):
|
||||
self.print_usage(sys.stderr)
|
||||
self.exit(UNKNOWN_ERROR, "%s\n" % msg)
|
||||
self.exit(UNKNOWN_ERROR, "{}\n".format(msg))
|
||||
|
||||
|
||||
def invalid_config_error_message(action, key, val):
|
||||
|
||||
Reference in New Issue
Block a user