Format String Syntax specification differs from actual behaviour

The actual behavior is that attribute_name and the first field can be anything that doesn’t contain . or ], for example "{-.-1[-].0}" is valid, if a bit hard to read and unlikely to work [1]. Also note that negative numbers ("{-1}") are treated as attempted attribute/map key access, not as numeric indices.

I don’t know if the behavior is intended, but I doubt that it will be changed. I would say the docs should be updated.

replacement_field ::=  "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name        ::=  arg_name ("." attribute_name | "[" element_index "]")*
arg_name          ::=  [digit+ | attribute_name]
attribute_name    ::=  <any source character except "]" or "."> +
element_index     ::=  digit+ | index_string
index_string      ::=  <any source character except "]"> +
conversion        ::=  "r" | "s" | "a"
format_spec       ::=  format-spec:format_spec

This should be more accurate to the implementation.

May I ask hat you are doing so that this behavior is relevant for you?


  1. But you can construct an object so that it does work: s.format(**{"-":SimpleNamespace(**{"-1":{'-':SimpleNamespace(**{'0':"value"})}})}) ↩︎