Skip to content

Commit 5f731e5

Browse files
committed
Update Docs: string.rst describes precision and modulo-precision
1 parent c7c6a7d commit 5f731e5

File tree

1 file changed

+79
-10
lines changed

1 file changed

+79
-10
lines changed

Doc/library/string.rst

Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,24 @@ following:
403403

404404
.. index:: single: z; in string formatting
405405

406-
The ``'z'`` option coerces negative zero floating-point values to positive
407-
zero after rounding to the format precision. This option is only valid for
408-
floating-point presentation types.
406+
For floating-point presentation types the ``'z'`` option coerces negative zero
407+
floating-point values to positive zero after rounding to the format precision.
408+
409+
For integer presentation types ``'b'``, ``'o'``, ``'x'``, and ``'X'``formatted
410+
with precision, the ``'z'`` 'modulo-precision' option first reduces the integer
411+
into ``range(base ** precision)``. The result is a predictable two's complement
412+
style formatting with the number of digits *exactly* equal to the precision.
413+
This is especially useful for formatting negative numbers with known bounds
414+
in environments that deal with fixed widths integers, such as :mod:`struct`.
415+
416+
For other presentation types ``z`` is an invalid specifier.
409417

410418
.. versionchanged:: 3.11
411419
Added the ``'z'`` option (see also :pep:`682`).
412420

421+
.. versionchanged:: next
422+
Implemented the ``'z'`` specifier for integer fields (see also :pep:`786`).
423+
413424
.. index:: single: # (hash); in string formatting
414425

415426
The ``'#'`` option causes the "alternate form" to be used for the
@@ -437,13 +448,30 @@ excluding :class:`complex`. This is equivalent to a *fill* character of
437448
Preceding the *width* field by ``'0'`` no longer affects the default
438449
alignment for strings.
439450

440-
The *precision* is a decimal integer indicating how many digits should be
441-
displayed after the decimal point for presentation types
442-
``'f'`` and ``'F'``, or before and after the decimal point for presentation
443-
types ``'g'`` or ``'G'``. For string presentation types the field
444-
indicates the maximum field size - in other words, how many characters will be
445-
used from the field content. The *precision* is not allowed for integer
446-
presentation types.
451+
.. index:: single: precision; in string formatting
452+
453+
For floating point presentation types ``'f'`` and ``'F'`` the *precision*
454+
is a decimal integer indicating how many digits should be displayed after
455+
the decimal point. For presentation types ``'g'`` and ``'G'`` the precision
456+
is how many digits should be displayed in total before and after the
457+
decimal point.
458+
459+
For string presentation types the precision indicates the maximum
460+
field size - in other words, how many characters will be used from the
461+
field content.
462+
463+
For integer presentation types (excluding ``'c'``), the precision defines the
464+
minimum number of digits to be displayed, the result padded with leading
465+
zeros if the length of the digits is smaller than the precision specified.
466+
Precision differs from *width*, as only the digits of the number contribute
467+
to the precision count - this is useful when one combines multiple format
468+
specifiers together, and one desires a minimum number of digits, not a
469+
minimum overall string length. ``z`` can be combined with precision to
470+
format the number to **exactly** the precision number of digits, truncating
471+
the result as necessary.
472+
473+
.. versionchanged:: next
474+
Implemented the *precision* specifier for integer presentation types.
447475

448476
The *grouping* option after *width* and *precision* fields specifies
449477
a digit group separator for the integral and fractional parts
@@ -793,6 +821,47 @@ Nesting arguments and more complex examples::
793821
10 A 12 1010
794822
11 B 13 1011
795823

824+
Comparing the precision and width specifiers::
825+
826+
>>> x = 10
827+
>>> f"{x:#02x}"
828+
'0xa'
829+
>>> # we really wanted 2 digits
830+
>>> f"{x:#.2x}"
831+
'0x0a'
832+
>>> # that's better
833+
>>>
834+
>>> def hexdump(b: bytes) -> str:
835+
... return " ".join(f"{c:#.2x}" for c in b)
836+
>>>
837+
>>> hexdump(b"GET /\r\n\r\n")
838+
'0x47 0x45 0x54 0x20 0x2f 0x0d 0x0a 0x0d 0x0a'
839+
>>> # observe the CR and LF bytes padded to precision 2
840+
>>> # in this basic HTTP/0.9 request
841+
>>>
842+
>>> def unicode_dump(s: str) -> str:
843+
... return " ".join(f"U+{ord(c):.4X}" for c in s)
844+
>>>
845+
>>> unicode_dump("USA 🦅")
846+
'U+0055 U+0053 U+0041 U+0020 U+1F985'
847+
>>> # observe the last character's Unicode codepoint has 5 digits;
848+
>>> # precision is only the minimum number of digits
849+
850+
Using the modulo-precision flag::
851+
852+
>>> import struct
853+
>>> my_struct = b"\xff"
854+
>>> (t,) = struct.unpack('b', my_struct) # signed char
855+
>>> print(t, f"{t:#.2x}", f"{t:z#.2x}")
856+
'-1 -0x01 0xff'
857+
>>> (t,) = struct.unpack('B', my_struct) # unsigned char
858+
>>> print(t, f"{t:#.2x}", f"{t:z#.2x}")
859+
'255 0xff 0xff'
860+
861+
Observe that in both the signed and unsigned unpacking the two's complement
862+
formatting mode (``z``) produces a predictable, consistent string, suitable
863+
for displaying byte-like output.
864+
796865

797866

798867
.. _template-strings-pep292:

0 commit comments

Comments
 (0)