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