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.

150 lines
6.0 KiB

  1. from argparse import ArgumentParser, _SubParsersAction
  2. from argparse import _MutuallyExclusiveGroup, _ArgumentGroup
  3. from gooey.gui.lang.i18n import _
  4. class GooeySubParser(_SubParsersAction):
  5. def __init__(self, *args, **kwargs):
  6. super(GooeySubParser, self).__init__(*args, **kwargs)
  7. # TODO: figure out how to correctly dispatch all of these
  8. # so that the individual wrappers aren't needed
  9. class GooeyArgumentGroup(_ArgumentGroup):
  10. def __init__(self, parser, widgets, options, *args, **kwargs):
  11. self.parser = parser
  12. self.widgets = widgets
  13. self.options = options
  14. super(GooeyArgumentGroup, self).__init__(self.parser, *args, **kwargs)
  15. def add_argument(self, *args, **kwargs):
  16. widget = kwargs.pop('widget', None)
  17. metavar = kwargs.pop('metavar', None)
  18. options = kwargs.pop('gooey_options', None)
  19. super(GooeyArgumentGroup, self).add_argument(*args, **kwargs)
  20. self.parser._actions[-1].metavar = metavar
  21. self.widgets[self.parser._actions[-1].dest] = widget
  22. self.options[self.parser._actions[-1].dest] = options
  23. def add_argument_group(self, *args, **kwargs):
  24. options = kwargs.pop('gooey_options', {})
  25. group = GooeyArgumentGroup(self.parser, self.widgets, self.options, *args, **kwargs)
  26. group.gooey_options = options
  27. self._action_groups.append(group)
  28. return group
  29. def add_mutually_exclusive_group(self, *args, **kwargs):
  30. options = kwargs.pop('gooey_options', {})
  31. container = self
  32. group = GooeyMutuallyExclusiveGroup(container, self.parser, self.widgets, self.options, *args, **kwargs)
  33. group.gooey_options = options
  34. self.parser._mutually_exclusive_groups.append(group)
  35. return group
  36. class GooeyMutuallyExclusiveGroup(_MutuallyExclusiveGroup):
  37. def __init__(self, container, parser, widgets, options, *args, **kwargs):
  38. self.parser = parser
  39. self.widgets = widgets
  40. self.options = options
  41. super(GooeyMutuallyExclusiveGroup, self).__init__(container, *args, **kwargs)
  42. def add_argument(self, *args, **kwargs):
  43. widget = kwargs.pop('widget', None)
  44. metavar = kwargs.pop('metavar', None)
  45. options = kwargs.pop('gooey_options', None)
  46. super(GooeyMutuallyExclusiveGroup, self).add_argument(*args, **kwargs)
  47. self.parser._actions[-1].metavar = metavar
  48. self.widgets[self.parser._actions[-1].dest] = widget
  49. self.options[self.parser._actions[-1].dest] = options
  50. class GooeyParser(object):
  51. def __init__(self, **kwargs):
  52. self.__dict__['parser'] = ArgumentParser(**kwargs)
  53. self.widgets = {}
  54. self.options = {}
  55. @property
  56. def _mutually_exclusive_groups(self):
  57. return self.parser._mutually_exclusive_groups
  58. @property
  59. def _actions(self):
  60. return self.parser._actions
  61. @property
  62. def description(self):
  63. return self.parser.description
  64. def add_argument(self, *args, **kwargs):
  65. widget = kwargs.pop('widget', None)
  66. metavar = kwargs.pop('metavar', None)
  67. options = kwargs.pop('gooey_options', None)
  68. if widget and widget == 'Listbox':
  69. if not 'nargs' in kwargs or kwargs['nargs'] not in ['*', '+']:
  70. raise ValueError(
  71. 'Gooey\'s Listbox widget requires that nargs be specified.\n'
  72. 'Nargs must be set to either `*` or `+` (e.g. nargs="*")'
  73. )
  74. self.parser.add_argument(*args, **kwargs)
  75. self.parser._actions[-1].metavar = metavar
  76. self.widgets[self.parser._actions[-1].dest] = widget
  77. self.options[self.parser._actions[-1].dest] = options
  78. def add_mutually_exclusive_group(self, *args, **kwargs):
  79. options = kwargs.pop('gooey_options', {})
  80. group = GooeyMutuallyExclusiveGroup(self, self.parser, self.widgets, self.options, *args, **kwargs)
  81. group.gooey_options = options
  82. self.parser._mutually_exclusive_groups.append(group)
  83. return group
  84. def add_argument_group(self, *args, **kwargs):
  85. options = kwargs.pop('gooey_options', {})
  86. group = GooeyArgumentGroup(self.parser, self.widgets, self.options, *args, **kwargs)
  87. group.gooey_options = options
  88. self.parser._action_groups.append(group)
  89. return group
  90. def parse_args(self, args=None, namespace=None):
  91. return self.parser.parse_args(args, namespace)
  92. def add_subparsers(self, **kwargs):
  93. if self._subparsers is not None:
  94. self.error(_('cannot have multiple subparser arguments'))
  95. # add the parser class to the arguments if it's not present
  96. kwargs.setdefault('parser_class', type(self))
  97. if 'title' in kwargs or 'description' in kwargs:
  98. title = _(kwargs.pop('title', 'subcommands'))
  99. description = _(kwargs.pop('description', None))
  100. self._subparsers = self.add_argument_group(title, description)
  101. else:
  102. self._subparsers = self._positionals
  103. # prog defaults to the usage message of this parser, skipping
  104. # optional arguments and with no "usage:" prefix
  105. if kwargs.get('prog') is None:
  106. formatter = self._get_formatter()
  107. positionals = self._get_positional_actions()
  108. groups = self._mutually_exclusive_groups
  109. formatter.add_usage(self.usage, positionals, groups, '')
  110. kwargs['prog'] = formatter.format_help().strip()
  111. # create the parsers action and add it to the positionals list
  112. parsers_class = self._pop_action_class(kwargs, 'parsers')
  113. action = parsers_class(option_strings=[], **kwargs)
  114. self._subparsers._add_action(action)
  115. # return the created parsers action
  116. return action
  117. def __getattr__(self, item):
  118. return getattr(self.parser, item)
  119. def __setattr__(self, key, value):
  120. return setattr(self.parser, key, value)