comparison env/lib/python3.9/site-packages/pip/_internal/cli/cmdoptions.py @ 0:4f3585e2f14b draft default tip

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