cmdoptions.py 28 KB

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