[Python-Dev] 3.1 and 2.7 break format() when used with complex (sometimes)

Eric Smith eric at trueblade.com
Mon Feb 22 20:16:11 CET 2010


This code works on 2.6 and 3.0:
 >>> format(1+1j, '10s')
'(1+1j)    '

That's because format ends up calling object.__format__ because complex 
doesn't have its own __format__. Then object.__format__ calls str(self) 
which returns '(1+1j)    '. So the original call basically turns into 
"format('(1+1j)    ', '10s')".

In 3.1 (released) and 2.7 (not yet released) I implemented __format__ on 
complex. So now that same code is an error:
 >>> format(1+1j, '10s')
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ValueError: Unknown format code 's' for object of type 'complex'

That's because complex._format__ doesn't recognize string formatting 
codes, in particular 's'.

There's a general problem that types that sprout __format__ will break 
existing usages of format() that use some string formatting codes, 
unless the types recognize string formats in addition to their own. I 
think we should change the documentation of format() to warn that you 
should really call str() on the first argument if you're relying on the 
second argument being a string formatting code.

But what to do about 3.1 and 2.7 with respect to complex? I see 2 options:

1. Leave it as-is, such that 3.1 and 2.7 might break some uses of 
format(complex, str).
2. Modify format to understand 's' and do the conversion itself. But we 
don't do this for int and float, that's why we added '!s'.

I'm sort of leaning toward #1, but I'd like to know if anyone has an 
opinion. I haven't heard of anyone complaining about this yet; it would 
only have tripped up people moving from 3.0 -> 3.1, or from 2.6 -> 3.1 
who used format (or str.format()) while specifying 's' or some other 
str-specific format codes.

Eric.


More information about the Python-Dev mailing list