I was modernizing some old %
formatted string via regex substitution to change:
# Old:
'Map: % 20s' % name
# to New:
'Map: {: 20s}'.format(name)
and was surprised a
ValueError: Space not allowed in string format specifier
As the same syntax is valid for numerics and this error did not yet show up on my search on StackOverflow. Why does this error happen in the new format and how to correctly write an equivalent formatting?
Sitenote:
format
instead.Related Questions:
Other alignment characters: ValueError: '=' alignment not allowed in string format specifier
Same problem for f-strings. Space in f-string leads to ValueError: Invalid format specifier
Pythons modern string replacement syntax [[fill]align]
requires an alignment character from "<" | ">" | "^"
if a fill
value is provided. ("="
is not valid when when formatting with a string).
The correct usage is now:
'Map: {: >20s}'.format(name)`
# or as space is the default it can be omitted
'Map: {:>20s}'.format(name)`
Careful be aware that this is not equivalent in all cases to the old %
formatting style
In cases where the format string contains a single generic format specifier (e.g. %s), and the right-hand side is an ambiguous expression, we cannot offer a safe fix. For example, given:
"%s" % val
val
could be a single-element tuple, or a single value (not contained in a tuple). Both of these would resolve to the same formatted string when using printf-style formatting, but resolve differently when using f-strings:
val = 1
print("%s" % val) # "1"
print("{}".format(val)) # "1"
val = (1,)
print("%s" % val) # "1"
print("{}".format(val)) # "(1,)"
from https://docs.astral.sh/ruff/rules/printf-string-formatting/