@@ -398,13 +398,24 @@ following:
398398
399399.. index :: single: z; in string formatting
400400
401- The ``'z' `` option coerces negative zero floating-point values to positive
402- zero after rounding to the format precision. This option is only valid for
403- floating-point presentation types.
401+ For floating-point presentation types the ``'z' `` option coerces negative zero
402+ floating-point values to positive zero after rounding to the format precision.
403+
404+ For integer presentation types ``'b' ``, ``'o' ``, ``'x' ``, and ``'X'``formatted
405+ with precision, the ``'z' `` 'modulo-precision' option first reduces the integer
406+ into ``range(base ** precision) ``. The result is a predictable two's complement
407+ style formatting with the number of digits *exactly * equal to the precision.
408+ This is especially useful for formatting negative numbers with known bounds
409+ in environments that deal with fixed widths integers, such as :mod: `struct `.
410+
411+ For other presentation types ``z `` is an invalid specifier.
404412
405413.. versionchanged :: 3.11
406414 Added the ``'z' `` option (see also :pep: `682 `).
407415
416+ .. versionchanged :: next
417+ Implemented the ``'z' `` specifier for integer fields (see also :pep: `786 `).
418+
408419.. index :: single: # (hash); in string formatting
409420
410421The ``'#' `` option causes the "alternate form" to be used for the
@@ -455,13 +466,30 @@ excluding :class:`complex`. This is equivalent to a *fill* character of
455466 Preceding the *width * field by ``'0' `` no longer affects the default
456467 alignment for strings.
457468
458- The *precision * is a decimal integer indicating how many digits should be
459- displayed after the decimal point for presentation types
460- ``'f' `` and ``'F' ``, or before and after the decimal point for presentation
461- types ``'g' `` or ``'G' ``. For string presentation types the field
462- indicates the maximum field size - in other words, how many characters will be
463- used from the field content. The *precision * is not allowed for integer
464- presentation types.
469+ .. index :: single: precision; in string formatting
470+
471+ For floating point presentation types ``'f' `` and ``'F' `` the *precision *
472+ is a decimal integer indicating how many digits should be displayed after
473+ the decimal point. For presentation types ``'g' `` and ``'G' `` the precision
474+ is how many digits should be displayed in total before and after the
475+ decimal point.
476+
477+ For string presentation types the precision indicates the maximum
478+ field size - in other words, how many characters will be used from the
479+ field content.
480+
481+ For integer presentation types (excluding ``'c' ``), the precision defines the
482+ minimum number of digits to be displayed, the result padded with leading
483+ zeros if the length of the digits is smaller than the precision specified.
484+ Precision differs from *width *, as only the digits of the number contribute
485+ to the precision count - this is useful when one combines multiple format
486+ specifiers together, and one desires a minimum number of digits, not a
487+ minimum overall string length. ``z `` can be combined with precision to
488+ format the number to **exactly ** the precision number of digits, truncating
489+ the result as necessary.
490+
491+ .. versionchanged :: next
492+ Implemented the *precision * specifier for integer presentation types.
465493
466494The ``'_' `` or ``',' `` option after *precision * means the use of an underscore
467495or a comma for a thousands separator of the fractional part for floating-point
@@ -772,6 +800,47 @@ Nesting arguments and more complex examples::
772800 10 A 12 1010
773801 11 B 13 1011
774802
803+ Comparing the precision and width specifiers::
804+
805+ >>> x = 10
806+ >>> f"{x:#02x}"
807+ '0xa'
808+ >>> # we really wanted 2 digits
809+ >>> f"{x:#.2x}"
810+ '0x0a'
811+ >>> # that's better
812+ >>>
813+ >>> def hexdump(b: bytes) -> str:
814+ ... return " ".join(f"{c:#.2x}" for c in b)
815+ >>>
816+ >>> hexdump(b"GET /\r\n\r\n")
817+ '0x47 0x45 0x54 0x20 0x2f 0x0d 0x0a 0x0d 0x0a'
818+ >>> # observe the CR and LF bytes padded to precision 2
819+ >>> # in this basic HTTP/0.9 request
820+ >>>
821+ >>> def unicode_dump(s: str) -> str:
822+ ... return " ".join(f"U+{ord(c):.4X}" for c in s)
823+ >>>
824+ >>> unicode_dump("USA 🦅")
825+ 'U+0055 U+0053 U+0041 U+0020 U+1F985'
826+ >>> # observe the last character's Unicode codepoint has 5 digits;
827+ >>> # precision is only the minimum number of digits
828+
829+ Using the modulo-precision flag::
830+
831+ >>> import struct
832+ >>> my_struct = b"\xff"
833+ >>> (t,) = struct.unpack('b', my_struct) # signed char
834+ >>> print(t, f"{t:#.2x}", f"{t:z#.2x}")
835+ '-1 -0x01 0xff'
836+ >>> (t,) = struct.unpack('B', my_struct) # unsigned char
837+ >>> print(t, f"{t:#.2x}", f"{t:z#.2x}")
838+ '255 0xff 0xff'
839+
840+ Observe that in both the signed and unsigned unpacking the two's complement
841+ formatting mode (``z ``) produces a predictable, consistent string, suitable
842+ for displaying byte-like output.
843+
775844
776845
777846.. _template-strings :
0 commit comments