|
13 | 13 | import importlib.util |
14 | 14 | import logging |
15 | 15 | import os |
| 16 | +import pathlib |
16 | 17 | import textwrap |
17 | 18 | from functools import partial |
18 | 19 | from optparse import SUPPRESS_HELP, Option, OptionGroup, OptionParser, Values |
@@ -280,8 +281,17 @@ class PipOption(Option): |
280 | 281 | dest="retries", |
281 | 282 | type="int", |
282 | 283 | default=5, |
283 | | - help="Maximum number of retries each connection should attempt " |
284 | | - "(default %default times).", |
| 284 | + help="Maximum attempts to establish a new HTTP connection. (default: %default)", |
| 285 | +) |
| 286 | + |
| 287 | +resume_retries: Callable[..., Option] = partial( |
| 288 | + Option, |
| 289 | + "--resume-retries", |
| 290 | + dest="resume_retries", |
| 291 | + type="int", |
| 292 | + default=0, |
| 293 | + help="Maximum attempts to resume or restart an incomplete download. " |
| 294 | + "(default: %default)", |
285 | 295 | ) |
286 | 296 |
|
287 | 297 | timeout: Callable[..., Option] = partial( |
@@ -733,6 +743,46 @@ def _handle_no_cache_dir( |
733 | 743 | help="Don't install package dependencies.", |
734 | 744 | ) |
735 | 745 |
|
| 746 | + |
| 747 | +def _handle_dependency_group( |
| 748 | + option: Option, opt: str, value: str, parser: OptionParser |
| 749 | +) -> None: |
| 750 | + """ |
| 751 | + Process a value provided for the --group option. |
| 752 | +
|
| 753 | + Splits on the rightmost ":", and validates that the path (if present) ends |
| 754 | + in `pyproject.toml`. Defaults the path to `pyproject.toml` when one is not given. |
| 755 | +
|
| 756 | + `:` cannot appear in dependency group names, so this is a safe and simple parse. |
| 757 | +
|
| 758 | + This is an optparse.Option callback for the dependency_groups option. |
| 759 | + """ |
| 760 | + path, sep, groupname = value.rpartition(":") |
| 761 | + if not sep: |
| 762 | + path = "pyproject.toml" |
| 763 | + else: |
| 764 | + # check for 'pyproject.toml' filenames using pathlib |
| 765 | + if pathlib.PurePath(path).name != "pyproject.toml": |
| 766 | + msg = "group paths use 'pyproject.toml' filenames" |
| 767 | + raise_option_error(parser, option=option, msg=msg) |
| 768 | + |
| 769 | + parser.values.dependency_groups.append((path, groupname)) |
| 770 | + |
| 771 | + |
| 772 | +dependency_groups: Callable[..., Option] = partial( |
| 773 | + Option, |
| 774 | + "--group", |
| 775 | + dest="dependency_groups", |
| 776 | + default=[], |
| 777 | + type=str, |
| 778 | + action="callback", |
| 779 | + callback=_handle_dependency_group, |
| 780 | + metavar="[path:]group", |
| 781 | + help='Install a named dependency-group from a "pyproject.toml" file. ' |
| 782 | + 'If a path is given, the name of the file must be "pyproject.toml". ' |
| 783 | + 'Defaults to using "pyproject.toml" in the current directory.', |
| 784 | +) |
| 785 | + |
736 | 786 | ignore_requires_python: Callable[..., Option] = partial( |
737 | 787 | Option, |
738 | 788 | "--ignore-requires-python", |
@@ -783,9 +833,9 @@ def _handle_no_use_pep517( |
783 | 833 | """ |
784 | 834 | raise_option_error(parser, option=option, msg=msg) |
785 | 835 |
|
786 | | - # If user doesn't wish to use pep517, we check if setuptools and wheel are installed |
| 836 | + # If user doesn't wish to use pep517, we check if setuptools is installed |
787 | 837 | # and raise error if it is not. |
788 | | - packages = ("setuptools", "wheel") |
| 838 | + packages = ("setuptools",) |
789 | 839 | if not all(importlib.util.find_spec(package) for package in packages): |
790 | 840 | msg = ( |
791 | 841 | f"It is not possible to use --no-use-pep517 " |
@@ -887,6 +937,14 @@ def _handle_config_settings( |
887 | 937 | "pip only finds stable versions.", |
888 | 938 | ) |
889 | 939 |
|
| 940 | +json: Callable[..., Option] = partial( |
| 941 | + Option, |
| 942 | + "--json", |
| 943 | + action="store_true", |
| 944 | + default=False, |
| 945 | + help="Output data in a machine-readable JSON format.", |
| 946 | +) |
| 947 | + |
890 | 948 | disable_pip_version_check: Callable[..., Option] = partial( |
891 | 949 | Option, |
892 | 950 | "--disable-pip-version-check", |
@@ -990,7 +1048,7 @@ def check_list_path_option(options: Values) -> None: |
990 | 1048 | dest="no_python_version_warning", |
991 | 1049 | action="store_true", |
992 | 1050 | default=False, |
993 | | - help="Silence deprecation warnings for upcoming unsupported Pythons.", |
| 1051 | + help=SUPPRESS_HELP, # No-op, a hold-over from the Python 2->3 transition. |
994 | 1052 | ) |
995 | 1053 |
|
996 | 1054 |
|
@@ -1028,7 +1086,6 @@ def check_list_path_option(options: Values) -> None: |
1028 | 1086 | help=("Enable deprecated functionality, that will be removed in the future."), |
1029 | 1087 | ) |
1030 | 1088 |
|
1031 | | - |
1032 | 1089 | ########## |
1033 | 1090 | # groups # |
1034 | 1091 | ########## |
@@ -1061,6 +1118,7 @@ def check_list_path_option(options: Values) -> None: |
1061 | 1118 | no_python_version_warning, |
1062 | 1119 | use_new_feature, |
1063 | 1120 | use_deprecated_feature, |
| 1121 | + resume_retries, |
1064 | 1122 | ], |
1065 | 1123 | } |
1066 | 1124 |
|
|
0 commit comments