classification
Title: string.Formatter accepts empty fields but displays wrong when nested
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.6, Python 3.4, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: Bill Tutt, anthon, eric.smith, jayvdb, python-dev
Priority: normal Keywords: patch

Created on 2015-09-08 19:23 by anthon, last changed 2015-12-16 22:16 by jayvdb. This issue is now closed.

Files
File name Uploaded Description Edit
25034.patch anthon, 2015-09-09 06:50
Messages (6)
msg250253 - (view) Author: Anthon van der Neut (anthon) * Date: 2015-09-08 19:23
Since 3.4.1, string.Formatter() accepts empty keys {}. If these are nested they give different results from explicitly numbered, where the same arguments applied  "".format() give the expected results:

    from string import Formatter

    f = Formatter()

    fmt0 = "X {:<{}} {} X"
    fmt1 = "X {0:<{1}} {2} X"

    for fmt in [fmt0, fmt1]:
        x = f.format(fmt, 'ab', 5, 1)
        y = fmt.format(   'ab', 5, 1)
        print(x)
        print(y)
gives:

    X ab    5 X
    X ab    1 X
    X ab    1 X
    X ab    1 X
of which the first line is incorrect.
msg250254 - (view) Author: Anthon van der Neut (anthon) * Date: 2015-09-08 19:49
Here is a patch for Python-3.5.0rc3/Lib/test/test_string.py unittests fail:


--- /opt/python/3.5/lib/python3.5/test/test_string.py	2015-09-08 17:06:07.099197904 +0200
+++ test_string.py	2015-09-08 21:47:01.471634309 +0200
@@ -58,6 +58,8 @@
                          'foo{1}{num}{1}'.format(None, 'bar', num=6))
         self.assertEqual(fmt.format('{:^{}}', 'bar', 6),
                          '{:^{}}'.format('bar', 6))
+        self.assertEqual(fmt.format('{:^{}} {}', 'bar', 6, 'X'),
+                         '{:^{}} {}'.format('bar', 6, 'X'))
         self.assertEqual(fmt.format('{:^{pad}}{}', 'foo', 'bar', pad=6),
                          '{:^{pad}}{}'.format('foo', 'bar', pad=6))
msg250291 - (view) Author: Anthon van der Neut (anthon) * Date: 2015-09-09 06:50
The problem lies in the recursive call to _vformat which might consume fields without name ({}) and increment auto_arg_index, but that
incremented value was not returned to the parent.

Since the line became longer than pep8 allowed I wrapped all of the method call arguments to the next line, hope that that's ok.

The patch is against the mercurial repository and works for 3.4.1 upwards.
msg251860 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-09-29 14:31
New changeset 9eae18e8af66 by Eric V. Smith in branch '3.4':
Fixed issue #25034: Fix string.Formatter problem with auto-numbering
https://hg.python.org/cpython/rev/9eae18e8af66

New changeset 65d7b4fd0332 by Eric V. Smith in branch '3.5':
Issue #25034: Merge from 3.4.
https://hg.python.org/cpython/rev/65d7b4fd0332

New changeset aef6365294c8 by Eric V. Smith in branch 'default':
Issue #25034: Merge from 3.5.
https://hg.python.org/cpython/rev/aef6365294c8
msg251861 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2015-09-29 14:34
Fixed in 3.4, 3.5, and 3.6. Thanks for the bug report and patch! I added you to the Misc/ACKS file.
msg255258 - (view) Author: Bill Tutt (Bill Tutt) Date: 2015-11-24 09:10
I don't suppose this change could make it into 2.7.11 as well?

Thanks,
Bill
History
Date User Action Args
2015-12-16 22:16:03jayvdbsetnosy: + jayvdb
2015-11-24 09:10:44Bill Tuttsetnosy: + Bill Tutt
messages: + msg255258
2015-09-29 14:34:36eric.smithsetstatus: open -> closed
versions: + Python 3.6
messages: + msg251861

resolution: fixed
stage: resolved
2015-09-29 14:31:09python-devsetnosy: + python-dev
messages: + msg251860
2015-09-09 06:50:22anthonsetfiles: + 25034.patch
keywords: + patch
messages: + msg250291
2015-09-08 20:28:26eric.smithsetassignee: eric.smith
2015-09-08 19:49:40anthonsetmessages: + msg250254
2015-09-08 19:27:25r.david.murraysetnosy: + eric.smith
2015-09-08 19:23:13anthoncreate