diff options
author | R David Murray <rdmurray@bitdance.com> | 2012-09-01 03:09:34 (GMT) |
---|---|---|
committer | R David Murray <rdmurray@bitdance.com> | 2012-09-01 03:09:34 (GMT) |
commit | 64b0ef15097017b20b1edca1d3bc1e38d51feb10 (patch) | |
tree | e4a8291bea18c0642c011cfbccf1d6688304fa75 /Lib/argparse.py | |
parent | 81378c8296f46c4bc36286438dfc66d48b047bf0 (diff) | |
parent | 6fb8fb17bff87fdd5e738430502f34f8729766e3 (diff) | |
download | cpython-64b0ef15097017b20b1edca1d3bc1e38d51feb10.zip cpython-64b0ef15097017b20b1edca1d3bc1e38d51feb10.tar.gz cpython-64b0ef15097017b20b1edca1d3bc1e38d51feb10.tar.bz2 |
Merge #12776,#11839: call argparse type function only once.
Before, the type function was called twice in the case where the default
was specified and the argument was given as well. This was especially
problematic for the FileType type, as a default file would always be
opened, even if a file argument was specified on the command line.
Patch by Arnaud Fontaine, with additional test by Mike Meyer.
Diffstat (limited to 'Lib/argparse.py')
-rw-r--r-- | Lib/argparse.py | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py index cc3e374..adecb88 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1722,10 +1722,7 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): if action.dest is not SUPPRESS: if not hasattr(namespace, action.dest): if action.default is not SUPPRESS: - default = action.default - if isinstance(action.default, str): - default = self._get_value(action, default) - setattr(namespace, action.dest, default) + setattr(namespace, action.dest, action.default) # add any parser defaults that aren't present for dest in self._defaults: @@ -1948,9 +1945,24 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): # if we didn't consume all the argument strings, there were extras extras.extend(arg_strings[stop_index:]) - # make sure all required actions were present - required_actions = [_get_action_name(action) for action in self._actions - if action.required and action not in seen_actions] + # make sure all required actions were present and also convert + # action defaults which were not given as arguments + required_actions = [] + for action in self._actions: + if action not in seen_actions: + if action.required: + required_actions.append(_get_action_name(action)) + else: + # Convert action default now instead of doing it before + # parsing arguments to avoid calling convert functions + # twice (which may fail) if the argument was given, but + # only if it was defined already in the namespace + if (action.default is not None and + hasattr(namespace, action.dest) and + action.default is getattr(namespace, action.dest)): + setattr(namespace, action.dest, + self._get_value(action, action.default)) + if required_actions: self.error(_('the following arguments are required: %s') % ', '.join(required_actions)) |