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