1"""Base option parser setup"""
8from contextlib
import suppress
9from typing
import Any, Dict, Generator, List, Tuple
19 """A prettier/less verbose help formatter for optparse."""
21 def __init__(self, *args: Any, **kwargs: Any) ->
None:
23 kwargs[
"max_help_position"] = 30
24 kwargs[
"indent_increment"] = 1
32 self, option: optparse.Option, mvarfmt: str =
" <{}>", optsep: str =
", "
35 Return a comma-separated list of option strings and metavars.
37 :param option: tuple of (short opt, long opt), e.g: ('-f', '--format')
38 :param mvarfmt: metavar format string
39 :param optsep: separator
58 if heading ==
"Options":
60 return heading +
":\n"
64 Ensure there is only one newline between usage and the first heading
65 if there is no description.
83 description = f
"{label}:\n{description}\n"
96 new_lines = [indent + line
for line
in text.split(
"\n")]
97 return "\n".join(new_lines)
101 """Custom help formatter for use in ConfigOptionParser.
103 This is updates the defaults before expanding them, allowing
104 them to show up correctly in the help listing.
106 Also redact auth from url type options
110 default_values =
None
120 default_values = [default_values]
126 for val
in default_values:
134 self, idx: int, *args: Any, **kwargs: Any
136 """Insert an OptionGroup at a given position."""
137 group = self.add_option_group(*args, **kwargs)
139 self.option_groups.pop()
140 self.option_groups.insert(idx, group)
146 """Get a list of all options, including those in option groups."""
147 res = self.option_list[:]
148 for i
in self.option_groups:
155 """Custom option parser which updates its defaults by checking the
156 configuration files and environmental variables"""
162 isolated: bool =
False,
171 def check_default(self, option: optparse.Option, key: str, val: Any) -> Any:
175 print(f
"An error occurred during configuration: {exc}")
180 ) -> Generator[Tuple[str, Any], None, None]:
182 override_order = [
"global", self.
name,
":env:"]
185 section_items: Dict[str, List[Tuple[str, Any]]] = {
186 name: []
for name
in override_order
188 for section_key, val
in self.
config.items():
192 "Ignoring configuration key '%s' as it's value is empty.",
198 if section
in override_order:
199 section_items[section].append((key, val))
202 for section
in override_order:
203 for key, val
in section_items[section]:
207 """Updates the given defaults with values from the config files and
208 the environ. Does a little special handling for certain types of
217 option = self.get_option(
"--" + key)
232 "{} is not a valid value for {} option, "
233 "please specify a boolean value like yes/no, "
234 "true/false or 1/0 instead.".format(val, key)
237 with suppress(ValueError):
239 with suppress(ValueError):
243 "{} is not a valid value for {} option, "
244 "please instead specify either a non-negative integer "
245 "or a boolean value like yes/no or false/true "
246 "which is equivalent to 1/0.".format(val, key)
265 for key
in late_eval:
271 """Overriding to make updating the defaults after instantiation of
272 the option parser possible, _update_defaults() does the dirty work."""
273 if not self.process_default_values:
280 except ConfigurationError
as err:
281 self.exit(UNKNOWN_ERROR, str(err))
284 for option
in self._get_all_options():
292 def error(self, msg: str) ->
None:
294 self.exit(UNKNOWN_ERROR, f
"{msg}\n")
optparse.Values get_default_values(self)
Any check_default(self, optparse.Option option, str key, Any val)
Generator[Tuple[str, Any], None, None] _get_ordered_configuration_items(self)
Dict[str, Any] _update_defaults(self, Dict[str, Any] defaults)
None error(self, str msg)
None __init__(self, *Any args, str name, bool isolated=False, **Any kwargs)
List[optparse.Option] option_list_all(self)
optparse.OptionGroup insert_option_group(self, int idx, *Any args, **Any kwargs)