def build_arg_parser(config=None, modules=None, parser=None):
    """
    Build the argparse object extracting information from the modules.

    :param modules: dict of Module instances
    :type modules: dict(str:model.IModule)
    
    :param config: instance or subinstance of CommonData object
    :type config: `libs.CommonData`
    
    :param parser: start point of parser to build it 
    :type parser: `ArgumentParser`

    """
    if modules is not None:
        if not isinstance(modules, dict):
            raise TypeError(type(modules) % "Expected list, got '%s' instead")
        else:
            for x in six.itervalues(modules):
                if not issubclass(x, IModule):
                    raise TypeError("Expected IModule, got '%s' instead" % type(x))
    else:
        modules = AppSettings.modules

    if config is None:
        config = GlobalExecutionParameters()

    # --------------------------------------------------------------------------
    # Build command line
    # --------------------------------------------------------------------------
    if parser is None:
        parser = STBArgumentParser(description='%s' % __banner__,
                                   epilog=_build_examples(modules),
                                   formatter_class=_argparse.RawTextHelpFormatter)
    _extract_parameters(config, parser)

    # --------------------------------------------------------------------------
    # Add sub parsers for each module
    # --------------------------------------------------------------------------
    main_subparser = parser.add_subparsers(help='available commands:', dest='module_name')
    main_subparser.required = True

    for mod_name, mod_class in six.iteritems(modules):
        # Add subparser to module
        mod_parser = main_subparser.add_parser(mod_class.name,
                                               help=mod_class.description)

        sub_modules_enabled = False

        # If module has raw argsubparser, add it
        if hasattr(mod_class, "__submodules__"):

            if len([x for x in mod_class.__submodules__ if x != "default"]) > 0:

                # New sub-module added
                sub_modules_enabled = True

                sub_module_actions = mod_parser.add_subparsers(help="%s commands:" % mod_name, dest="module_%s" % mod_name)
                sub_module_actions.required = True

                for x, y in six.iteritems(mod_class.__submodules__):

                    # Skip default action info
                    if x == "default":
                        continue

                    sub_help = y.get('help', "")
                    sub_action = y.get('cmd_args', None)

                    sub_sub_parser = sub_module_actions.add_parser(x, help=sub_help)

                    # Add module parameters
                    if hasattr(mod_class, "__model__"):
                        _extract_parameters(mod_class.__model__(), sub_sub_parser, mod_name)

                    if sub_action is not None:
                        # Add sub parser
                        sub_action(sub_sub_parser)

        if sub_modules_enabled is False:
            # Add module parameters
            if hasattr(mod_class, "__model__"):
                _extract_parameters(mod_class.__model__(), mod_parser, mod_name)

    return parser


# ----------------------------------------------------------------------
dataset/ETHPy150Open cr0hn/enteletaor/enteletaor_lib/libs/core/cmd.py/build_arg_parser/swapped operands of `%`