You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.4 KiB

4 years ago
  1. # coding: utf-8
  2. #
  3. # Copyright © 2010—2014 Andrey Mikhaylenko and contributors
  4. #
  5. # This file is part of Argh.
  6. #
  7. # Argh is free software under terms of the GNU Lesser
  8. # General Public License version 3 (LGPLv3) as published by the Free
  9. # Software Foundation. See the file README.rst for copying conditions.
  10. #
  11. import argparse
  12. __all__ = (
  13. 'ATTR_NAME', 'ATTR_ALIASES', 'ATTR_ARGS', 'ATTR_WRAPPED_EXCEPTIONS',
  14. 'ATTR_WRAPPED_EXCEPTIONS_PROCESSOR', 'ATTR_EXPECTS_NAMESPACE_OBJECT',
  15. 'PARSER_FORMATTER', 'DEFAULT_ARGUMENT_TEMPLATE', 'DEST_FUNCTION',
  16. )
  17. #
  18. # Names of function attributes where Argh stores command behaviour
  19. #
  20. #: explicit command name (differing from function name)
  21. ATTR_NAME = 'argh_name'
  22. #: alternative command names
  23. ATTR_ALIASES = 'argh_aliases'
  24. #: declared arguments
  25. ATTR_ARGS = 'argh_args'
  26. #: list of exception classes that should be wrapped and printed as results
  27. ATTR_WRAPPED_EXCEPTIONS = 'argh_wrap_errors'
  28. #: a function to preprocess the exception object when it is wrapped
  29. ATTR_WRAPPED_EXCEPTIONS_PROCESSOR = 'argh_wrap_errors_processor'
  30. #: forcing argparse.Namespace object instead of signature introspection
  31. ATTR_EXPECTS_NAMESPACE_OBJECT = 'argh_expects_namespace_object'
  32. #
  33. # Dest names in parser defaults
  34. #
  35. #: dest name for a function mapped to given endpoint (goes to Namespace obj)
  36. DEST_FUNCTION = 'function'
  37. #
  38. # Other library-wide stuff
  39. #
  40. class CustomFormatter(argparse.ArgumentDefaultsHelpFormatter,
  41. argparse.RawDescriptionHelpFormatter):
  42. def _expand_help(self, action):
  43. """
  44. This method is copied verbatim from ArgumentDefaultsHelpFormatter with
  45. a couple of lines added just before the end. Reason: we need to
  46. `repr()` default values instead of simply inserting them as is.
  47. This helps notice, for example, an empty string as the default value;
  48. moreover, it prevents breaking argparse due to logical quirks inside
  49. of its formatters.
  50. Ideally this could be achieved by simply defining
  51. :attr:`DEFAULT_ARGUMENT_TEMPLATE` as ``{default!r}`` but unfortunately
  52. argparse only supports the old printf syntax.
  53. """
  54. params = dict(vars(action), prog=self._prog)
  55. for name in list(params):
  56. if params[name] is argparse.SUPPRESS:
  57. del params[name]
  58. for name in list(params):
  59. if hasattr(params[name], '__name__'):
  60. params[name] = params[name].__name__
  61. if params.get('choices') is not None:
  62. choices_str = ', '.join([str(c) for c in params['choices']])
  63. params['choices'] = choices_str
  64. # XXX this is added in Argh vs. argparse.ArgumentDefaultsHelpFormatter
  65. # (avoiding empty strings, otherwise Argparse would die with
  66. # an IndexError in _format_action)
  67. #
  68. if 'default' in params:
  69. if params['default'] is None:
  70. params['default'] = '-'
  71. else:
  72. params['default'] = repr(params['default'])
  73. #
  74. # /
  75. return self._get_help_string(action) % params
  76. #: Default formatter to be used in implicitly instantiated ArgumentParser.
  77. PARSER_FORMATTER = CustomFormatter
  78. DEFAULT_ARGUMENT_TEMPLATE = '%(default)s'
  79. """
  80. Default template of argument help message (see issue #64).
  81. The template ``%(default)s`` is used by `argparse` to display the argument's
  82. default value.
  83. """