[Python-3000] More PEP 3101 changes incoming
Ron Adam
rrr at ronadam.com
Sat Aug 4 02:12:17 CEST 2007
Talin wrote:
> What's missing, however, is a description of how all of this interacts
> with the __format__ hook. The problem we are facing right now is
> sometimes we want to override the __format__ hook and sometimes we
> don't. Right now, the model that we want seems to be:
>
> 1) High precedence type coercion, i.e. 'r', which bypasses __format__.
> 2) Check for __format__, and let it interpret the format specifier.
> 3) Regular type coercion, i.e. 'd', 'f' and so on.
> 4) Regular formatting based on type.
A few more thoughts regarding this..
We can divide these into concrete and abstract type specifiers.
Concrete type specifiers only accept a specific type. They would raise an
exception if the argument is of another type. Concrete type specifiers
would always passed to an objects __format__ method.
Abstract type specifications are more lenient and work with a wider range
of objects because they use duck typing.
So that splits things up as follows...
(I added an abstract 't' text type, to resolve the ambiguity of the 's'
type either calling __format__ or __str__)
Concrete type specifiers:
s - string type (not the __str__ method in this case)
b,c,d,o,x,X - int type
e,E,f,F - float type
Abstract types specifiers: (uses duck typing)
! - calls __format__ method, fallbacks... (__str__, __repr__)
t - (text) calls __str__ method, no fallback
r - calls __repr__ method, fallback (__str__)
The '!' type could be the default if no type is specified, it is needed if
you also specify any formatting options.
'{0:!xyz}'
So '!xyz' would be passed to the __format__ method if it exists and it
would be up to that type to know what to do with the xyz. The format_spec
wouldn't be passed to __str__ or __repr__.
Should there be an abstract numeric type? These would call an objects
__int__ or __float__ method if it exists.
One of the things I've noticed is you have 'd' instead of 'i'. Maybe 'i'
should be the concrete integer type, and 'd' and abstract integer type that
calls an objects __int__ method. Then we would need a floating point
abstract type that calls __float__ ... 'g'?
In the case of an abstract type that does a conversion the format spec
could be forwarded to the objects __format__ method of the returned object.
Then we have the following left over...
'g' - General format. This prints the number as a fixed-point
number, unless the number is too large, in which case
it switches to 'e' exponent notation.
'G' - General format. Same as 'g' except switches to 'E'
if the number gets to large.
'n' - Number. This is the same as 'g', except that it uses the
current locale setting to insert the appropriate
number separator characters.
'%' - Percentage. Multiplies the number by 100 and displays
in fixed ('f') format, followed by a percent sign.
Now I'm not sure how to best handle these. Are they abstract and call a
particular __method__, or are they concrete and always call __format__ on a
particular type?
Cheers,
Ron
More information about the Python-3000
mailing list