Repository: r1chardj0n3s/parse

Issue:
seach cut the result with {:^}
from parse impor *
str = '     12  ,      34   '

# Incorrect with search
print(search('{:^},{:^}', a))
<Result ('12', '3') {}>

# Correct with parse
print(parse('{:^},{:^}', a))
<Result ('12', '34') {}>


Discussion:

Patch:
diff --git a/.gitignore b/.gitignore
index c909359..bde949c 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+venv
 *.pyc
 *.pyo
 
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..e5db401 100644
--- a/parse.py
+++ b/parse.py
@@ -758,7 +758,7 @@ ALLOWED_TYPES = set(list('nbox%fFegwWdDsSl') + ['t' + c for c in 'ieahgcts'])
 
 
 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
@@ -1261,11 +1264,11 @@ class Parser(object):
 
         # align "=" has been handled
         if align == '<':
-            s = '%s%s+' % (s, fill)
+            s = '%s%s*' % (s, fill)
         elif align == '>':
             s = '%s*%s' % (fill, s)
         elif align == '^':
-            s = '%s*%s%s+' % (fill, s, fill)
+            s = '%s*%s%s*' % (fill, s, fill)
 
         return s
 


Test patch:
diff --git a/test_parse.py b/test_parse.py
index 1752a42..2392686 100755
--- a/test_parse.py
+++ b/test_parse.py
@@ -205,6 +205,17 @@ class TestParse(unittest.TestCase):
         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')
@@ -865,17 +876,22 @@ class TestBugs(unittest.TestCase):
         # prior to the fix, this would raise an AttributeError
         pickle.dumps(p)
 
-    def test_search_centered_bug_112(self):
-        r = parse.parse("{:^},{:^}", " 12 , 34 ")
-        self.assertEqual(r[1], "34")
-        r = parse.search("{:^},{:^}", " 12 , 34 ")
-        self.assertEqual(r[1], "34")
-
-    def test_search_left_align_bug_112(self):
-        r = parse.parse("{:<},{:<}", "12 ,34 ")
-        self.assertEqual(r[1], "34")
-        r = parse.search("{:<},{:<}", "12 ,34 ")
-        self.assertEqual(r[1], "34")
+    def test_unused_centered_alignment_bug(self):
+        r = parse.parse("{:^2S}", "foo")
+        self.assertEqual(r[0], "foo")
+        r = parse.search("{:^2S}", "foo")
+        self.assertEqual(r[0], "foo")
+
+        # specifically test for the case in issue #118 as well
+        r = parse.parse("Column {:d}:{:^}", "Column 1: Timestep")
+        self.assertEqual(r[0], 1)
+        self.assertEqual(r[1], "Timestep")
+
+    def test_unused_left_alignment_bug(self):
+        r = parse.parse("{:<2S}", "foo")
+        self.assertEqual(r[0], "foo")
+        r = parse.search("{:<2S}", "foo")
+        self.assertEqual(r[0], "foo")
 
     def test_match_trailing_newline(self):
         r = parse.parse('{}', 'test\n')