[Python-3000] More PEP 3101 changes incoming

Talin talin at acm.org
Sat Aug 11 08:48:56 CEST 2007


I'm going to address several issues of the discussion, in hopes of 
short-cutting through some of the debate. I may not be responding to the 
correct person in all cases.

Ron Adam wrote:
> If you want the 'r' specifier to always have precedence over even custom 
> __format__ methods, then you can do that too, but I don't see the need.

In my conversation with Guido, he felt pretty strongly that he wanted 
'repr' to be able to override the type-specific __format__ function.

I'm assuming, therefore, that this is a non-negotiable design 
constraint. Unfortunately, it's one that completely destroys the nice 
neat orthogonal design that you've proposed.

I often find that the best way to reason about irreconcilable design 
constraints is to reduce them to a set of contradictory logical 
propositions:

   a) A __format__ method must be redefine the meaning of a format 
specifier.
   b) The 'repr' option must be able to take precedence the __format__ 
method.

The only possible resolution to this di-lemma is that the 'repr' option 
must not be part of the format specifier, but rather must be part of 
something else.

Assuming that we continue with the assumption that we want to delegate 
as much as possible to the __format__ methods of individual types, this 
means that we are pretty much forced to divide the format string into 
two pieces, which are:

    1) The part that __format__ is allowed to reinterpret.
    2) The part that __format__ is required to implement without 
reinterpreting.

----

Now, as far as delegating formatting between types: We don't need a 
hyper-extensible system for delegating to different formatters.

For all Python types except the numeric types, the operation of 
__format__ is pretty simple: the format specifier is passed to 
__format__ and that's it. If the __format__ method can't handle the 
specifier, that's an error, end of story.

Numeric types are special because of the fact that they are silently 
inter-convertable to each other. For example, you can add a float and an 
int, and Python will just do the right thing without complaining. It 
means that a Python programmer may not always know the exact numeric 
type they are dealing with - and this is a feature IMHO.

Therefore, it's my strong belief that you should be able to format any 
numeric type without knowing exactly what type it is. Which means that 
all numeric types need to be able to handle, in some way, all valid 
number format strings. IMHO.

Fortunately, the set of number types is small and fixed, and is not 
likely to increase any time soon. And this requirement does *not* apply 
to any data type other than numbers.

----

As to the issue of how flexible the system should be:

My belief is that one of the primary design criteria for the format 
specifier mini-language is that it doesn't detract from the readability 
of the format string.

So for example, if I have a string "Total: {0:d} Tax: {1:d}", it's 
fairly easy for me to mentally filter out the "{0:d}" part and replace 
it with a number, and this in turn lets me imagine how the string might 
look when printed.

(The older syntax, 'Total: %d', was even better in this regard, but when 
you start to use named/numbered fields it actually is worse. And 
implicit ordering is brittle.)

My design goal here is relatively simple: For the most common use cases, 
the format field shouldn't me much longer (if it all) than the value to 
be printed would be. For uncommon cases, where the programmer is 
invoking additional options, the format field can be longer, but it 
should still be kept concise.

----

One final thing I wanted to mention, which Guido reminded me, is that 
we're getting short on time. This PEP has not yet been officially 
accepted, and the reason is because of the lack of an implementation. I 
don't want to miss the boat. (The boat in this case being Alpha 1.)

-- Talin


More information about the Python-3000 mailing list