Skip to content

Commit 34a8cc4

Browse files
committed
gh-61449: handle 0-padding option for Fractions like for floats
1 parent 66eafc9 commit 34a8cc4

File tree

4 files changed

+34
-24
lines changed

4 files changed

+34
-24
lines changed

Doc/library/fractions.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,8 +233,7 @@ a single number, or from a string.
233233
:ref:`format specification mini-language <formatspec>`. The "alternate
234234
form" flag ``'#'`` is supported: if present, it forces the output string
235235
to always include an explicit denominator, even when the value being
236-
formatted is an exact integer. The zero-fill flag ``'0'`` is not
237-
supported.
236+
formatted is an exact integer.
238237

239238
If the ``format_spec`` format specification string ends with one of
240239
the presentation types ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``,

Lib/fractions.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,15 @@ def _format_float_style(self, match):
500500
no_neg_zero = bool(match["no_neg_zero"])
501501
alternate_form = bool(match["alt"])
502502
zeropad = bool(match["zeropad"])
503+
504+
# Support zeropad handling like built-in types (see gh-61449).
505+
if match["zeropad"] is not None:
506+
if match["fill"] is not None and match["align"] is not None:
507+
zeropad = False
508+
elif match["align"] is not None:
509+
zeropad = False
510+
fill = "0"
511+
503512
minimumwidth = int(match["minimumwidth"] or "0")
504513
thousands_sep = match["thousands_sep"]
505514
precision = int(match["precision"] or "6")
@@ -603,10 +612,7 @@ def __format__(self, format_spec, /):
603612
return self._format_general(match)
604613

605614
if match := _FLOAT_FORMAT_SPECIFICATION_MATCHER(format_spec):
606-
# Refuse the temptation to guess if both alignment _and_
607-
# zero padding are specified.
608-
if match["align"] is None or match["zeropad"] is None:
609-
return self._format_float_style(match)
615+
return self._format_float_style(match)
610616

611617
raise ValueError(
612618
f"Invalid format specifier {format_spec!r} "

Lib/test/test_fractions.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,8 @@ def test_format_e_presentation_type(self):
13261326
(F('1234567.123456'), '.5_e', '1.234_57e+06'),
13271327
# z flag is legal, but never makes a difference to the output
13281328
(F(-1, 7**100), 'z.6e', '-3.091690e-85'),
1329+
# fill and/or alignment with zero padding
1330+
(F(2, 3), '=010e', format(float(F(2, 3)), '=010e')),
13291331
]
13301332
for fraction, spec, expected in testcases:
13311333
with self.subTest(fraction=fraction, spec=spec):
@@ -1525,6 +1527,23 @@ def test_format_f_presentation_type(self):
15251527
(F(151, 1000), '.1f', '0.2'),
15261528
(F(22, 7), '.02f', '3.14'), # issue gh-130662
15271529
(F(22, 7), '005.02f', '03.14'),
1530+
# fill and/or alignment with zero padding
1531+
(F(2, 3), 'X>010f', format(float(F(2, 3)), 'X>010f')),
1532+
(F(2, 3), 'X<010f', format(float(F(2, 3)), 'X<010f')),
1533+
(F(2, 3), 'X^010f', format(float(F(2, 3)), 'X^010f')),
1534+
(F(2, 3), 'X=010f', format(float(F(2, 3)), 'X=010f')),
1535+
(F(2, 3), '0>010f', format(float(F(2, 3)), '0>010f')),
1536+
(F(2, 3), '0<010f', format(float(F(2, 3)), '0<010f')),
1537+
(F(2, 3), '0^010f', format(float(F(2, 3)), '0^010f')),
1538+
(F(2, 3), '0=010f', format(float(F(2, 3)), '0=010f')),
1539+
(F(2, 3), '>010f', format(float(F(2, 3)), '>010f')),
1540+
(F(2, 3), '<010f', format(float(F(2, 3)), '<010f')),
1541+
(F(2, 3), '^010f', format(float(F(2, 3)), '^010f')),
1542+
(F(2, 3), '=010e', format(float(F(2, 3)), '=010e')),
1543+
(F(2, 3), '=010f', format(float(F(2, 3)), '=010f')),
1544+
(F(2, 3), '>00.2f', format(float(F(2, 3)), '>00.2f')),
1545+
(F(2, 3), '>00f', format(float(F(2, 3)), '>00f')),
1546+
(F(2, 3), '=010%', format(float(F(2, 3)), '=010%')),
15281547
]
15291548
for fraction, spec, expected in testcases:
15301549
with self.subTest(fraction=fraction, spec=spec):
@@ -1593,6 +1612,8 @@ def test_format_g_presentation_type(self):
15931612
(F(2**64), '_.25g', '18_446_744_073_709_551_616'),
15941613
# As with 'e' format, z flag is legal, but has no effect
15951614
(F(-1, 7**100), 'zg', '-3.09169e-85'),
1615+
# fill and/or alignment with zero padding
1616+
(F(2, 3), '=010g', format(float(F(2, 3)), '=010g')),
15961617
]
15971618
for fraction, spec, expected in testcases:
15981619
with self.subTest(fraction=fraction, spec=spec):
@@ -1605,24 +1626,6 @@ def test_invalid_formats(self):
16051626

16061627
invalid_specs = [
16071628
'Q6f', # regression test
1608-
# illegal to use fill or alignment when zero padding
1609-
'X>010f',
1610-
'X<010f',
1611-
'X^010f',
1612-
'X=010f',
1613-
'0>010f',
1614-
'0<010f',
1615-
'0^010f',
1616-
'0=010f',
1617-
'>010f',
1618-
'<010f',
1619-
'^010f',
1620-
'=010e',
1621-
'=010f',
1622-
'=010g',
1623-
'=010%',
1624-
'>00.2f',
1625-
'>00f',
16261629
# Missing precision
16271630
'.e',
16281631
'.f',
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Align support of zero-padding option for :class:`~fractions.Fraction`
2+
formatting with builtin numeric types. Patch by Sergey B Kirpichev.

0 commit comments

Comments
 (0)