1
1
"""Base option parser setup"""
2
2
3
- # The following comment should be removed at some point in the future.
4
- # mypy: disallow-untyped-defs=False
5
-
6
3
import logging
7
4
import optparse
8
5
import shutil
9
6
import sys
10
7
import textwrap
11
8
from contextlib import suppress
12
- from typing import Any
9
+ from typing import Any , Dict , Iterator , List , Tuple
13
10
14
11
from pip ._internal .cli .status_codes import UNKNOWN_ERROR
15
12
from pip ._internal .configuration import Configuration , ConfigurationError
@@ -22,16 +19,19 @@ class PrettyHelpFormatter(optparse.IndentedHelpFormatter):
22
19
"""A prettier/less verbose help formatter for optparse."""
23
20
24
21
def __init__ (self , * args , ** kwargs ):
22
+ # type: (*Any, **Any) -> None
25
23
# help position must be aligned with __init__.parseopts.description
26
24
kwargs ["max_help_position" ] = 30
27
25
kwargs ["indent_increment" ] = 1
28
26
kwargs ["width" ] = shutil .get_terminal_size ()[0 ] - 2
29
27
super ().__init__ (* args , ** kwargs )
30
28
31
29
def format_option_strings (self , option ):
30
+ # type: (optparse.Option) -> str
32
31
return self ._format_option_strings (option )
33
32
34
33
def _format_option_strings (self , option , mvarfmt = " <{}>" , optsep = ", " ):
34
+ # type: (optparse.Option, str, str) -> str
35
35
"""
36
36
Return a comma-separated list of option strings and metavars.
37
37
@@ -49,17 +49,20 @@ def _format_option_strings(self, option, mvarfmt=" <{}>", optsep=", "):
49
49
opts .insert (1 , optsep )
50
50
51
51
if option .takes_value ():
52
+ assert option .dest is not None
52
53
metavar = option .metavar or option .dest .lower ()
53
54
opts .append (mvarfmt .format (metavar .lower ()))
54
55
55
56
return "" .join (opts )
56
57
57
58
def format_heading (self , heading ):
59
+ # type: (str) -> str
58
60
if heading == "Options" :
59
61
return ""
60
62
return heading + ":\n "
61
63
62
64
def format_usage (self , usage ):
65
+ # type: (str) -> str
63
66
"""
64
67
Ensure there is only one newline between usage and the first heading
65
68
if there is no description.
@@ -68,6 +71,7 @@ def format_usage(self, usage):
68
71
return msg
69
72
70
73
def format_description (self , description ):
74
+ # type: (str) -> str
71
75
# leave full control over description to us
72
76
if description :
73
77
if hasattr (self .parser , "main" ):
@@ -86,13 +90,15 @@ def format_description(self, description):
86
90
return ""
87
91
88
92
def format_epilog (self , epilog ):
93
+ # type: (str) -> str
89
94
# leave full control over epilog to us
90
95
if epilog :
91
96
return epilog
92
97
else :
93
98
return ""
94
99
95
100
def indent_lines (self , text , indent ):
101
+ # type: (str, str) -> str
96
102
new_lines = [indent + line for line in text .split ("\n " )]
97
103
return "\n " .join (new_lines )
98
104
@@ -107,9 +113,12 @@ class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter):
107
113
"""
108
114
109
115
def expand_default (self , option ):
116
+ # type: (optparse.Option) -> str
110
117
default_values = None
111
118
if self .parser is not None :
119
+ assert isinstance (self .parser , ConfigOptionParser )
112
120
self .parser ._update_defaults (self .parser .defaults )
121
+ assert option .dest is not None
113
122
default_values = self .parser .defaults .get (option .dest )
114
123
help_text = super ().expand_default (option )
115
124
@@ -129,6 +138,7 @@ def expand_default(self, option):
129
138
130
139
class CustomOptionParser (optparse .OptionParser ):
131
140
def insert_option_group (self , idx , * args , ** kwargs ):
141
+ # type: (int, Any, Any) -> optparse.OptionGroup
132
142
"""Insert an OptionGroup at a given position."""
133
143
group = self .add_option_group (* args , ** kwargs )
134
144
@@ -139,6 +149,7 @@ def insert_option_group(self, idx, *args, **kwargs):
139
149
140
150
@property
141
151
def option_list_all (self ):
152
+ # type: () -> List[optparse.Option]
142
153
"""Get a list of all options, including those in option groups."""
143
154
res = self .option_list [:]
144
155
for i in self .option_groups :
@@ -166,18 +177,22 @@ def __init__(
166
177
super ().__init__ (* args , ** kwargs )
167
178
168
179
def check_default (self , option , key , val ):
180
+ # type: (optparse.Option, str, Any) -> Any
169
181
try :
170
182
return option .check_value (key , val )
171
183
except optparse .OptionValueError as exc :
172
184
print (f"An error occurred during configuration: { exc } " )
173
185
sys .exit (3 )
174
186
175
187
def _get_ordered_configuration_items (self ):
188
+ # type: () -> Iterator[Tuple[str, Any]]
176
189
# Configuration gives keys in an unordered manner. Order them.
177
190
override_order = ["global" , self .name , ":env:" ]
178
191
179
192
# Pool the options into different groups
180
- section_items = {name : [] for name in override_order }
193
+ section_items = {
194
+ name : [] for name in override_order
195
+ } # type: Dict[str, List[Tuple[str, Any]]]
181
196
for section_key , val in self .config .items ():
182
197
# ignore empty values
183
198
if not val :
@@ -197,6 +212,7 @@ def _get_ordered_configuration_items(self):
197
212
yield key , val
198
213
199
214
def _update_defaults (self , defaults ):
215
+ # type: (Dict[str, Any]) -> Dict[str, Any]
200
216
"""Updates the given defaults with values from the config files and
201
217
the environ. Does a little special handling for certain types of
202
218
options (lists)."""
@@ -215,6 +231,8 @@ def _update_defaults(self, defaults):
215
231
if option is None :
216
232
continue
217
233
234
+ assert option .dest is not None
235
+
218
236
if option .action in ("store_true" , "store_false" ):
219
237
try :
220
238
val = strtobool (val )
@@ -240,6 +258,7 @@ def _update_defaults(self, defaults):
240
258
val = val .split ()
241
259
val = [self .check_default (option , key , v ) for v in val ]
242
260
elif option .action == "callback" :
261
+ assert option .callback is not None
243
262
late_eval .add (option .dest )
244
263
opt_str = option .get_opt_string ()
245
264
val = option .convert_value (opt_str , val )
@@ -258,6 +277,7 @@ def _update_defaults(self, defaults):
258
277
return defaults
259
278
260
279
def get_default_values (self ):
280
+ # type: () -> optparse.Values
261
281
"""Overriding to make updating the defaults after instantiation of
262
282
the option parser possible, _update_defaults() does the dirty work."""
263
283
if not self .process_default_values :
@@ -272,12 +292,14 @@ def get_default_values(self):
272
292
273
293
defaults = self ._update_defaults (self .defaults .copy ()) # ours
274
294
for option in self ._get_all_options ():
295
+ assert option .dest is not None
275
296
default = defaults .get (option .dest )
276
297
if isinstance (default , str ):
277
298
opt_str = option .get_opt_string ()
278
299
defaults [option .dest ] = option .check_value (opt_str , default )
279
300
return optparse .Values (defaults )
280
301
281
302
def error (self , msg ):
303
+ # type: (str) -> None
282
304
self .print_usage (sys .stderr )
283
305
self .exit (UNKNOWN_ERROR , f"{ msg } \n " )
0 commit comments