Commits

Tikitu de Jager  committed 52537ef Draft

Refactored arg_parser walking for reuse.

  • Participants
  • Parent commits 77fabfe

Comments (0)

Files changed (1)

File argparse_config.src/argparse_config/__init__.py

     config_parser.read([filename])
     set_defaults(arg_parser, config_parser)
 
-def set_defaults(argparser, config_parser):
+def set_defaults(arg_parser, config_parser):
+    _walk_parser(arg_parser, SetDefaults(config_parser=config_parser))
+
+def _walk_parser(arg_parser, actions_obj):
     try:
-        for action in argparser._actions:
+        actions_obj.start_section('default')
+        for action in arg_parser._actions:
             if isinstance(action, _StoreAction):
-                _process_parser_action(action, config_parser)
+                actions_obj.process_parser_action(action)
             elif isinstance(action, _StoreConstAction):
-                _process_parser_action(action, config_parser, is_store_const=True)
+                actions_obj.process_parser_action(action, is_store_const=True)
             elif isinstance(action, _SubParsersAction):
                 for command, sub_parser in action.choices.items():
-                    if config_parser.has_section(command):
-                        for sub_action in sub_parser._actions:
-                            _process_parser_action(sub_action, config_parser, section_name=command)
+                    actions_obj.start_section(command)
+                    for sub_action in sub_parser._actions:
+                        actions_obj.process_parser_action(sub_action)
+                    actions_obj.end_section()
+        actions_obj.end_section()
     except DefaultError as e:
-        argparser.error(u'[{section_name}] config option "{option_string}" must be {type_transformer}() value, got: {value}'.format(
+        arg_parser.error(u'[{section_name}] config option "{option_string}" must be {type_transformer}() value, got: {value}'.format(
             section_name=e.section_name,
             option_string = e.option_string,
             type_transformer=e.type_transformer.__name__,
 def write_defaults(arg_parser):
     pass
 
+class SetDefaults(object):
+
+    def __init__(self, config_parser=None):
+        self.sections = []
+        self.config_parser = config_parser
+
+    def start_section(self, section_name):
+        self.sections.append(section_name)
+
+    def end_section(self):
+        self.sections.pop()
+
+    @property
+    def current_section(self):
+        return self.sections[-1] if self.sections else None
+
+    def process_parser_action(self, action, is_store_const=False):
+        for option_string in action.option_strings:
+            option_string = _convert_option_string(option_string)
+            if self.config_parser.has_option(self.current_section, option_string):
+                if is_store_const:
+                    action.default = action.const
+                else:
+                    value = self.config_parser.get(self.current_section, option_string)
+                    type_transformer = action.type if action.type is not None else lambda x:x
+                    try:
+                        action.default = type_transformer(value)
+                    except:
+                        raise DefaultError(self.current_section, option_string, value, type_transformer)
+                action.required = False
+
 class DefaultError(Exception):
     def __init__(self, section_name, option_string, value, type_transformer):
         self.section_name = section_name
 def _convert_option_string(op_s):
     return op_s.lstrip('-').replace('-', '_')
 
-def _process_parser_action(action, config_parser, section_name='default', is_store_const=False):
-    for option_string in action.option_strings:
-        option_string = _convert_option_string(option_string)
-        if config_parser.has_option(section_name, option_string):
-            if is_store_const:
-                action.default = action.const
-            else:
-                value = config_parser.get(section_name, option_string)
-                type_transformer = action.type if action.type is not None else lambda x:x
-                try:
-                    action.default = type_transformer(value)
-                except:
-                    raise DefaultError(section_name, option_string, value, type_transformer)
-            action.required = False
-