Bug report
The following codes get different results between python3.6.9 and python3.8.10
import argparse if __name__ == "__main__": parser = argparse.ArgumentParser( allow_abbrev=False ) parser.add_argument('-on', "--output-name", type=str, help="output") args, _ = parser.parse_known_args(["-on", "name", "-o", "dir"]) print(args)
python3.6.9
[chenf@b12e0231:/mnt/ssd/chenf/projects/test_hhb_2.4/debug/cmd_config]$ python3 --version Python 3.6.9 [chenf@b12e0231:/mnt/ssd/chenf/projects/test_hhb_2.4/debug/cmd_config]$ python3 ~/test.py Namespace(output_name='name')
python3.8.10
[chenf@b11b0623:/mnt/ssd/chenf/project/hhb_test_2.4/cmd_config]$ python3 --version Python 3.8.10 [chenf@b11b0623:/mnt/ssd/chenf/project/hhb_test_2.4/cmd_config]$ python3 ~/test.py Namespace(output_name='dir')
Debug
I have tried to debug the codes and get some clues.
I have set the allow_abbrev=False to disable prefix match, but it works in python3.6.9 and fails in python3.8.10.
When I div into argparse.py and find that it considers the allow_abbrev in python3.6.9 but not in python3.8.10 as follow:
in python3.6.9 argparse.py
def _parse_optional(self, arg_string): .... if self.allow_abbrev: # search through all possible prefixes of the option string # and all actions in the parser for possible interpretations option_tuples = self._get_option_tuples(arg_string) # if multiple actions match, the option string was ambiguous if len(option_tuples) > 1: options = ', '.join([option_string for action, option_string, explicit_arg in option_tuples]) args = {'option': arg_string, 'matches': options} msg = _('ambiguous option: %(option)s could match %(matches)s') self.error(msg % args) # if exactly one action matched, this segmentation is good, # so return the parsed action elif len(option_tuples) == 1: option_tuple, = option_tuples return option_tuple ....
in python3.8.10 argparse.py
def _parse_optional(self, arg_string): .... # search through all possible prefixes of the option string # and all actions in the parser for possible interpretations option_tuples = self._get_option_tuples(arg_string) # if multiple actions match, the option string was ambiguous if len(option_tuples) > 1: options = ', '.join([option_string for action, option_string, explicit_arg in option_tuples]) args = {'option': arg_string, 'matches': options} msg = _('ambiguous option: %(option)s could match %(matches)s') self.error(msg % args) # if exactly one action matched, this segmentation is good, # so return the parsed action elif len(option_tuples) == 1: option_tuple, = option_tuples return option_tuple ....