From 130c717a099aaaafa43e7949cab9b8b147c98365 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 25 Oct 2023 11:48:03 +0100 Subject: [PATCH 01/13] gh-67790: Add integer-style formatting for Fraction type --- Doc/whatsnew/3.13.rst | 7 +++ Lib/fractions.py | 87 +++++++++++++++++++++++++++++--------- Lib/test/test_fractions.py | 58 ++++++++++++++++++++++--- 3 files changed, 127 insertions(+), 25 deletions(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index a514659e383e4b..dbc23f7972d507 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -171,6 +171,13 @@ doctest :attr:`doctest.TestResults.skipped` attributes. (Contributed by Victor Stinner in :gh:`108794`.) +fractions +--------- + +* Objects of type :class:`fractions.Fraction` now support integer-style + formatting with the ``d`` presentation type. (Contributed by Mark Dickinson + in :gh:`?????`) + io -- diff --git a/Lib/fractions.py b/Lib/fractions.py index c95db0730e5b6d..c51bba4411d4c9 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -139,6 +139,26 @@ def _round_to_figures(n, d, figures): return sign, significand, exponent +# Pattern for matching int-style format specifications; +# supports 'd' presentation type (and missing presentation type, interpreted +# as equivalent to 'd'). +_INT_FORMAT_SPECIFICATION_MATCHER = re.compile(r""" + (?: + (?P.)? + (?P[<>=^]) + )? + (?P[-+ ]?) + # Alt flag forces a slash and denominator in the output, even for + # integer-valued Fraction objects. + (?P\#)? + # We don't implement the zeropad flag since there's no single obvious way + # to interpret it. + (?P0|[1-9][0-9]*)? + (?P[,_])? + (?Pd?) +""", re.DOTALL | re.VERBOSE).fullmatch + + # Pattern for matching float-style format specifications; # supports 'e', 'E', 'f', 'F', 'g', 'G' and '%' presentation types. _FLOAT_FORMAT_SPECIFICATION_MATCHER = re.compile(r""" @@ -414,27 +434,39 @@ def __str__(self): else: return '%s/%s' % (self._numerator, self._denominator) - def __format__(self, format_spec, /): - """Format this fraction according to the given format specification.""" - - # Backwards compatiblility with existing formatting. - if not format_spec: - return str(self) + def _format_int_style(self, match): + """Helper method for __format__; handles 'd' presentation type.""" # Validate and parse the format specifier. - match = _FLOAT_FORMAT_SPECIFICATION_MATCHER(format_spec) - if match is None: - raise ValueError( - f"Invalid format specifier {format_spec!r} " - f"for object of type {type(self).__name__!r}" - ) - elif match["align"] is not None and match["zeropad"] is not None: - # Avoid the temptation to guess. - raise ValueError( - f"Invalid format specifier {format_spec!r} " - f"for object of type {type(self).__name__!r}; " - "can't use explicit alignment when zero-padding" - ) + fill = match["fill"] or " " + align = match["align"] or ">" + pos_sign = "" if match["sign"] == "-" else match["sign"] + alternate_form = bool(match["alt"]) + minimumwidth = int(match["minimumwidth"] or "0") + thousands_sep = match["thousands_sep"] or '' + + # Determine the body and sign representation. + n, d = self._numerator, self._denominator + if d > 1 or alternate_form: + body = f"{abs(n):{thousands_sep}}/{d:{thousands_sep}}" + else: + body = f"{abs(n):{thousands_sep}}" + sign = '-' if n < 0 else pos_sign + + # Pad with fill character if necessary and return. + padding = fill * (minimumwidth - len(sign) - len(body)) + if align == ">": + return padding + sign + body + elif align == "<": + return sign + body + padding + elif align == "^": + half = len(padding) // 2 + return padding[:half] + sign + body + padding[half:] + else: # align == "=" + return sign + padding + body + + def _format_float_style(self, match): + """Helper method for __format__; handles float presentation types.""" fill = match["fill"] or " " align = match["align"] or ">" pos_sign = "" if match["sign"] == "-" else match["sign"] @@ -530,6 +562,23 @@ def __format__(self, format_spec, /): else: # align == "=" return sign + padding + body + def __format__(self, format_spec, /): + """Format this fraction according to the given format specification.""" + + if match := _INT_FORMAT_SPECIFICATION_MATCHER(format_spec): + return self._format_int_style(match) + + if match := _FLOAT_FORMAT_SPECIFICATION_MATCHER(format_spec): + # Refuse the temptation to guess if both alignment _and_ + # zero padding are specified. + if match["align"] is None or match["zeropad"] is None: + return self._format_float_style(match) + + raise ValueError( + f"Invalid format specifier {format_spec!r} " + f"for object of type {type(self).__name__!r}" + ) + def _operator_fallbacks(monomorphic_operator, fallback_operator): """Generates forward and reverse operators given a purely-rational operator and a function from the operator module. diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index 499e3b6e656faa..cc0deb05430ec7 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -848,17 +848,57 @@ def denominator(self): self.assertEqual(type(f.numerator), myint) self.assertEqual(type(f.denominator), myint) - def test_format_no_presentation_type(self): - # Triples (fraction, specification, expected_result) + def test_format_d_presentation_type(self): + # Triples (fraction, specification, expected_result). We test both + # with and without a trailing 'd' on the specification. testcases = [ - (F(1, 3), '', '1/3'), - (F(-1, 3), '', '-1/3'), - (F(3), '', '3'), - (F(-3), '', '-3'), + # Explicit sign handling + (F(2, 3), '+', '+2/3'), + (F(-2, 3), '+', '-2/3'), + (F(3), '+', '+3'), + (F(-3), '+', '-3'), + (F(2, 3), ' ', ' 2/3'), + (F(-2, 3), ' ', '-2/3'), + (F(3), ' ', ' 3'), + (F(-3), ' ', '-3'), + (F(2, 3), '-', '2/3'), + (F(-2, 3), '-', '-2/3'), + (F(3), '-', '3'), + (F(-3), '-', '-3'), + # Padding + (F(0), '5', ' 0'), + (F(2, 3), '5', ' 2/3'), + (F(-2, 3), '5', ' -2/3'), + (F(2, 3), '0', '2/3'), + (F(2, 3), '1', '2/3'), + (F(2, 3), '2', '2/3'), + # Alignment + (F(2, 3), '<5', '2/3 '), + (F(2, 3), '>5', ' 2/3'), + (F(2, 3), '^5', ' 2/3 '), + (F(2, 3), '=5', ' 2/3'), + (F(-2, 3), '<5', '-2/3 '), + (F(-2, 3), '>5', ' -2/3'), + (F(-2, 3), '^5', '-2/3 '), + (F(-2, 3), '=5', '- 2/3'), + # Fill + (F(2, 3), 'X>5', 'XX2/3'), + (F(-2, 3), '.<5', '-2/3.'), + (F(-2, 3), '\n^6', '\n-2/3\n'), + # Thousands separators + (F(1234, 5679), ',', '1,234/5,679'), + (F(-1234, 5679), '_', '-1_234/5_679'), + (F(1234567), '_', '1_234_567'), + (F(-1234567), ',', '-1,234,567'), + # Alternate form forces a slash in the output + (F(123), '#', '123/1'), + (F(-123), '#', '-123/1'), + (F(0), '#', '0/1'), ] for fraction, spec, expected in testcases: with self.subTest(fraction=fraction, spec=spec): self.assertEqual(format(fraction, spec), expected) + self.assertEqual(format(fraction, spec + 'd'), expected) def test_format_e_presentation_type(self): # Triples (fraction, specification, expected_result) @@ -1218,6 +1258,12 @@ def test_invalid_formats(self): '.%', # Z instead of z for negative zero suppression 'Z.2f' + # D instead of d for integer-style formatting + '10D', + # z flag not supported for integer-style formatting + 'zd', + # zero padding not supported for integer-style formatting + '05d', ] for spec in invalid_specs: with self.subTest(spec=spec): From 13a60d7839d1ac557eee2321bbe489fbaf82aa1e Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 25 Oct 2023 12:44:10 +0100 Subject: [PATCH 02/13] Add docs --- Doc/library/fractions.rst | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 509c63686f5a7f..39d7bf0dbc3e84 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -106,6 +106,10 @@ another rational number, or from a string. presentation types ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` and ``"%""``. + .. versionchanged:: 3.13 + :class:`Fraction` instances now support integer-style formatting, with + presentation type ``"d"`` or missing presentation type. + .. attribute:: numerator Numerator of the Fraction in lowest term. @@ -204,10 +208,14 @@ another rational number, or from a string. Provides support for float-style formatting of :class:`Fraction` instances via the :meth:`str.format` method, the :func:`format` built-in function, or :ref:`Formatted string literals `. The - presentation types ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` - and ``"%"`` are supported. For these presentation types, formatting for a - :class:`Fraction` object ``x`` follows the rules outlined for - the :class:`float` type in the :ref:`formatspec` section. + presentation types ``"d"``, ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, + ``"G"`` and ``"%"`` are supported. For presentation types other than + ``"d"``, formatting for a :class:`Fraction` object follows the + rules outlined for the :class:`float` type in the :ref:`formatspec` + section. For presentation type ``"d"``, formatting follows the rules for + the :class:`int` type, except that the zero-fill flag is not supported. + If no presentation type is given, the rules are identical to those for + presentation type ``"d"``. Here are some examples:: @@ -221,7 +229,10 @@ another rational number, or from a string. >>> old_price, new_price = 499, 672 >>> "{:.2%} price increase".format(Fraction(new_price, old_price) - 1) '34.67% price increase' - + >>> format(Fraction(103993, 33102), '_d') + '103_993/33_102' + >>> format(Fraction(1, 7), '.^+10') + '...+1/7...' .. seealso:: From 751211a950fee768105e03af91e238c36e42127e Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 25 Oct 2023 13:08:03 +0100 Subject: [PATCH 03/13] Add news entry --- .../next/Library/2023-10-25-13-07-53.gh-issue-67790.jMn9Ad.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2023-10-25-13-07-53.gh-issue-67790.jMn9Ad.rst diff --git a/Misc/NEWS.d/next/Library/2023-10-25-13-07-53.gh-issue-67790.jMn9Ad.rst b/Misc/NEWS.d/next/Library/2023-10-25-13-07-53.gh-issue-67790.jMn9Ad.rst new file mode 100644 index 00000000000000..44c5702a6551b0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-10-25-13-07-53.gh-issue-67790.jMn9Ad.rst @@ -0,0 +1,2 @@ +Implement basic formatting support (minimum width, alignment, fill) for +:class:`fractions.Fraction`. From 51aa87e0a825b5d2cc011a3e51a955661cf724bc Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 25 Oct 2023 13:14:34 +0100 Subject: [PATCH 04/13] Add PR number --- Doc/whatsnew/3.13.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index dbc23f7972d507..9313728e4086d8 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -176,7 +176,7 @@ fractions * Objects of type :class:`fractions.Fraction` now support integer-style formatting with the ``d`` presentation type. (Contributed by Mark Dickinson - in :gh:`?????`) + in :gh:`111320`) io -- From 5c7ac04d2305fb5ac9f14edffd5ce03799d4e1a2 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 25 Oct 2023 13:18:29 +0100 Subject: [PATCH 05/13] Restore original line spacing in docs --- Doc/library/fractions.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 39d7bf0dbc3e84..f5c8cdeeea443e 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -234,6 +234,7 @@ another rational number, or from a string. >>> format(Fraction(1, 7), '.^+10') '...+1/7...' + .. seealso:: Module :mod:`numbers` From 3e7b6b61015f1ddf6616aad90d0fdab61cf03bcf Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 25 Oct 2023 15:16:55 +0100 Subject: [PATCH 06/13] Remove 'float-style', since it's now too specific --- Doc/library/fractions.rst | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index f5c8cdeeea443e..00221037ab1dd4 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -205,17 +205,16 @@ another rational number, or from a string. .. method:: __format__(format_spec, /) - Provides support for float-style formatting of :class:`Fraction` - instances via the :meth:`str.format` method, the :func:`format` built-in - function, or :ref:`Formatted string literals `. The - presentation types ``"d"``, ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, - ``"G"`` and ``"%"`` are supported. For presentation types other than - ``"d"``, formatting for a :class:`Fraction` object follows the - rules outlined for the :class:`float` type in the :ref:`formatspec` - section. For presentation type ``"d"``, formatting follows the rules for - the :class:`int` type, except that the zero-fill flag is not supported. - If no presentation type is given, the rules are identical to those for - presentation type ``"d"``. + Provides support for formatting of :class:`Fraction` instances via the + :meth:`str.format` method, the :func:`format` built-in function, or + :ref:`Formatted string literals `. The presentation types + ``"d"``, ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` and ``"%"`` + are supported. For presentation types other than ``"d"``, formatting for + a :class:`Fraction` object follows the rules outlined for the + :class:`float` type in the :ref:`formatspec` section. For presentation + type ``"d"``, formatting follows the rules for the :class:`int` type, + except that the zero-fill flag is not supported. If no presentation type + is given, the rules are identical to those for presentation type ``"d"``. Here are some examples:: From acfa57c3f0dc17e6ed810e2a9d8bcea1e0a53907 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Wed, 25 Oct 2023 15:19:25 +0100 Subject: [PATCH 07/13] Tighten doc wording --- Doc/library/fractions.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 00221037ab1dd4..ef60ea322db897 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -210,11 +210,11 @@ another rational number, or from a string. :ref:`Formatted string literals `. The presentation types ``"d"``, ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` and ``"%"`` are supported. For presentation types other than ``"d"``, formatting for - a :class:`Fraction` object follows the rules outlined for the - :class:`float` type in the :ref:`formatspec` section. For presentation - type ``"d"``, formatting follows the rules for the :class:`int` type, - except that the zero-fill flag is not supported. If no presentation type - is given, the rules are identical to those for presentation type ``"d"``. + :class:`Fraction` follows the rules outlined for the :class:`float` type + in the :ref:`formatspec` section. For presentation type ``"d"``, + formatting follows the rules for the :class:`int` type, except that the + zero-fill flag is not supported. If no presentation type is given, the + rules are identical to those for presentation type ``"d"``. Here are some examples:: From 82281821b461569286a979d35441eca7f20538a3 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 3 Dec 2023 09:55:27 +0000 Subject: [PATCH 08/13] Remove support for 'd' presentation type; don't refer to integer-style --- Doc/library/fractions.rst | 39 ++++++++++++++++++++++++-------------- Doc/whatsnew/3.13.rst | 5 +++-- Lib/fractions.py | 18 +++++++++--------- Lib/test/test_fractions.py | 6 ++---- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index ef60ea322db897..3ea223e7a807d2 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -107,8 +107,8 @@ another rational number, or from a string. and ``"%""``. .. versionchanged:: 3.13 - :class:`Fraction` instances now support integer-style formatting, with - presentation type ``"d"`` or missing presentation type. + Formatting of :class:`Fraction` instances without a presentation type + now supports fill, alignment, sign handling, minimum width and grouping. .. attribute:: numerator @@ -207,18 +207,33 @@ another rational number, or from a string. Provides support for formatting of :class:`Fraction` instances via the :meth:`str.format` method, the :func:`format` built-in function, or - :ref:`Formatted string literals `. The presentation types - ``"d"``, ``"e"``, ``"E"``, ``"f"``, ``"F"``, ``"g"``, ``"G"`` and ``"%"`` - are supported. For presentation types other than ``"d"``, formatting for - :class:`Fraction` follows the rules outlined for the :class:`float` type - in the :ref:`formatspec` section. For presentation type ``"d"``, - formatting follows the rules for the :class:`int` type, except that the - zero-fill flag is not supported. If no presentation type is given, the - rules are identical to those for presentation type ``"d"``. + :ref:`Formatted string literals `. + + If the ``format_spec`` format specification string does not end with one + of the presentation types ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, + ``'G'`` and ``'%'`` then formatting follows the general rules for fill, + alignment, sign handling, minimum width, and grouping as described in the + :ref:`format specification mini-language `. The "alternate + form" flag ``'#'`` is supported: if present, it forces the output string to + always include an explicit denominator, even when the value being + formatted is an exact integer. The zero-fill flag `'0'` is not supported. + + If the ``format_spec`` format specification string does end with one of + the presentation types ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, + ``'G'`` and ``'%'`` then formatting follows the rules outlined for the + :class:`float` type in the :ref:`formatspec` section. Here are some examples:: >>> from fractions import Fraction + >>> format(Fraction(103993, 33102), '_') + '103_993/33_102' + >>> format(Fraction(1, 7), '.^+10') + '...+1/7...' + >>> format(Fraction(3, 1), '') + '3' + >>> format(Fraction(3, 1), '#') + '3/1' >>> format(Fraction(1, 7), '.40g') '0.1428571428571428571428571428571428571429' >>> format(Fraction('1234567.855'), '_.2f') @@ -228,10 +243,6 @@ another rational number, or from a string. >>> old_price, new_price = 499, 672 >>> "{:.2%} price increase".format(Fraction(new_price, old_price) - 1) '34.67% price increase' - >>> format(Fraction(103993, 33102), '_d') - '103_993/33_102' - >>> format(Fraction(1, 7), '.^+10') - '...+1/7...' .. seealso:: diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index fbe852a172d93e..e172f80611f49a 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -195,8 +195,9 @@ doctest fractions --------- -* Objects of type :class:`fractions.Fraction` now support integer-style - formatting with the ``d`` presentation type. (Contributed by Mark Dickinson +* Formatting for objects of type :class:`fractions.Fraction` now supports + the standard format specification mini-language rules for fill, alignment, + sign handling, minimum width and grouping. (Contributed by Mark Dickinson in :gh:`111320`) glob diff --git a/Lib/fractions.py b/Lib/fractions.py index c51bba4411d4c9..6532d5d54e3c35 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -139,10 +139,8 @@ def _round_to_figures(n, d, figures): return sign, significand, exponent -# Pattern for matching int-style format specifications; -# supports 'd' presentation type (and missing presentation type, interpreted -# as equivalent to 'd'). -_INT_FORMAT_SPECIFICATION_MATCHER = re.compile(r""" +# Pattern for matching non-float-style format specifications. +_GENERAL_FORMAT_SPECIFICATION_MATCHER = re.compile(r""" (?: (?P.)? (?P[<>=^]) @@ -155,7 +153,6 @@ def _round_to_figures(n, d, figures): # to interpret it. (?P0|[1-9][0-9]*)? (?P[,_])? - (?Pd?) """, re.DOTALL | re.VERBOSE).fullmatch @@ -434,9 +431,12 @@ def __str__(self): else: return '%s/%s' % (self._numerator, self._denominator) - def _format_int_style(self, match): - """Helper method for __format__; handles 'd' presentation type.""" + def _format_general(self, match): + """Helper method for __format__. + Handles fill, alignment, signs, and thousands separators in the + case of no presentation type. + """ # Validate and parse the format specifier. fill = match["fill"] or " " align = match["align"] or ">" @@ -565,8 +565,8 @@ def _format_float_style(self, match): def __format__(self, format_spec, /): """Format this fraction according to the given format specification.""" - if match := _INT_FORMAT_SPECIFICATION_MATCHER(format_spec): - return self._format_int_style(match) + if match := _GENERAL_FORMAT_SPECIFICATION_MATCHER(format_spec): + return self._format_general(match) if match := _FLOAT_FORMAT_SPECIFICATION_MATCHER(format_spec): # Refuse the temptation to guess if both alignment _and_ diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index cc0deb05430ec7..a7355fd920bc5c 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -848,9 +848,8 @@ def denominator(self): self.assertEqual(type(f.numerator), myint) self.assertEqual(type(f.denominator), myint) - def test_format_d_presentation_type(self): - # Triples (fraction, specification, expected_result). We test both - # with and without a trailing 'd' on the specification. + def test_format_no_presentation_type(self): + # Triples (fraction, specification, expected_result). testcases = [ # Explicit sign handling (F(2, 3), '+', '+2/3'), @@ -898,7 +897,6 @@ def test_format_d_presentation_type(self): for fraction, spec, expected in testcases: with self.subTest(fraction=fraction, spec=spec): self.assertEqual(format(fraction, spec), expected) - self.assertEqual(format(fraction, spec + 'd'), expected) def test_format_e_presentation_type(self): # Triples (fraction, specification, expected_result) From 2fc7d5696ea592f8342ce4bbaa7ab75eb8fcb747 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 3 Dec 2023 09:57:45 +0000 Subject: [PATCH 09/13] Fix single backtick --- Doc/library/fractions.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 3ea223e7a807d2..b9efe2363433bc 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -216,7 +216,8 @@ another rational number, or from a string. :ref:`format specification mini-language `. The "alternate form" flag ``'#'`` is supported: if present, it forces the output string to always include an explicit denominator, even when the value being - formatted is an exact integer. The zero-fill flag `'0'` is not supported. + formatted is an exact integer. The zero-fill flag ``'0'`` is not + supported. If the ``format_spec`` format specification string does end with one of the presentation types ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, From 0df75d8288418b57cb2daf8f77fa41389a7e5947 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 3 Dec 2023 09:59:27 +0000 Subject: [PATCH 10/13] Fix grammar - 'or' is better than 'and' here --- Doc/library/fractions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index b9efe2363433bc..d319a0ada9d910 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -211,7 +211,7 @@ another rational number, or from a string. If the ``format_spec`` format specification string does not end with one of the presentation types ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, - ``'G'`` and ``'%'`` then formatting follows the general rules for fill, + ``'G'`` or ``'%'`` then formatting follows the general rules for fill, alignment, sign handling, minimum width, and grouping as described in the :ref:`format specification mini-language `. The "alternate form" flag ``'#'`` is supported: if present, it forces the output string to @@ -221,7 +221,7 @@ another rational number, or from a string. If the ``format_spec`` format specification string does end with one of the presentation types ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, - ``'G'`` and ``'%'`` then formatting follows the rules outlined for the + ``'G'`` or ``'%'`` then formatting follows the rules outlined for the :class:`float` type in the :ref:`formatspec` section. Here are some examples:: From 9cdc4084cda711177f52d055f53a738a93469f93 Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 3 Dec 2023 10:15:43 +0000 Subject: [PATCH 11/13] Tweak wording --- Doc/library/fractions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index d319a0ada9d910..7a6697b0786b23 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -219,7 +219,7 @@ another rational number, or from a string. formatted is an exact integer. The zero-fill flag ``'0'`` is not supported. - If the ``format_spec`` format specification string does end with one of + If the ``format_spec`` format specification string ends with one of the presentation types ``'e'``, ``'E'``, ``'f'``, ``'F'``, ``'g'``, ``'G'`` or ``'%'`` then formatting follows the rules outlined for the :class:`float` type in the :ref:`formatspec` section. From 30260f99b88e5c0fd9fd5d5494f3768e8e69c4bb Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 3 Dec 2023 10:20:09 +0000 Subject: [PATCH 12/13] Update invalid format tests --- Lib/test/test_fractions.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_fractions.py b/Lib/test/test_fractions.py index a7355fd920bc5c..84779526ce0eb0 100644 --- a/Lib/test/test_fractions.py +++ b/Lib/test/test_fractions.py @@ -1256,12 +1256,10 @@ def test_invalid_formats(self): '.%', # Z instead of z for negative zero suppression 'Z.2f' - # D instead of d for integer-style formatting - '10D', - # z flag not supported for integer-style formatting - 'zd', - # zero padding not supported for integer-style formatting - '05d', + # z flag not supported for general formatting + 'z', + # zero padding not supported for general formatting + '05', ] for spec in invalid_specs: with self.subTest(spec=spec): From e736e8ea2eaebaf034055d988f6b8f5cac7b1cac Mon Sep 17 00:00:00 2001 From: Mark Dickinson Date: Sun, 3 Dec 2023 10:41:50 +0000 Subject: [PATCH 13/13] Fix a long line in the .rst source --- Doc/library/fractions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/fractions.rst b/Doc/library/fractions.rst index 7a6697b0786b23..887c3844d20faa 100644 --- a/Doc/library/fractions.rst +++ b/Doc/library/fractions.rst @@ -214,8 +214,8 @@ another rational number, or from a string. ``'G'`` or ``'%'`` then formatting follows the general rules for fill, alignment, sign handling, minimum width, and grouping as described in the :ref:`format specification mini-language `. The "alternate - form" flag ``'#'`` is supported: if present, it forces the output string to - always include an explicit denominator, even when the value being + form" flag ``'#'`` is supported: if present, it forces the output string + to always include an explicit denominator, even when the value being formatted is an exact integer. The zero-fill flag ``'0'`` is not supported. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy