cmdoptions.py 28 KB

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