Ejemplo n.º 1
0
def add_logging_args(parser: argparse.ArgumentParser,
                     patch: bool = True,
                     erase_args: bool = True) -> None:
    """
    Add command line flags specific to logging.

    :param parser: `argparse` parser where to add new flags.
    :param erase_args: Automatically remove logging-related flags from parsed args.
    :param patch: Patch parse_args() to automatically setup logging.
    """
    parser.add_argument("--log-level",
                        default="INFO",
                        choices=logging._nameToLevel,
                        help="Logging verbosity.")
    parser.add_argument(
        "--log-structured",
        action="store_true",
        help="Enable structured logging (JSON record per line).")
    parser.add_argument(
        "--log-config",
        help="Path to the file which sets individual log levels of domains.")

    # monkey-patch parse_args()
    # custom actions do not work, unfortunately, because they are not invoked if
    # the corresponding --flags are not specified

    def _patched_parse_args(args=None, namespace=None) -> argparse.Namespace:
        args = parser._original_parse_args(args, namespace)
        setup(args.log_level, args.log_structured, args.log_config)
        if erase_args:
            for log_arg in ("log_level", "log_structured", "log_config"):
                delattr(args, log_arg)
        return args

    if patch and not hasattr(parser, "_original_parse_args"):
        parser._original_parse_args = parser.parse_args
        parser.parse_args = _patched_parse_args
Ejemplo n.º 2
0
def bind(
    parser: argparse.ArgumentParser,
    hp_mgr: hpman.HyperParameterManager,
    *,
    inject_actions: Union[bool, List[str]] = True,
    action_prefix: str = config.HP_ACTION_PREFIX_DEFAULT,
    serial_format: str = config.HP_SERIAL_FORMAT_DEFAULT,
    show_defaults: bool = True,
):
    """Bridging the gap between argparse and hpman. This is
        the most important method. Once bounded, hpargparse
        will do the rest for you.

    :param parser: A `class`:`argparse.ArgumentParser` object
    :param hp_mgr: The hyperparameter manager from `hpman`. It is
        usually an 'underscore' variable obtained by `from hpman.m import _`
    :param inject_actions: A list of actions names to inject, or True, to
        inject all available actions. Available actions are 'save', 'load', and
        'list'
    :param action_prefix: Prefix for options of hpargparse injected additional
        actions. e.g., the default action_prefix is 'hp'. Therefore, the
        command line options added by :func:`.bind` will be '--hp-save',
        '--hp-load', '--hp-list', etc.
    :param serial_format: One of 'auto', 'yaml' and 'pickle'. Defaults to
        'auto'.  In most cases you need not to alter this argument as long as
        you give the right file extension when using save and load action. To
        be specific, '.yaml' and '.yml' would be deemed as yaml format, and
        '.pickle' and '.pkl' would be seen as pickle format.
    :param show_defaults: Show the default value in help messages.

    :note: pickle is done by `dill` to support pickling of more types.
    """

    # make action list to be injected
    inject_actions = parse_action_list(inject_actions)

    inject_args(
        parser,
        hp_mgr,
        inject_actions=inject_actions,
        action_prefix=action_prefix,
        serial_format=serial_format,
        show_defaults=show_defaults,
    )

    # hook parser.parse_args
    parser._original_parse_args = parser.parse_args

    def new_parse_args(self, *args, **kwargs):
        args = self._original_parse_args(*args, **kwargs)

        get_action_value = lambda name: getattr(
            args, "{}_{}".format(action_prefix, name)
        )

        # load saved hyperparameter instance
        load_value = get_action_value("load")
        if "load" in inject_actions and load_value is not None:
            hp_load(load_value, hp_mgr, serial_format)

        # set hyperparameters set from command lines
        for k, v in hp_mgr.get_values().items():
            if hasattr(args, k):
                t = getattr(args, k)
                if isinstance(t, EmptyValue):
                    continue
                hp_mgr.set_value(k, t)

        save_value = get_action_value("save")
        if "save" in inject_actions and save_value is not None:
            hp_save(save_value, hp_mgr, serial_format)

        if "list" in inject_actions and args.hp_list:
            if args.hp_list == "yaml":
                print(yaml.dump(hp_mgr.get_values()), end="")
            else:
                assert args.hp_list == "detail", args.hp_list
                hp_list(hp_mgr)

            sys.exit(0)

        if inject_actions and get_action_value("exit"):
            sys.exit(0)

        return args

    parser.parse_args = MethodType(new_parse_args, parser)