1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Merge pull request #9635 from jdufresne/blacken-cli

Blacken src/pip/_internal/cli directory
This commit is contained in:
Tzu-ping Chung 2021-02-23 04:30:42 +08:00 committed by GitHub
commit d37fdf27d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 518 additions and 471 deletions

View file

@ -23,7 +23,6 @@ repos:
exclude: |
(?x)
^docs/|
^src/pip/_internal/cli|
^src/pip/_internal/commands|
^src/pip/_internal/distributions|
^src/pip/_internal/index|

View file

@ -14,17 +14,16 @@ from pip._internal.utils.misc import get_installed_distributions
def autocomplete():
# type: () -> None
"""Entry Point for completion of main and subcommand options.
"""
"""Entry Point for completion of main and subcommand options."""
# Don't complete if user hasn't sourced bash_completion file.
if 'PIP_AUTO_COMPLETE' not in os.environ:
if "PIP_AUTO_COMPLETE" not in os.environ:
return
cwords = os.environ['COMP_WORDS'].split()[1:]
cword = int(os.environ['COMP_CWORD'])
cwords = os.environ["COMP_WORDS"].split()[1:]
cword = int(os.environ["COMP_CWORD"])
try:
current = cwords[cword - 1]
except IndexError:
current = ''
current = ""
parser = create_main_parser()
subcommands = list(commands_dict)
@ -39,13 +38,13 @@ def autocomplete():
# subcommand options
if subcommand_name is not None:
# special case: 'help' subcommand has no options
if subcommand_name == 'help':
if subcommand_name == "help":
sys.exit(1)
# special case: list locally installed dists for show and uninstall
should_list_installed = (
subcommand_name in ['show', 'uninstall'] and
not current.startswith('-')
)
should_list_installed = not current.startswith("-") and subcommand_name in [
"show",
"uninstall",
]
if should_list_installed:
lc = current.lower()
installed = [
@ -67,13 +66,15 @@ def autocomplete():
options.append((opt_str, opt.nargs))
# filter out previously specified options from available options
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
prev_opts = [x.split("=")[0] for x in cwords[1 : cword - 1]]
options = [(x, v) for (x, v) in options if x not in prev_opts]
# filter options by current input
options = [(k, v) for k, v in options if k.startswith(current)]
# get completion type given cwords and available subcommand options
completion_type = get_path_completion_type(
cwords, cword, subcommand.parser.option_list_all,
cwords,
cword,
subcommand.parser.option_list_all,
)
# get completion files and directories if ``completion_type`` is
# ``<file>``, ``<dir>`` or ``<path>``
@ -84,7 +85,7 @@ def autocomplete():
opt_label = option[0]
# append '=' to options which require args
if option[1] and option[0][:2] == "--":
opt_label += '='
opt_label += "="
print(opt_label)
else:
# show main parser options only when necessary
@ -92,19 +93,17 @@ def autocomplete():
opts = [i.option_list for i in parser.option_groups]
opts.append(parser.option_list)
flattened_opts = chain.from_iterable(opts)
if current.startswith('-'):
if current.startswith("-"):
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,
flattened_opts)
completion_type = get_path_completion_type(cwords, cword, flattened_opts)
if completion_type:
subcommands = list(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)]))
print(" ".join([x for x in subcommands if x.startswith(current)]))
sys.exit(1)
@ -117,16 +116,16 @@ def get_path_completion_type(cwords, cword, opts):
:param opts: The available options to check
:return: path completion type (``file``, ``dir``, ``path`` or None)
"""
if cword < 2 or not cwords[cword - 2].startswith('-'):
if cword < 2 or not cwords[cword - 2].startswith("-"):
return None
for opt in opts:
if opt.help == optparse.SUPPRESS_HELP:
continue
for o in str(opt).split('/'):
if cwords[cword - 2].split('=')[0] == o:
for o in str(opt).split("/"):
if cwords[cword - 2].split("=")[0] == o:
if not opt.metavar or any(
x in ('path', 'file', 'dir')
for x in opt.metavar.split('/')):
x in ("path", "file", "dir") for x in opt.metavar.split("/")
):
return opt.metavar
return None
@ -148,15 +147,16 @@ def auto_complete_paths(current, completion_type):
return
filename = os.path.normcase(filename)
# list all files that start with ``filename``
file_list = (x for x in os.listdir(current_path)
if os.path.normcase(x).startswith(filename))
file_list = (
x for x in os.listdir(current_path) if os.path.normcase(x).startswith(filename)
)
for f in file_list:
opt = os.path.join(current_path, f)
comp_file = os.path.normcase(os.path.join(directory, f))
# complete regular files when there is not ``<dir>`` after option
# complete directories when there is ``<file>``, ``<path>`` or
# ``<dir>``after option
if completion_type != 'dir' and os.path.isfile(opt):
if completion_type != "dir" and os.path.isfile(opt):
yield comp_file
elif os.path.isdir(opt):
yield os.path.join(comp_file, '')
yield os.path.join(comp_file, "")

View file

@ -34,7 +34,7 @@ from pip._internal.utils.temp_dir import TempDirectoryTypeRegistry as TempDirReg
from pip._internal.utils.temp_dir import global_tempdir_manager, tempdir_registry
from pip._internal.utils.virtualenv import running_under_virtualenv
__all__ = ['Command']
__all__ = ["Command"]
logger = logging.getLogger(__name__)
@ -51,7 +51,7 @@ class Command(CommandContextMixIn):
self.summary = summary
self.parser = ConfigOptionParser(
usage=self.usage,
prog=f'{get_prog()} {name}',
prog=f"{get_prog()} {name}",
formatter=UpdatingDefaultsHelpFormatter(),
add_help_option=False,
name=name,
@ -62,7 +62,7 @@ class Command(CommandContextMixIn):
self.tempdir_registry = None # type: Optional[TempDirRegistry]
# Commands should add options to this option group
optgroup_name = f'{self.name.capitalize()} Options'
optgroup_name = f"{self.name.capitalize()} Options"
self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name)
# Add the general options
@ -86,7 +86,7 @@ class Command(CommandContextMixIn):
"""
# Make sure we do the pip version check if the index_group options
# are present.
assert not hasattr(options, 'no_index')
assert not hasattr(options, "no_index")
def run(self, options, args):
# type: (Values, List[Any]) -> int
@ -131,17 +131,15 @@ class Command(CommandContextMixIn):
# This also affects isolated builds and it should.
if options.no_input:
os.environ['PIP_NO_INPUT'] = '1'
os.environ["PIP_NO_INPUT"] = "1"
if options.exists_action:
os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action)
os.environ["PIP_EXISTS_ACTION"] = " ".join(options.exists_action)
if options.require_venv and not self.ignore_require_venv:
# If a venv is required check if it can really be found
if not running_under_virtualenv():
logger.critical(
'Could not find an activated virtualenv (required).'
)
logger.critical("Could not find an activated virtualenv (required).")
sys.exit(VIRTUALENV_NOT_FOUND)
if options.cache_dir:
@ -171,7 +169,7 @@ class Command(CommandContextMixIn):
issue=8333,
)
if '2020-resolver' in options.features_enabled:
if "2020-resolver" in options.features_enabled:
logger.warning(
"--use-feature=2020-resolver no longer has any effect, "
"since it is now the default dependency resolver in pip. "
@ -184,35 +182,39 @@ class Command(CommandContextMixIn):
return status
except PreviousBuildDirError as exc:
logger.critical(str(exc))
logger.debug('Exception information:', exc_info=True)
logger.debug("Exception information:", exc_info=True)
return PREVIOUS_BUILD_DIR_ERROR
except (InstallationError, UninstallationError, BadCommand,
NetworkConnectionError) as exc:
except (
InstallationError,
UninstallationError,
BadCommand,
NetworkConnectionError,
) as exc:
logger.critical(str(exc))
logger.debug('Exception information:', exc_info=True)
logger.debug("Exception information:", exc_info=True)
return ERROR
except CommandError as exc:
logger.critical('%s', exc)
logger.debug('Exception information:', exc_info=True)
logger.critical("%s", exc)
logger.debug("Exception information:", exc_info=True)
return ERROR
except BrokenStdoutLoggingError:
# Bypass our logger and write any remaining messages to stderr
# because stdout no longer works.
print('ERROR: Pipe to stdout was broken', file=sys.stderr)
print("ERROR: Pipe to stdout was broken", file=sys.stderr)
if level_number <= logging.DEBUG:
traceback.print_exc(file=sys.stderr)
return ERROR
except KeyboardInterrupt:
logger.critical('Operation cancelled by user')
logger.debug('Exception information:', exc_info=True)
logger.critical("Operation cancelled by user")
logger.debug("Exception information:", exc_info=True)
return ERROR
except BaseException:
logger.critical('Exception:', exc_info=True)
logger.critical("Exception:", exc_info=True)
return UNKNOWN_ERROR
finally:

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
from contextlib import ExitStack, contextmanager
from typing import ContextManager, Iterator, TypeVar
_T = TypeVar('_T', covariant=True)
_T = TypeVar("_T", covariant=True)
class CommandContextMixIn:

View file

@ -41,6 +41,7 @@ logger = logging.getLogger(__name__)
# call to main. As it is not safe to do any processing after calling
# main, this should not be an issue in practice.
def main(args=None):
# type: (Optional[List[str]]) -> int
if args is None:
@ -61,7 +62,7 @@ def main(args=None):
# Needed for locale.getpreferredencoding(False) to work
# in pip._internal.utils.encoding.auto_decode
try:
locale.setlocale(locale.LC_ALL, '')
locale.setlocale(locale.LC_ALL, "")
except locale.Error as e:
# setlocale can apparently crash if locale are uninitialized
logger.debug("Ignoring error %s when setting locale", e)

View file

@ -16,14 +16,13 @@ __all__ = ["create_main_parser", "parse_command"]
def create_main_parser():
# type: () -> ConfigOptionParser
"""Creates and returns the main parser for pip's CLI
"""
"""Creates and returns the main parser for pip's CLI"""
parser = ConfigOptionParser(
usage='\n%prog <command> [options]',
usage="\n%prog <command> [options]",
add_help_option=False,
formatter=UpdatingDefaultsHelpFormatter(),
name='global',
name="global",
prog=get_prog(),
)
parser.disable_interspersed_args()
@ -38,11 +37,11 @@ def create_main_parser():
parser.main = True # type: ignore
# create command listing for description
description = [''] + [
f'{name:27} {command_info.summary}'
description = [""] + [
f"{name:27} {command_info.summary}"
for name, command_info in commands_dict.items()
]
parser.description = '\n'.join(description)
parser.description = "\n".join(description)
return parser
@ -67,7 +66,7 @@ def parse_command(args):
sys.exit()
# pip || pip help -> print_help()
if not args_else or (args_else[0] == 'help' and len(args_else) == 1):
if not args_else or (args_else[0] == "help" and len(args_else) == 1):
parser.print_help()
sys.exit()
@ -81,7 +80,7 @@ def parse_command(args):
if guess:
msg.append(f'maybe you meant "{guess}"')
raise CommandError(' - '.join(msg))
raise CommandError(" - ".join(msg))
# all the args without the subcommand
cmd_args = args[:]

View file

@ -23,15 +23,15 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
def __init__(self, *args, **kwargs):
# help position must be aligned with __init__.parseopts.description
kwargs['max_help_position'] = 30
kwargs['indent_increment'] = 1
kwargs['width'] = shutil.get_terminal_size()[0] - 2
kwargs["max_help_position"] = 30
kwargs["indent_increment"] = 1
kwargs["width"] = shutil.get_terminal_size()[0] - 2
super().__init__(*args, **kwargs)
def format_option_strings(self, option):
return self._format_option_strings(option)
def _format_option_strings(self, option, mvarfmt=' <{}>', optsep=', '):
def _format_option_strings(self, option, mvarfmt=" <{}>", optsep=", "):
"""
Return a comma-separated list of option strings and metavars.
@ -52,49 +52,48 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
metavar = option.metavar or option.dest.lower()
opts.append(mvarfmt.format(metavar.lower()))
return ''.join(opts)
return "".join(opts)
def format_heading(self, heading):
if heading == 'Options':
return ''
return heading + ':\n'
if heading == "Options":
return ""
return heading + ":\n"
def format_usage(self, usage):
"""
Ensure there is only one newline between usage and the first heading
if there is no description.
"""
msg = '\nUsage: {}\n'.format(
self.indent_lines(textwrap.dedent(usage), " "))
msg = "\nUsage: {}\n".format(self.indent_lines(textwrap.dedent(usage), " "))
return msg
def format_description(self, description):
# leave full control over description to us
if description:
if hasattr(self.parser, 'main'):
label = 'Commands'
if hasattr(self.parser, "main"):
label = "Commands"
else:
label = 'Description'
label = "Description"
# some doc strings have initial newlines, some don't
description = description.lstrip('\n')
description = description.lstrip("\n")
# some doc strings have final newlines and spaces, some don't
description = description.rstrip()
# dedent, then reindent
description = self.indent_lines(textwrap.dedent(description), " ")
description = f'{label}:\n{description}\n'
description = f"{label}:\n{description}\n"
return description
else:
return ''
return ""
def format_epilog(self, epilog):
# leave full control over epilog to us
if epilog:
return epilog
else:
return ''
return ""
def indent_lines(self, text, indent):
new_lines = [indent + line for line in text.split('\n')]
new_lines = [indent + line for line in text.split("\n")]
return "\n".join(new_lines)
@ -114,7 +113,7 @@ class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter):
default_values = self.parser.defaults.get(option.dest)
help_text = super().expand_default(option)
if default_values and option.metavar == 'URL':
if default_values and option.metavar == "URL":
if isinstance(default_values, str):
default_values = [default_values]
@ -123,14 +122,12 @@ class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter):
default_values = []
for val in default_values:
help_text = help_text.replace(
val, redact_auth_from_url(val))
help_text = help_text.replace(val, redact_auth_from_url(val))
return help_text
class CustomOptionParser(optparse.OptionParser):
def insert_option_group(self, idx, *args, **kwargs):
"""Insert an OptionGroup at a given position."""
group = self.add_option_group(*args, **kwargs)
@ -186,7 +183,7 @@ class ConfigOptionParser(CustomOptionParser):
if not val:
logger.debug(
"Ignoring configuration key '%s' as it's value is empty.",
section_key
section_key,
)
continue
@ -210,7 +207,7 @@ class ConfigOptionParser(CustomOptionParser):
# Then set the options with those values
for key, val in self._get_ordered_configuration_items():
# '--' because configuration supports only long names
option = self.get_option('--' + key)
option = self.get_option("--" + key)
# Ignore options not present in this parser. E.g. non-globals put
# in [global] by users that want them to apply to all applicable
@ -218,31 +215,31 @@ class ConfigOptionParser(CustomOptionParser):
if option is None:
continue
if option.action in ('store_true', 'store_false'):
if option.action in ("store_true", "store_false"):
try:
val = strtobool(val)
except ValueError:
self.error(
'{} is not a valid value for {} option, ' # noqa
'please specify a boolean value like yes/no, '
'true/false or 1/0 instead.'.format(val, key)
"{} is not a valid value for {} option, " # noqa
"please specify a boolean value like yes/no, "
"true/false or 1/0 instead.".format(val, key)
)
elif option.action == 'count':
elif option.action == "count":
with suppress(ValueError):
val = strtobool(val)
with suppress(ValueError):
val = int(val)
if not isinstance(val, int) or val < 0:
self.error(
'{} is not a valid value for {} option, ' # noqa
'please instead specify either a non-negative integer '
'or a boolean value like yes/no or false/true '
'which is equivalent to 1/0.'.format(val, key)
"{} is not a valid value for {} option, " # noqa
"please instead specify either a non-negative integer "
"or a boolean value like yes/no or false/true "
"which is equivalent to 1/0.".format(val, key)
)
elif option.action == 'append':
elif option.action == "append":
val = val.split()
val = [self.check_default(option, key, v) for v in val]
elif option.action == 'callback':
elif option.action == "callback":
late_eval.add(option.dest)
opt_str = option.get_opt_string()
val = option.convert_value(opt_str, val)

View file

@ -108,7 +108,6 @@ class InterruptibleMixin:
class SilentBar(Bar):
def update(self):
# type: () -> None
pass
@ -123,14 +122,11 @@ class BlueEmojiBar(IncrementalBar):
class DownloadProgressMixin:
def __init__(self, *args, **kwargs):
# type: (List[Any], Dict[Any, Any]) -> None
# https://github.com/python/mypy/issues/5887
super().__init__(*args, **kwargs) # type: ignore
self.message = (" " * (
get_indentation() + 2
)) + self.message # type: str
self.message = (" " * (get_indentation() + 2)) + self.message # type: str
@property
def downloaded(self):
@ -162,7 +158,6 @@ class DownloadProgressMixin:
class WindowsMixin:
def __init__(self, *args, **kwargs):
# type: (List[Any], Dict[Any, Any]) -> None
# The Windows terminal does not support the hide/show cursor ANSI codes
@ -192,16 +187,14 @@ class WindowsMixin:
self.file.flush = lambda: self.file.wrapped.flush()
class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin,
DownloadProgressMixin):
class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, DownloadProgressMixin):
file = sys.stdout
message = "%(percent)d%%"
suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s"
class DefaultDownloadProgressBar(BaseDownloadProgressBar,
_BaseBar):
class DefaultDownloadProgressBar(BaseDownloadProgressBar, _BaseBar):
pass
@ -209,23 +202,21 @@ class DownloadSilentBar(BaseDownloadProgressBar, SilentBar):
pass
class DownloadBar(BaseDownloadProgressBar,
Bar):
class DownloadBar(BaseDownloadProgressBar, Bar):
pass
class DownloadFillingCirclesBar(BaseDownloadProgressBar,
FillingCirclesBar):
class DownloadFillingCirclesBar(BaseDownloadProgressBar, FillingCirclesBar):
pass
class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar,
BlueEmojiBar):
class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, BlueEmojiBar):
pass
class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin,
DownloadProgressMixin, Spinner):
class DownloadProgressSpinner(
WindowsMixin, InterruptibleMixin, DownloadProgressMixin, Spinner
):
file = sys.stdout
suffix = "%(downloaded)s %(download_speed)s"
@ -241,13 +232,15 @@ class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin,
message = self.message % self
phase = self.next_phase()
suffix = self.suffix % self
line = ''.join([
message,
" " if message else "",
phase,
" " if suffix else "",
suffix,
])
line = "".join(
[
message,
" " if message else "",
phase,
" " if suffix else "",
suffix,
]
)
self.writeln(line)
@ -257,7 +250,7 @@ BAR_TYPES = {
"on": (DefaultDownloadProgressBar, DownloadProgressSpinner),
"ascii": (DownloadBar, DownloadProgressSpinner),
"pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner),
"emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner)
"emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner),
}

View file

@ -47,6 +47,7 @@ class SessionCommandMixin(CommandContextMixIn):
"""
A class mixin for command classes needing _build_session().
"""
def __init__(self):
# type: () -> None
super().__init__()
@ -83,8 +84,7 @@ class SessionCommandMixin(CommandContextMixIn):
assert not options.cache_dir or os.path.isabs(options.cache_dir)
session = PipSession(
cache=(
os.path.join(options.cache_dir, "http")
if options.cache_dir else None
os.path.join(options.cache_dir, "http") if options.cache_dir else None
),
retries=retries if retries is not None else options.retries,
trusted_hosts=options.trusted_hosts,
@ -101,9 +101,7 @@ class SessionCommandMixin(CommandContextMixIn):
# Handle timeouts
if options.timeout or timeout:
session.timeout = (
timeout if timeout is not None else options.timeout
)
session.timeout = timeout if timeout is not None else options.timeout
# Handle configured proxies
if options.proxy:
@ -134,16 +132,14 @@ class IndexGroupCommand(Command, SessionCommandMixin):
This overrides the default behavior of not doing the check.
"""
# Make sure the index_group options are present.
assert hasattr(options, 'no_index')
assert hasattr(options, "no_index")
if options.disable_pip_version_check or options.no_index:
return
# Otherwise, check if we're using the latest version of pip available.
session = self._build_session(
options,
retries=0,
timeout=min(5, options.timeout)
options, retries=0, timeout=min(5, options.timeout)
)
with session:
pip_self_version_check(session, options)
@ -161,6 +157,7 @@ def with_cleanup(func):
"""Decorator for common logic related to managing temporary
directories.
"""
def configure_tempdir_registry(registry):
# type: (TempDirectoryTypeRegistry) -> None
for t in KEEPABLE_TEMPDIR_TYPES:
@ -185,7 +182,6 @@ def with_cleanup(func):
class RequirementCommand(IndexGroupCommand):
def __init__(self, *args, **kw):
# type: (Any, Any) -> None
super().__init__(*args, **kw)
@ -204,13 +200,13 @@ class RequirementCommand(IndexGroupCommand):
@classmethod
def make_requirement_preparer(
cls,
temp_build_dir, # type: TempDirectory
options, # type: Values
req_tracker, # type: RequirementTracker
session, # type: PipSession
finder, # type: PackageFinder
use_user_site, # type: bool
download_dir=None, # type: str
temp_build_dir, # type: TempDirectory
options, # type: Values
req_tracker, # type: RequirementTracker
session, # type: PipSession
finder, # type: PackageFinder
use_user_site, # type: bool
download_dir=None, # type: str
):
# type: (...) -> RequirementPreparer
"""
@ -221,20 +217,20 @@ class RequirementCommand(IndexGroupCommand):
resolver_variant = cls.determine_resolver_variant(options)
if resolver_variant == "2020-resolver":
lazy_wheel = 'fast-deps' in options.features_enabled
lazy_wheel = "fast-deps" in options.features_enabled
if lazy_wheel:
logger.warning(
'pip is using lazily downloaded wheels using HTTP '
'range requests to obtain dependency information. '
'This experimental feature is enabled through '
'--use-feature=fast-deps and it is not ready for '
'production.'
"pip is using lazily downloaded wheels using HTTP "
"range requests to obtain dependency information. "
"This experimental feature is enabled through "
"--use-feature=fast-deps and it is not ready for "
"production."
)
else:
lazy_wheel = False
if 'fast-deps' in options.features_enabled:
if "fast-deps" in options.features_enabled:
logger.warning(
'fast-deps has no effect when used with the legacy resolver.'
"fast-deps has no effect when used with the legacy resolver."
)
return RequirementPreparer(
@ -254,17 +250,17 @@ class RequirementCommand(IndexGroupCommand):
@classmethod
def make_resolver(
cls,
preparer, # type: RequirementPreparer
finder, # type: PackageFinder
options, # type: Values
wheel_cache=None, # type: Optional[WheelCache]
use_user_site=False, # type: bool
ignore_installed=True, # type: bool
ignore_requires_python=False, # type: bool
force_reinstall=False, # type: bool
preparer, # type: RequirementPreparer
finder, # type: PackageFinder
options, # type: Values
wheel_cache=None, # type: Optional[WheelCache]
use_user_site=False, # type: bool
ignore_installed=True, # type: bool
ignore_requires_python=False, # type: bool
force_reinstall=False, # type: bool
upgrade_strategy="to-satisfy-only", # type: str
use_pep517=None, # type: Optional[bool]
py_version_info=None, # type: Optional[Tuple[int, ...]]
use_pep517=None, # type: Optional[bool]
py_version_info=None, # type: Optional[Tuple[int, ...]]
):
# type: (...) -> BaseResolver
"""
@ -296,6 +292,7 @@ class RequirementCommand(IndexGroupCommand):
py_version_info=py_version_info,
)
import pip._internal.resolution.legacy.resolver
return pip._internal.resolution.legacy.resolver.Resolver(
preparer=preparer,
finder=finder,
@ -312,10 +309,10 @@ class RequirementCommand(IndexGroupCommand):
def get_requirements(
self,
args, # type: List[str]
options, # type: Values
finder, # type: PackageFinder
session, # type: PipSession
args, # type: List[str]
options, # type: Values
finder, # type: PackageFinder
session, # type: PipSession
):
# type: (...) -> List[InstallRequirement]
"""
@ -324,9 +321,12 @@ class RequirementCommand(IndexGroupCommand):
requirements = [] # type: List[InstallRequirement]
for filename in options.constraints:
for parsed_req in parse_requirements(
filename,
constraint=True, finder=finder, options=options,
session=session):
filename,
constraint=True,
finder=finder,
options=options,
session=session,
):
req_to_add = install_req_from_parsed_requirement(
parsed_req,
isolated=options.isolated_mode,
@ -336,7 +336,9 @@ class RequirementCommand(IndexGroupCommand):
for req in args:
req_to_add = install_req_from_line(
req, None, isolated=options.isolated_mode,
req,
None,
isolated=options.isolated_mode,
use_pep517=options.use_pep517,
user_supplied=True,
)
@ -354,8 +356,8 @@ class RequirementCommand(IndexGroupCommand):
# NOTE: options.require_hashes may be set if --require-hashes is True
for filename in options.requirements:
for parsed_req in parse_requirements(
filename,
finder=finder, options=options, session=session):
filename, finder=finder, options=options, session=session
):
req_to_add = install_req_from_parsed_requirement(
parsed_req,
isolated=options.isolated_mode,
@ -369,16 +371,19 @@ class RequirementCommand(IndexGroupCommand):
options.require_hashes = True
if not (args or options.editables or options.requirements):
opts = {'name': self.name}
opts = {"name": self.name}
if options.find_links:
raise CommandError(
'You must give at least one requirement to {name} '
"You must give at least one requirement to {name} "
'(maybe you meant "pip {name} {links}"?)'.format(
**dict(opts, links=' '.join(options.find_links))))
**dict(opts, links=" ".join(options.find_links))
)
)
else:
raise CommandError(
'You must give at least one requirement to {name} '
'(see "pip help {name}")'.format(**opts))
"You must give at least one requirement to {name} "
'(see "pip help {name}")'.format(**opts)
)
return requirements
@ -396,9 +401,9 @@ class RequirementCommand(IndexGroupCommand):
def _build_package_finder(
self,
options, # type: Values
session, # type: PipSession
target_python=None, # type: Optional[TargetPython]
options, # type: Values
session, # type: PipSession
target_python=None, # type: Optional[TargetPython]
ignore_requires_python=None, # type: Optional[bool]
):
# type: (...) -> PackageFinder

View file

@ -24,9 +24,14 @@ class SpinnerInterface:
class InteractiveSpinner(SpinnerInterface):
def __init__(self, message, file=None, spin_chars="-\\|/",
# Empirically, 8 updates/second looks nice
min_update_interval_seconds=0.125):
def __init__(
self,
message,
file=None,
spin_chars="-\\|/",
# Empirically, 8 updates/second looks nice
min_update_interval_seconds=0.125,
):
# type: (str, IO[str], str, float) -> None
self._message = message
if file is None: