Skip to content

string.Formatter.parse does not handle auto-numbered positional fields #89867

Open

Description

@SDesch
mannequin
BPO 45704
Nosy @ericvsmith

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2021-11-03.11:55:47.784>
labels = ['type-bug', '3.8', '3.9', '3.10', '3.11', '3.7']
title = 'string.Formatter.parse does not handle auto-numbered positional fields'
updated_at = <Date 2021-11-05.18:06:11.745>
user = 'https://bugs.python.org/SDesch'

bugs.python.org fields:

activity = <Date 2021-11-05.18:06:11.745>
actor = 'eric.smith'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = []
creation = <Date 2021-11-03.11:55:47.784>
creator = 'SDesch'
dependencies = []
files = []
hgrepos = []
issue_num = 45704
keywords = []
message_count = 9.0
messages = ['405610', '405619', '405624', '405627', '405636', '405757', '405796', '405802', '405814']
nosy_count = 2.0
nosy_names = ['eric.smith', 'SDesch']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue45704'
versions = ['Python 3.6', 'Python 3.7', 'Python 3.8', 'Python 3.9', 'Python 3.10', 'Python 3.11']

Linked PRs

Activity

  1. SDesch commented on Nov 3, 2021

    SDeschmannequin
    MannequinAuthor

    It appears when adding auto-numbered positional fields in python 3.1 Formatter.parse was not updated to handle them and currently returns an empty string as the field name.

    list(Formatter().parse('hello {}'))  # [('hello ', '', '', None)]
    

    This does not align with Formatter.get_field which according to the docs: "Given field_name as returned by parse() (see above), convert it to an object to be formatted."

    When supplying an empty string to .get_field() you get a KeyError

    Formatter().get_field("", [1, 2, 3], {}). # raises KeyError
    
  2. ericvsmith commented on Nov 3, 2021

    @ericvsmith
    Member

    For reference, the documentation is at https://docs.python.org/3/library/string.html#custom-string-formatting

    I guess in your example it should return:
    [('hello ', '0', '', None)]

  3. SDesch commented on Nov 3, 2021

    SDeschmannequin
    MannequinAuthor

    Yes it should return a string containing the index of the positional argument i.e. "0" so that it is compatible with .get_field(). Side note: It's a somewhat weird that .get_field expects a string while .get_value expects an int for positional arguments.

  4. 4 remaining items

  5. ericvsmith commented on Nov 5, 2021

    @ericvsmith
    Member

    I think your code is rational. But since string.Formatter gets such little use, I'm not sure it's worth adding this to the stdlib. On the other hand, it could be used internal to string.Formatter.

    We'd need to pick a better name, though. And maybe it should return the field_name as an int.

  6. ericvsmith commented on Nov 5, 2021

    @ericvsmith
    Member

    That is, return field_name as an int if it's an int, otherwise as a string.

  7. transferred this issue fromon Apr 10, 2022
  8. dg-pb commented on Jan 31, 2025

    @dg-pb
    Contributor

    The more I think about this, the more I think it's not .parse's job to fill in the field numbers, it's the job of whoever is calling it.

    I agree with this. .parse correctly returns empty string for empty field name. This is factorised well providing one-to-one relationship between input and output.


    However, the main issue is that this is not possible for things with nesting to work.

    If parsing only one level, then suggested parse change would return things correctly. E.g.:

    list(string.Formatter().parse('{}{}'))
    [('', '0', '', None), ('', '1', '', None)]

    However, it would not return things correctly for:

    list(string.Formatter().parse('{:.{}f}{}'))
    [('', '0', '.{}f', None), ('', '1', '', None)]

    While its equivalent of manually numbered fields would look like:

    fmt = '{0:.{1}f}{2}'
    # And correct parse output should be:
    list(string.Formatter().parse('{:.{}f}{}'))
    [('', '0', '.{}f', None), ('', '2', '', None)]

    Auto-numbering is very easy to do outside it. Especially for a flat case. I suggest closing this as "Not planned".

  9. encukou commented on Feb 3, 2025

    @encukou
    Member

    That's reasonable! Looks like all that's left is to mention this in the parse/get_field docs.

  10. added
    stdlibStandard Library Python modules in the Lib/ directory
    and removed
    interpreter-core(Objects, Python, Grammar, and Parser dirs)
    3.11only security fixes
    on Feb 3, 2025
  11. added a commit that references this issue on Apr 30, 2025
  12. added a commit that references this issue on Apr 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions