From a35d172e5b7abf1694e1b078eeb54e7b286cbcc4 Mon Sep 17 00:00:00 2001 From: allegroai <> Date: Tue, 12 Jan 2021 18:56:45 +0200 Subject: [PATCH] Fix argparse nargs support broken --- clearml/backend_interface/task/args.py | 22 ++++++++++++++-------- clearml/utilities/args.py | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/clearml/backend_interface/task/args.py b/clearml/backend_interface/task/args.py index 3bb60dc1..98662702 100644 --- a/clearml/backend_interface/task/args.py +++ b/clearml/backend_interface/task/args.py @@ -271,18 +271,24 @@ class _Arguments(object): try: v = yaml.load(v.strip(), Loader=yaml.SafeLoader) if not isinstance(v, (list, tuple)): - # do nothing, we have no idea what happened - pass - elif current_action.type: - v = [current_action.type(a) for a in v] - elif current_action.default: - v_type = type(current_action.default[0]) - v = [v_type(a) for a in v] + # we have no idea what happened, just put into a list. + v = [v] if v else None + # casting + if v: + if current_action.type: + v = [current_action.type(a) for a in v] + elif current_action.default: + v_type = type(current_action.default[0]) + v = [v_type(a) for a in v] if current_action.default is not None or v not in (None, ''): arg_parser_arguments[k] = v except Exception: - pass + if self._task and self._task.log: + self._task.log.warning( + 'Failed parsing task parameter {}="{}" keeping default {}={}'.format( + k, v, k, current_action.default)) + elif current_action and not current_action.type: # cast manually if there is no type var_type = type(current_action.default) diff --git a/clearml/utilities/args.py b/clearml/utilities/args.py index 69349333..a90c9b80 100644 --- a/clearml/utilities/args.py +++ b/clearml/utilities/args.py @@ -146,10 +146,15 @@ class PatchArgumentParser: else: parsed_args = parsed_args_namespace = copy(parsed_args) + # cast arguments in parsed_args_namespace entries to str if parsed_args_namespace and isinstance(parsed_args_namespace, Namespace): for k, v in parser._parsed_arg_string_lookup.items(): # noqa if hasattr(parsed_args_namespace, k): - setattr(parsed_args_namespace, k, v) + setattr( + parsed_args_namespace, k, + str([v] if (isinstance(getattr(parsed_args_namespace, k, None), list) and + not isinstance(v, list)) else v) + ) PatchArgumentParser._last_parsed_args = (PatchArgumentParser._last_parsed_args or []) + [parsed_args] return parsed_args @@ -162,7 +167,14 @@ class PatchArgumentParser: def _get_value(self, action, arg_string): if not hasattr(self, '_parsed_arg_string_lookup'): setattr(self, '_parsed_arg_string_lookup', dict()) - self._parsed_arg_string_lookup[str(action.dest)] = str(arg_string) + k = str(action.dest) + if k not in self._parsed_arg_string_lookup: + self._parsed_arg_string_lookup[k] = arg_string + else: + self._parsed_arg_string_lookup[k] = \ + (self._parsed_arg_string_lookup[k] + if isinstance(self._parsed_arg_string_lookup[k], list) + else [self._parsed_arg_string_lookup[k]]) + [arg_string] return PatchArgumentParser._original_get_value(self, action, arg_string)