Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python TypeError: non-empty format string passed to object.__format__

I hit this TypeError exception recently, which I found very difficult to debug. I eventually reduced it to this small test case:

>>> "{:20}".format(b"hi")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: non-empty format string passed to object.__format__

This is very non-obvious, to me anyway. The workaround for my code was to decode the byte string into unicode:

 >>> "{:20}".format(b"hi".decode("ascii"))
 'hi                  '

What is the meaning of this exception? Is there a way it can be made more clear?

like image 964
Chris AtLee Avatar asked Jun 11 '14 18:06

Chris AtLee


People also ask

What is __ format __ in Python?

The __format__() method is used by string. format() as well as the format() built-in function. Both of these interfaces are used to get presentable string versions of a given object.

How does format work in Python?

Formatters work by fixing one or a lot of replacement fields or placeholders outlined by a pair of curled brackets “{}” — into a string and calling the str. format() technique. You'll pass into the format() method the value you wish to concatenate with the string.


2 Answers

bytes objects do not have a __format__ method of their own, so the default from object is used:

>>> bytes.__format__ is object.__format__
True
>>> '{:20}'.format(object())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: non-empty format string passed to object.__format__

It just means that you cannot use anything other than straight up, unformatted unaligned formatting on these. Explicitly convert to a string object (as you did by decoding bytes to str) to get format spec support.

You can make the conversion explicit by using the !s string conversion:

>>> '{!s:20s}'.format(b"Hi")
"b'Hi'               "
>>> '{!s:20s}'.format(object())
'<object object at 0x1100b9080>'

object.__format__ explicitly rejects format strings to avoid implicit string conversions, specifically because formatting instructions are type specific.

like image 192
Martijn Pieters Avatar answered Oct 03 '22 22:10

Martijn Pieters


This also happens when trying to format None:

>>> '{:.0f}'.format(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: non-empty format string passed to object.__format__

That took a moment to work out (in my case, when None was being returned by an instance variable)!

like image 27
Jeremy Field Avatar answered Oct 03 '22 20:10

Jeremy Field