comparison planemo/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py @ 1:56ad4e20f292 draft

"planemo upload commit 6eee67778febed82ddd413c3ca40b3183a3898f1"
author guerler
date Fri, 31 Jul 2020 00:32:28 -0400
parents
children
comparison
equal deleted inserted replaced
0:d30785e31577 1:56ad4e20f292
1 """
2 shared options and groups
3
4 The principle here is to define options once, but *not* instantiate them
5 globally. One reason being that options with action='append' can carry state
6 between parses. pip parses general options twice internally, and shouldn't
7 pass on state. To be consistent, all options will follow this design.
8
9 """
10 from __future__ import absolute_import
11
12 import logging
13 import textwrap
14 import warnings
15 from distutils.util import strtobool
16 from functools import partial
17 from optparse import SUPPRESS_HELP, Option, OptionGroup
18 from textwrap import dedent
19
20 from pip._internal.exceptions import CommandError
21 from pip._internal.locations import USER_CACHE_DIR, get_src_prefix
22 from pip._internal.models.format_control import FormatControl
23 from pip._internal.models.index import PyPI
24 from pip._internal.models.search_scope import SearchScope
25 from pip._internal.models.target_python import TargetPython
26 from pip._internal.utils.hashes import STRONG_HASHES
27 from pip._internal.utils.misc import redact_password_from_url
28 from pip._internal.utils.typing import MYPY_CHECK_RUNNING
29 from pip._internal.utils.ui import BAR_TYPES
30
31 if MYPY_CHECK_RUNNING:
32 from typing import Any, Callable, Dict, Optional, Tuple
33 from optparse import OptionParser, Values
34 from pip._internal.cli.parser import ConfigOptionParser
35
36 logger = logging.getLogger(__name__)
37
38
39 def raise_option_error(parser, option, msg):
40 """
41 Raise an option parsing error using parser.error().
42
43 Args:
44 parser: an OptionParser instance.
45 option: an Option instance.
46 msg: the error text.
47 """
48 msg = '{} error: {}'.format(option, msg)
49 msg = textwrap.fill(' '.join(msg.split()))
50 parser.error(msg)
51
52
53 def make_option_group(group, parser):
54 # type: (Dict[str, Any], ConfigOptionParser) -> OptionGroup
55 """
56 Return an OptionGroup object
57 group -- assumed to be dict with 'name' and 'options' keys
58 parser -- an optparse Parser
59 """
60 option_group = OptionGroup(parser, group['name'])
61 for option in group['options']:
62 option_group.add_option(option())
63 return option_group
64
65
66 def check_install_build_global(options, check_options=None):
67 # type: (Values, Optional[Values]) -> None
68 """Disable wheels if per-setup.py call options are set.
69
70 :param options: The OptionParser options to update.
71 :param check_options: The options to check, if not supplied defaults to
72 options.
73 """
74 if check_options is None:
75 check_options = options
76
77 def getname(n):
78 return getattr(check_options, n, None)
79 names = ["build_options", "global_options", "install_options"]
80 if any(map(getname, names)):
81 control = options.format_control
82 control.disallow_binaries()
83 warnings.warn(
84 'Disabling all use of wheels due to the use of --build-options '
85 '/ --global-options / --install-options.', stacklevel=2,
86 )
87
88
89 def check_dist_restriction(options, check_target=False):
90 # type: (Values, bool) -> None
91 """Function for determining if custom platform options are allowed.
92
93 :param options: The OptionParser options.
94 :param check_target: Whether or not to check if --target is being used.
95 """
96 dist_restriction_set = any([
97 options.python_version,
98 options.platform,
99 options.abi,
100 options.implementation,
101 ])
102
103 binary_only = FormatControl(set(), {':all:'})
104 sdist_dependencies_allowed = (
105 options.format_control != binary_only and
106 not options.ignore_dependencies
107 )
108
109 # Installations or downloads using dist restrictions must not combine
110 # source distributions and dist-specific wheels, as they are not
111 # guaranteed to be locally compatible.
112 if dist_restriction_set and sdist_dependencies_allowed:
113 raise CommandError(
114 "When restricting platform and interpreter constraints using "
115 "--python-version, --platform, --abi, or --implementation, "
116 "either --no-deps must be set, or --only-binary=:all: must be "
117 "set and --no-binary must not be set (or must be set to "
118 ":none:)."
119 )
120
121 if check_target:
122 if dist_restriction_set and not options.target_dir:
123 raise CommandError(
124 "Can not use any platform or abi specific options unless "
125 "installing via '--target'"
126 )
127
128
129 ###########
130 # options #
131 ###########
132
133 help_ = partial(
134 Option,
135 '-h', '--help',
136 dest='help',
137 action='help',
138 help='Show help.',
139 ) # type: Callable[..., Option]
140
141 isolated_mode = partial(
142 Option,
143 "--isolated",
144 dest="isolated_mode",
145 action="store_true",
146 default=False,
147 help=(
148 "Run pip in an isolated mode, ignoring environment variables and user "
149 "configuration."
150 ),
151 ) # type: Callable[..., Option]
152
153 require_virtualenv = partial(
154 Option,
155 # Run only if inside a virtualenv, bail if not.
156 '--require-virtualenv', '--require-venv',
157 dest='require_venv',
158 action='store_true',
159 default=False,
160 help=SUPPRESS_HELP
161 ) # type: Callable[..., Option]
162
163 verbose = partial(
164 Option,
165 '-v', '--verbose',
166 dest='verbose',
167 action='count',
168 default=0,
169 help='Give more output. Option is additive, and can be used up to 3 times.'
170 ) # type: Callable[..., Option]
171
172 no_color = partial(
173 Option,
174 '--no-color',
175 dest='no_color',
176 action='store_true',
177 default=False,
178 help="Suppress colored output",
179 ) # type: Callable[..., Option]
180
181 version = partial(
182 Option,
183 '-V', '--version',
184 dest='version',
185 action='store_true',
186 help='Show version and exit.',
187 ) # type: Callable[..., Option]
188
189 quiet = partial(
190 Option,
191 '-q', '--quiet',
192 dest='quiet',
193 action='count',
194 default=0,
195 help=(
196 'Give less output. Option is additive, and can be used up to 3'
197 ' times (corresponding to WARNING, ERROR, and CRITICAL logging'
198 ' levels).'
199 ),
200 ) # type: Callable[..., Option]
201
202 progress_bar = partial(
203 Option,
204 '--progress-bar',
205 dest='progress_bar',
206 type='choice',
207 choices=list(BAR_TYPES.keys()),
208 default='on',
209 help=(
210 'Specify type of progress to be displayed [' +
211 '|'.join(BAR_TYPES.keys()) + '] (default: %default)'
212 ),
213 ) # type: Callable[..., Option]
214
215 log = partial(
216 Option,
217 "--log", "--log-file", "--local-log",
218 dest="log",
219 metavar="path",
220 help="Path to a verbose appending log."
221 ) # type: Callable[..., Option]
222
223 no_input = partial(
224 Option,
225 # Don't ask for input
226 '--no-input',
227 dest='no_input',
228 action='store_true',
229 default=False,
230 help=SUPPRESS_HELP
231 ) # type: Callable[..., Option]
232
233 proxy = partial(
234 Option,
235 '--proxy',
236 dest='proxy',
237 type='str',
238 default='',
239 help="Specify a proxy in the form [user:passwd@]proxy.server:port."
240 ) # type: Callable[..., Option]
241
242 retries = partial(
243 Option,
244 '--retries',
245 dest='retries',
246 type='int',
247 default=5,
248 help="Maximum number of retries each connection should attempt "
249 "(default %default times).",
250 ) # type: Callable[..., Option]
251
252 timeout = partial(
253 Option,
254 '--timeout', '--default-timeout',
255 metavar='sec',
256 dest='timeout',
257 type='float',
258 default=15,
259 help='Set the socket timeout (default %default seconds).',
260 ) # type: Callable[..., Option]
261
262 skip_requirements_regex = partial(
263 Option,
264 # A regex to be used to skip requirements
265 '--skip-requirements-regex',
266 dest='skip_requirements_regex',
267 type='str',
268 default='',
269 help=SUPPRESS_HELP,
270 ) # type: Callable[..., Option]
271
272
273 def exists_action():
274 # type: () -> Option
275 return Option(
276 # Option when path already exist
277 '--exists-action',
278 dest='exists_action',
279 type='choice',
280 choices=['s', 'i', 'w', 'b', 'a'],
281 default=[],
282 action='append',
283 metavar='action',
284 help="Default action when a path already exists: "
285 "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort.",
286 )
287
288
289 cert = partial(
290 Option,
291 '--cert',
292 dest='cert',
293 type='str',
294 metavar='path',
295 help="Path to alternate CA bundle.",
296 ) # type: Callable[..., Option]
297
298 client_cert = partial(
299 Option,
300 '--client-cert',
301 dest='client_cert',
302 type='str',
303 default=None,
304 metavar='path',
305 help="Path to SSL client certificate, a single file containing the "
306 "private key and the certificate in PEM format.",
307 ) # type: Callable[..., Option]
308
309 index_url = partial(
310 Option,
311 '-i', '--index-url', '--pypi-url',
312 dest='index_url',
313 metavar='URL',
314 default=PyPI.simple_url,
315 help="Base URL of the Python Package Index (default %default). "
316 "This should point to a repository compliant with PEP 503 "
317 "(the simple repository API) or a local directory laid out "
318 "in the same format.",
319 ) # type: Callable[..., Option]
320
321
322 def extra_index_url():
323 return Option(
324 '--extra-index-url',
325 dest='extra_index_urls',
326 metavar='URL',
327 action='append',
328 default=[],
329 help="Extra URLs of package indexes to use in addition to "
330 "--index-url. Should follow the same rules as "
331 "--index-url.",
332 )
333
334
335 no_index = partial(
336 Option,
337 '--no-index',
338 dest='no_index',
339 action='store_true',
340 default=False,
341 help='Ignore package index (only looking at --find-links URLs instead).',
342 ) # type: Callable[..., Option]
343
344
345 def find_links():
346 # type: () -> Option
347 return Option(
348 '-f', '--find-links',
349 dest='find_links',
350 action='append',
351 default=[],
352 metavar='url',
353 help="If a url or path to an html file, then parse for links to "
354 "archives. If a local path or file:// url that's a directory, "
355 "then look for archives in the directory listing.",
356 )
357
358
359 def make_search_scope(options, suppress_no_index=False):
360 # type: (Values, bool) -> SearchScope
361 """
362 :param suppress_no_index: Whether to ignore the --no-index option
363 when constructing the SearchScope object.
364 """
365 index_urls = [options.index_url] + options.extra_index_urls
366 if options.no_index and not suppress_no_index:
367 logger.debug(
368 'Ignoring indexes: %s',
369 ','.join(redact_password_from_url(url) for url in index_urls),
370 )
371 index_urls = []
372
373 # Make sure find_links is a list before passing to create().
374 find_links = options.find_links or []
375
376 search_scope = SearchScope.create(
377 find_links=find_links, index_urls=index_urls,
378 )
379
380 return search_scope
381
382
383 def trusted_host():
384 # type: () -> Option
385 return Option(
386 "--trusted-host",
387 dest="trusted_hosts",
388 action="append",
389 metavar="HOSTNAME",
390 default=[],
391 help="Mark this host as trusted, even though it does not have valid "
392 "or any HTTPS.",
393 )
394
395
396 def constraints():
397 # type: () -> Option
398 return Option(
399 '-c', '--constraint',
400 dest='constraints',
401 action='append',
402 default=[],
403 metavar='file',
404 help='Constrain versions using the given constraints file. '
405 'This option can be used multiple times.'
406 )
407
408
409 def requirements():
410 # type: () -> Option
411 return Option(
412 '-r', '--requirement',
413 dest='requirements',
414 action='append',
415 default=[],
416 metavar='file',
417 help='Install from the given requirements file. '
418 'This option can be used multiple times.'
419 )
420
421
422 def editable():
423 # type: () -> Option
424 return Option(
425 '-e', '--editable',
426 dest='editables',
427 action='append',
428 default=[],
429 metavar='path/url',
430 help=('Install a project in editable mode (i.e. setuptools '
431 '"develop mode") from a local project path or a VCS url.'),
432 )
433
434
435 src = partial(
436 Option,
437 '--src', '--source', '--source-dir', '--source-directory',
438 dest='src_dir',
439 metavar='dir',
440 default=get_src_prefix(),
441 help='Directory to check out editable projects into. '
442 'The default in a virtualenv is "<venv path>/src". '
443 'The default for global installs is "<current dir>/src".'
444 ) # type: Callable[..., Option]
445
446
447 def _get_format_control(values, option):
448 # type: (Values, Option) -> Any
449 """Get a format_control object."""
450 return getattr(values, option.dest)
451
452
453 def _handle_no_binary(option, opt_str, value, parser):
454 # type: (Option, str, str, OptionParser) -> None
455 existing = _get_format_control(parser.values, option)
456 FormatControl.handle_mutual_excludes(
457 value, existing.no_binary, existing.only_binary,
458 )
459
460
461 def _handle_only_binary(option, opt_str, value, parser):
462 # type: (Option, str, str, OptionParser) -> None
463 existing = _get_format_control(parser.values, option)
464 FormatControl.handle_mutual_excludes(
465 value, existing.only_binary, existing.no_binary,
466 )
467
468
469 def no_binary():
470 # type: () -> Option
471 format_control = FormatControl(set(), set())
472 return Option(
473 "--no-binary", dest="format_control", action="callback",
474 callback=_handle_no_binary, type="str",
475 default=format_control,
476 help="Do not use binary packages. Can be supplied multiple times, and "
477 "each time adds to the existing value. Accepts either :all: to "
478 "disable all binary packages, :none: to empty the set, or one or "
479 "more package names with commas between them. Note that some "
480 "packages are tricky to compile and may fail to install when "
481 "this option is used on them.",
482 )
483
484
485 def only_binary():
486 # type: () -> Option
487 format_control = FormatControl(set(), set())
488 return Option(
489 "--only-binary", dest="format_control", action="callback",
490 callback=_handle_only_binary, type="str",
491 default=format_control,
492 help="Do not use source packages. Can be supplied multiple times, and "
493 "each time adds to the existing value. Accepts either :all: to "
494 "disable all source packages, :none: to empty the set, or one or "
495 "more package names with commas between them. Packages without "
496 "binary distributions will fail to install when this option is "
497 "used on them.",
498 )
499
500
501 platform = partial(
502 Option,
503 '--platform',
504 dest='platform',
505 metavar='platform',
506 default=None,
507 help=("Only use wheels compatible with <platform>. "
508 "Defaults to the platform of the running system."),
509 ) # type: Callable[..., Option]
510
511
512 # This was made a separate function for unit-testing purposes.
513 def _convert_python_version(value):
514 # type: (str) -> Tuple[Tuple[int, ...], Optional[str]]
515 """
516 Convert a version string like "3", "37", or "3.7.3" into a tuple of ints.
517
518 :return: A 2-tuple (version_info, error_msg), where `error_msg` is
519 non-None if and only if there was a parsing error.
520 """
521 if not value:
522 # The empty string is the same as not providing a value.
523 return (None, None)
524
525 parts = value.split('.')
526 if len(parts) > 3:
527 return ((), 'at most three version parts are allowed')
528
529 if len(parts) == 1:
530 # Then we are in the case of "3" or "37".
531 value = parts[0]
532 if len(value) > 1:
533 parts = [value[0], value[1:]]
534
535 try:
536 version_info = tuple(int(part) for part in parts)
537 except ValueError:
538 return ((), 'each version part must be an integer')
539
540 return (version_info, None)
541
542
543 def _handle_python_version(option, opt_str, value, parser):
544 # type: (Option, str, str, OptionParser) -> None
545 """
546 Handle a provided --python-version value.
547 """
548 version_info, error_msg = _convert_python_version(value)
549 if error_msg is not None:
550 msg = (
551 'invalid --python-version value: {!r}: {}'.format(
552 value, error_msg,
553 )
554 )
555 raise_option_error(parser, option=option, msg=msg)
556
557 parser.values.python_version = version_info
558
559
560 python_version = partial(
561 Option,
562 '--python-version',
563 dest='python_version',
564 metavar='python_version',
565 action='callback',
566 callback=_handle_python_version, type='str',
567 default=None,
568 help=dedent("""\
569 The Python interpreter version to use for wheel and "Requires-Python"
570 compatibility checks. Defaults to a version derived from the running
571 interpreter. The version can be specified using up to three dot-separated
572 integers (e.g. "3" for 3.0.0, "3.7" for 3.7.0, or "3.7.3"). A major-minor
573 version can also be given as a string without dots (e.g. "37" for 3.7.0).
574 """),
575 ) # type: Callable[..., Option]
576
577
578 implementation = partial(
579 Option,
580 '--implementation',
581 dest='implementation',
582 metavar='implementation',
583 default=None,
584 help=("Only use wheels compatible with Python "
585 "implementation <implementation>, e.g. 'pp', 'jy', 'cp', "
586 " or 'ip'. If not specified, then the current "
587 "interpreter implementation is used. Use 'py' to force "
588 "implementation-agnostic wheels."),
589 ) # type: Callable[..., Option]
590
591
592 abi = partial(
593 Option,
594 '--abi',
595 dest='abi',
596 metavar='abi',
597 default=None,
598 help=("Only use wheels compatible with Python "
599 "abi <abi>, e.g. 'pypy_41'. If not specified, then the "
600 "current interpreter abi tag is used. Generally "
601 "you will need to specify --implementation, "
602 "--platform, and --python-version when using "
603 "this option."),
604 ) # type: Callable[..., Option]
605
606
607 def add_target_python_options(cmd_opts):
608 # type: (OptionGroup) -> None
609 cmd_opts.add_option(platform())
610 cmd_opts.add_option(python_version())
611 cmd_opts.add_option(implementation())
612 cmd_opts.add_option(abi())
613
614
615 def make_target_python(options):
616 # type: (Values) -> TargetPython
617 target_python = TargetPython(
618 platform=options.platform,
619 py_version_info=options.python_version,
620 abi=options.abi,
621 implementation=options.implementation,
622 )
623
624 return target_python
625
626
627 def prefer_binary():
628 # type: () -> Option
629 return Option(
630 "--prefer-binary",
631 dest="prefer_binary",
632 action="store_true",
633 default=False,
634 help="Prefer older binary packages over newer source packages."
635 )
636
637
638 cache_dir = partial(
639 Option,
640 "--cache-dir",
641 dest="cache_dir",
642 default=USER_CACHE_DIR,
643 metavar="dir",
644 help="Store the cache data in <dir>."
645 ) # type: Callable[..., Option]
646
647
648 def _handle_no_cache_dir(option, opt, value, parser):
649 # type: (Option, str, str, OptionParser) -> None
650 """
651 Process a value provided for the --no-cache-dir option.
652
653 This is an optparse.Option callback for the --no-cache-dir option.
654 """
655 # The value argument will be None if --no-cache-dir is passed via the
656 # command-line, since the option doesn't accept arguments. However,
657 # the value can be non-None if the option is triggered e.g. by an
658 # environment variable, like PIP_NO_CACHE_DIR=true.
659 if value is not None:
660 # Then parse the string value to get argument error-checking.
661 try:
662 strtobool(value)
663 except ValueError as exc:
664 raise_option_error(parser, option=option, msg=str(exc))
665
666 # Originally, setting PIP_NO_CACHE_DIR to a value that strtobool()
667 # converted to 0 (like "false" or "no") caused cache_dir to be disabled
668 # rather than enabled (logic would say the latter). Thus, we disable
669 # the cache directory not just on values that parse to True, but (for
670 # backwards compatibility reasons) also on values that parse to False.
671 # In other words, always set it to False if the option is provided in
672 # some (valid) form.
673 parser.values.cache_dir = False
674
675
676 no_cache = partial(
677 Option,
678 "--no-cache-dir",
679 dest="cache_dir",
680 action="callback",
681 callback=_handle_no_cache_dir,
682 help="Disable the cache.",
683 ) # type: Callable[..., Option]
684
685 no_deps = partial(
686 Option,
687 '--no-deps', '--no-dependencies',
688 dest='ignore_dependencies',
689 action='store_true',
690 default=False,
691 help="Don't install package dependencies.",
692 ) # type: Callable[..., Option]
693
694 build_dir = partial(
695 Option,
696 '-b', '--build', '--build-dir', '--build-directory',
697 dest='build_dir',
698 metavar='dir',
699 help='Directory to unpack packages into and build in. Note that '
700 'an initial build still takes place in a temporary directory. '
701 'The location of temporary directories can be controlled by setting '
702 'the TMPDIR environment variable (TEMP on Windows) appropriately. '
703 'When passed, build directories are not cleaned in case of failures.'
704 ) # type: Callable[..., Option]
705
706 ignore_requires_python = partial(
707 Option,
708 '--ignore-requires-python',
709 dest='ignore_requires_python',
710 action='store_true',
711 help='Ignore the Requires-Python information.'
712 ) # type: Callable[..., Option]
713
714 no_build_isolation = partial(
715 Option,
716 '--no-build-isolation',
717 dest='build_isolation',
718 action='store_false',
719 default=True,
720 help='Disable isolation when building a modern source distribution. '
721 'Build dependencies specified by PEP 518 must be already installed '
722 'if this option is used.'
723 ) # type: Callable[..., Option]
724
725
726 def _handle_no_use_pep517(option, opt, value, parser):
727 # type: (Option, str, str, OptionParser) -> None
728 """
729 Process a value provided for the --no-use-pep517 option.
730
731 This is an optparse.Option callback for the no_use_pep517 option.
732 """
733 # Since --no-use-pep517 doesn't accept arguments, the value argument
734 # will be None if --no-use-pep517 is passed via the command-line.
735 # However, the value can be non-None if the option is triggered e.g.
736 # by an environment variable, for example "PIP_NO_USE_PEP517=true".
737 if value is not None:
738 msg = """A value was passed for --no-use-pep517,
739 probably using either the PIP_NO_USE_PEP517 environment variable
740 or the "no-use-pep517" config file option. Use an appropriate value
741 of the PIP_USE_PEP517 environment variable or the "use-pep517"
742 config file option instead.
743 """
744 raise_option_error(parser, option=option, msg=msg)
745
746 # Otherwise, --no-use-pep517 was passed via the command-line.
747 parser.values.use_pep517 = False
748
749
750 use_pep517 = partial(
751 Option,
752 '--use-pep517',
753 dest='use_pep517',
754 action='store_true',
755 default=None,
756 help='Use PEP 517 for building source distributions '
757 '(use --no-use-pep517 to force legacy behaviour).'
758 ) # type: Any
759
760 no_use_pep517 = partial(
761 Option,
762 '--no-use-pep517',
763 dest='use_pep517',
764 action='callback',
765 callback=_handle_no_use_pep517,
766 default=None,
767 help=SUPPRESS_HELP
768 ) # type: Any
769
770 install_options = partial(
771 Option,
772 '--install-option',
773 dest='install_options',
774 action='append',
775 metavar='options',
776 help="Extra arguments to be supplied to the setup.py install "
777 "command (use like --install-option=\"--install-scripts=/usr/local/"
778 "bin\"). Use multiple --install-option options to pass multiple "
779 "options to setup.py install. If you are using an option with a "
780 "directory path, be sure to use absolute path.",
781 ) # type: Callable[..., Option]
782
783 global_options = partial(
784 Option,
785 '--global-option',
786 dest='global_options',
787 action='append',
788 metavar='options',
789 help="Extra global options to be supplied to the setup.py "
790 "call before the install command.",
791 ) # type: Callable[..., Option]
792
793 no_clean = partial(
794 Option,
795 '--no-clean',
796 action='store_true',
797 default=False,
798 help="Don't clean up build directories."
799 ) # type: Callable[..., Option]
800
801 pre = partial(
802 Option,
803 '--pre',
804 action='store_true',
805 default=False,
806 help="Include pre-release and development versions. By default, "
807 "pip only finds stable versions.",
808 ) # type: Callable[..., Option]
809
810 disable_pip_version_check = partial(
811 Option,
812 "--disable-pip-version-check",
813 dest="disable_pip_version_check",
814 action="store_true",
815 default=False,
816 help="Don't periodically check PyPI to determine whether a new version "
817 "of pip is available for download. Implied with --no-index.",
818 ) # type: Callable[..., Option]
819
820
821 # Deprecated, Remove later
822 always_unzip = partial(
823 Option,
824 '-Z', '--always-unzip',
825 dest='always_unzip',
826 action='store_true',
827 help=SUPPRESS_HELP,
828 ) # type: Callable[..., Option]
829
830
831 def _handle_merge_hash(option, opt_str, value, parser):
832 # type: (Option, str, str, OptionParser) -> None
833 """Given a value spelled "algo:digest", append the digest to a list
834 pointed to in a dict by the algo name."""
835 if not parser.values.hashes:
836 parser.values.hashes = {}
837 try:
838 algo, digest = value.split(':', 1)
839 except ValueError:
840 parser.error('Arguments to %s must be a hash name '
841 'followed by a value, like --hash=sha256:abcde...' %
842 opt_str)
843 if algo not in STRONG_HASHES:
844 parser.error('Allowed hash algorithms for %s are %s.' %
845 (opt_str, ', '.join(STRONG_HASHES)))
846 parser.values.hashes.setdefault(algo, []).append(digest)
847
848
849 hash = partial(
850 Option,
851 '--hash',
852 # Hash values eventually end up in InstallRequirement.hashes due to
853 # __dict__ copying in process_line().
854 dest='hashes',
855 action='callback',
856 callback=_handle_merge_hash,
857 type='string',
858 help="Verify that the package's archive matches this "
859 'hash before installing. Example: --hash=sha256:abcdef...',
860 ) # type: Callable[..., Option]
861
862
863 require_hashes = partial(
864 Option,
865 '--require-hashes',
866 dest='require_hashes',
867 action='store_true',
868 default=False,
869 help='Require a hash to check each requirement against, for '
870 'repeatable installs. This option is implied when any package in a '
871 'requirements file has a --hash option.',
872 ) # type: Callable[..., Option]
873
874
875 list_path = partial(
876 Option,
877 '--path',
878 dest='path',
879 action='append',
880 help='Restrict to the specified installation path for listing '
881 'packages (can be used multiple times).'
882 ) # type: Callable[..., Option]
883
884
885 def check_list_path_option(options):
886 # type: (Values) -> None
887 if options.path and (options.user or options.local):
888 raise CommandError(
889 "Cannot combine '--path' with '--user' or '--local'"
890 )
891
892
893 ##########
894 # groups #
895 ##########
896
897 general_group = {
898 'name': 'General Options',
899 'options': [
900 help_,
901 isolated_mode,
902 require_virtualenv,
903 verbose,
904 version,
905 quiet,
906 log,
907 no_input,
908 proxy,
909 retries,
910 timeout,
911 skip_requirements_regex,
912 exists_action,
913 trusted_host,
914 cert,
915 client_cert,
916 cache_dir,
917 no_cache,
918 disable_pip_version_check,
919 no_color,
920 ]
921 } # type: Dict[str, Any]
922
923 index_group = {
924 'name': 'Package Index Options',
925 'options': [
926 index_url,
927 extra_index_url,
928 no_index,
929 find_links,
930 ]
931 } # type: Dict[str, Any]