Skip to content

allow_abbrev=False does not work for single-dash long options #104860

@SunCrazy

Description

@SunCrazy

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 ....

Linked PRs

Metadata

Metadata

Labels

3.12only security fixes3.13bugs and security fixes3.14bugs and security fixesstdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

Projects

Status

Doc issues

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions