gh-67790: Support float-style formatting for Fraction instances by mdickinson · Pull Request #100161 · python/cpython (original) (raw)

This PR adds support for float-style formatting for Fraction objects: it supports the "e", "E", "f", "F", "g", "G" and "%" presentation types, and all the various bells and whistles of the formatting mini-language for those presentation types. The behaviour almost exactly matches that of float, but the implementation works with the exact Fraction value and does not do an intermediate conversion to float, and so avoids loss of precision or issues with numbers that are outside the dynamic range of the float type.

Note that the "n" presentation type is not supported. That support could be added later if people have a need for it.

There's one corner-case where the behaviour differs from that of float: for the float type, if explicit alignment is specified with a fill character of '0' and alignment type '=', then thousands separators (if specified) are inserted into the padding string:

format(3.14, '0=11,.2f') '0,000,003.14'

The exact same effect can be achieved by using the '0' flag:

format(3.14, '011,.2f') '0,000,003.14'

For Fraction, only the '0' flag has the above behaviour with respect to thousands separators: there's no special-casing of the particular '0=' fill-character/alignment combination. Instead, we treat the fill character '0' just like any other:

format(Fraction('3.14'), '0=11,.2f') '00000003.14' format(Fraction('3.14'), '011,.2f') '0,000,003.14'

The Fraction formatter is also stricter about combining these two things: it's not permitted to use both the '0' flag and explicit alignment, on the basis that we should refuse the temptation to guess in the face of ambiguity. float is less picky:

format(3.14, '0<011,.2f') '3.140000000' format(Fraction('3.14'), '0<011,.2f') Traceback (most recent call last): File "", line 1, in File "/Users/mdickinson/Repositories/python/cpython/Lib/fractions.py", line 414, in format raise ValueError( ValueError: Invalid format specifier '0<011,.2f' for object of type 'Fraction'; can't use explicit alignment when zero-padding