diff --git a/Lib/argparse.py b/Lib/argparse.py index adf8bdf16f1f5a..08a3155fd16afc 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1405,7 +1405,7 @@ def __init__(self, self._defaults = {} # determines whether an "option" looks like a negative number - self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$') + self._negative_number_matcher = _re.compile(r'^-(?:\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?|\.\d+(?:_\d+)*)$') # whether or not there are any optionals that look like negative # numbers -- uses a list so it can be shared and edited diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 42998d5c6ea06d..67f1064b0c3b18 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -2092,6 +2092,29 @@ class TestActionExtend(ParserTestCase): ('--foo f1 --foo f2 f3 f4', NS(foo=['f1', 'f2', 'f3', 'f4'])), ] + +class TestNegativeNumber(ParserTestCase): + """Test parsing negative numbers""" + + argument_signatures = [ + Sig('--int', type=int), + Sig('--float', type=float), + ] + failures = [ + '--float -_.45', + '--float -1__000.0', + '--int -1__000', + ] + successes = [ + ('--int -1000 --float -1000.0', NS(int=-1000, float=-1000.0)), + ('--int -1_000 --float -1_000.0', NS(int=-1000, float=-1000.0)), + ('--int -1_000_000 --float -1_000_000.0', NS(int=-1000000, float=-1000000.0)), + ('--float -1_000.0', NS(int=None, float=-1000.0)), + ('--float -1_000_000.0_0', NS(int=None, float=-1000000.0)), + ('--float -.5', NS(int=None, float=-0.5)), + ('--float -.5_000', NS(int=None, float=-0.5)), + ] + # ================ # Subparsers tests # ================