From 0477aa58673cd957c19d377e029347ce72c08b1b Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Mon, 22 Mar 2021 04:31:48 +0100 Subject: [PATCH] Add support for sign specifiers in number formats. (#134) --- README.rst | 5 +++-- parse.py | 5 ++++- test_parse.py | 11 +++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index e01aaaf..df881ea 100644 --- a/README.rst +++ b/README.rst @@ -132,7 +132,7 @@ format specification might have been used. Most of `format()`'s `Format Specification Mini-Language`_ is supported: - [[fill]align][0][width][.precision][type] + [[fill]align][sign][0][width][.precision][type] The differences between `parse()` and `format()` are: @@ -143,7 +143,8 @@ The differences between `parse()` and `format()` are: That is, the "#" format character is handled automatically by d, b, o and x formats. For "d" any will be accepted, but for the others the correct prefix must be present if at all. -- Numeric sign is handled automatically. +- Numeric sign is handled automatically. A sign specifier can be given, but + has no effect. - The thousands separator is handled automatically if the "n" type is used. - The types supported are a slightly different mix to the format() types. Some format() types come directly over: "d", "n", "%", "f", "e", "b", "o" and "x". diff --git a/parse.py b/parse.py index 062a421..c5d9b9f 100644 --- a/parse.py +++ b/parse.py @@ -758,7 +758,7 @@ class RepeatedNameError(ValueError): def extract_format(format, extra_types): - """Pull apart the format [[fill]align][0][width][.precision][type]""" + """Pull apart the format [[fill]align][sign][0][width][.precision][type]""" fill = align = None if format[0] in '<>=^': align = format[0] @@ -768,6 +768,9 @@ def extract_format(format, extra_types): align = format[1] format = format[2:] + if format.startswith(('+', '-', ' ')): + format = format[1:] + zero = False if format and format[0] == '0': zero = True diff --git a/test_parse.py b/test_parse.py index 1752a42..847ca8f 100755 --- a/test_parse.py +++ b/test_parse.py @@ -205,6 +205,17 @@ def test_typed(self): r = parse.parse('hello {:w} {:w}', 'hello 12 people') self.assertEqual(r.fixed, ('12', 'people')) + def test_sign(self): + # sign is ignored + r = parse.parse('Pi = {:.7f}', 'Pi = 3.1415926') + self.assertEqual(r.fixed, (3.1415926,)) + r = parse.parse('Pi = {:+.7f}', 'Pi = 3.1415926') + self.assertEqual(r.fixed, (3.1415926,)) + r = parse.parse('Pi = {:-.7f}', 'Pi = 3.1415926') + self.assertEqual(r.fixed, (3.1415926,)) + r = parse.parse('Pi = {: .7f}', 'Pi = 3.1415926') + self.assertEqual(r.fixed, (3.1415926,)) + def test_precision(self): # pull a float out of a string r = parse.parse('Pi = {:.7f}', 'Pi = 3.1415926')