Skip to content

PEP 786: Precision and Modulo-Precision Flag format specifiers for integer fields #4416

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

jb2170
Copy link

@jb2170 jb2170 commented May 8, 2025

New rebased PR with the correct branch name to avoid confusion (786 not 791).

Thank you Alyssa for sponsoring this!

There is a TODO section in the PEP that shall perish as the PEP is tweaked before accepting

Relevant discussions, issues, PRs linked

Basic requirements (all PEP Types)

  • Read and followed PEP 1 & PEP 12
  • File created from the latest PEP template
  • PEP has next available number, & set in filename (pep-NNNN.rst), PR title (PEP 123: <Title of PEP>) and PEP header
  • Title clearly, accurately and concisely describes the content in 79 characters or less
  • Core dev/PEP editor listed as Author or Sponsor, and formally confirmed their approval: @ncoghlan
  • Author, Status (Draft), Type and Created headers filled out correctly
  • PEP-Delegate, Topic, Requires and Replaces headers completed if appropriate: Is a PEP-Delegate required?
  • Required sections included
    • Abstract (first section)
    • Copyright (last section; exact wording from template required)
  • Code is well-formatted (PEP 7/PEP 8) and is in code blocks, with the right lexer names if non-Python: everything but 80-column line length, so as to avoid tedious re-aligning during this draft stage
  • PEP builds with no warnings, pre-commit checks pass and content displays as intended in the rendered HTML
  • Authors/sponsor added to .github/CODEOWNERS for the PEP

Standards Track requirements

  • PEP topic discussed in a suitable venue with general agreement that a PEP is appropriate
  • Suggested sections included (unless not applicable)
    • Motivation: included in Rationale
    • Rationale
    • Specification: on the TODO list if an RFC 2119 style summary is needed
    • Backwards Compatibility
    • Security Implications: not needed?
    • How to Teach This: Examples And Teaching section
    • Reference Implementation
    • Rejected Ideas
    • Open Issues: None so far
  • Python-Version set to valid (pre-beta) future Python version, if relevant: pending
  • Any project stated in the PEP as supporting/endorsing/benefiting from the PEP formally confirmed such: none
  • Right before or after initial merging, PEP discussion thread created and linked to in Discussions-To and Post-History

📚 Documentation preview 📚: https://pep-previews--4416.org.readthedocs.build/pep-0786/

@jb2170 jb2170 requested a review from a team as a code owner May 8, 2025 01:09
@AA-Turner AA-Turner added the new-pep A new draft PEP submitted for initial review label May 8, 2025
@AA-Turner AA-Turner requested a review from ncoghlan May 8, 2025 01:19
Copy link
Member

@AA-Turner AA-Turner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't read the content of the PEP yet, but a few notes:


* Format all lines to ~80 characters. I've left this formatting until we're happy with the contents.
* RFC 2119 Style Specification? After all is said and done here.
* Add Sergey and Raymond to the authors field, or is Thanks enough?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps easiest to ask them which they'd prefer?

jb2170 added 2 commits May 8, 2025 03:29
It's better to give the formatspec one canonical ordering than permit an
overly liberal rearrangeability.

If commutativity were added, then as well as the messy description required
for the docs for the particular case of `int` data, two people could write
two different format spec that result in the same output and not realise
it or agree, because they've written different things, leading to confusion etc.
Comment on lines +666 to 668
peps/pep-0786.rst @ncoghlan
# ...
peps/pep-0787.rst @ncoghlan
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove this gap:

Suggested change
peps/pep-0786.rst @ncoghlan
# ...
peps/pep-0787.rst @ncoghlan
peps/pep-0786.rst @ncoghlan
peps/pep-0787.rst @ncoghlan

@@ -0,0 +1,355 @@
PEP: 786
Title: Precision and Modulo-Precision Flag format specifiers for integer fields
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consistent case: https://devguide.python.org/documentation/style-guide/#capitalization

Suggested change
Title: Precision and Modulo-Precision Flag format specifiers for integer fields
Title: Precision and modulo-precision flag format specifiers for integer fields

Rationale
=========

When string formatting integers in binary octal and hexadecimal, one often desires the resulting string to contain a guaranteed minimum number of digits. For unsigned integers of known machine-width bounds (eg 8 bit bytes) this often also ends up the exact resulting number of digits. This has previously been implemented in the old-style ``%`` formatting using the ``.`` "precision" format specifier, closely related to that of the C programming language.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid Latin abbreviations: https://devguide.python.org/documentation/style-guide/#use-simple-language

Suggested change
When string formatting integers in binary octal and hexadecimal, one often desires the resulting string to contain a guaranteed minimum number of digits. For unsigned integers of known machine-width bounds (eg 8 bit bytes) this often also ends up the exact resulting number of digits. This has previously been implemented in the old-style ``%`` formatting using the ``.`` "precision" format specifier, closely related to that of the C programming language.
When string formatting integers in binary octal and hexadecimal, one often desires the resulting string to contain a guaranteed minimum number of digits. For unsigned integers of known machine-width bounds (for example, 8-bit bytes) this often also ends up the exact resulting number of digits. This has previously been implemented in the old-style ``%`` formatting using the ``.`` "precision" format specifier, closely related to that of the C programming language.

>>> "0o%.3o" % 18
'0o022' # three octal digits, ideal for displaying a umask or file permissions

When :pep:`3101` new-style formatting was first introduced, used in ``str.format`` and ``f``\ strings, the `format specification <formatspec_>`_ was simple enough that the behavior of "precision" could be trivially emulated with the ``width`` format specifier. Precision therefore was left unimplemented and forbidden for ``int`` fields. However, as time has progressed and new format specifiers have been added, whose interactions with ``width`` noticeably diverge its behavior away from emulating precision, the readmission of precision as its own format specifier, ``.``, is sufficiently warranted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
When :pep:`3101` new-style formatting was first introduced, used in ``str.format`` and ``f``\ strings, the `format specification <formatspec_>`_ was simple enough that the behavior of "precision" could be trivially emulated with the ``width`` format specifier. Precision therefore was left unimplemented and forbidden for ``int`` fields. However, as time has progressed and new format specifiers have been added, whose interactions with ``width`` noticeably diverge its behavior away from emulating precision, the readmission of precision as its own format specifier, ``.``, is sufficiently warranted.
When :pep:`3101` new-style formatting was first introduced, used in ``str.format`` and f-strings, the `format specification <formatspec_>`_ was simple enough that the behavior of "precision" could be trivially emulated with the ``width`` format specifier. Precision therefore was left unimplemented and forbidden for ``int`` fields. However, as time has progressed and new format specifiers have been added, whose interactions with ``width`` noticeably diverge its behavior away from emulating precision, the readmission of precision as its own format specifier, ``.``, is sufficiently warranted.

>>> f"{x:#08b}"
'0b001100' # we wanted 8 bits, not 6 :(

One could attempt to argue that since the length of a prefix is known to always be 2, it can be accounted for manually by adding 2 to the desired number of digits. Consider however the following demonstrations of why this is a bad idea:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
One could attempt to argue that since the length of a prefix is known to always be 2, it can be accounted for manually by adding 2 to the desired number of digits. Consider however the following demonstrations of why this is a bad idea:
One could attempt to argue that since the length of a prefix is known to always be two, it can be accounted for manually by adding two to the desired number of digits. Consider however the following demonstrations of why this is a bad idea:

>>> f"{y:z#.8b}"
'0b[...1]11111111'

This may have been useful to educate beginner users on how bitwise binary operations work, for example showing how ``-1 & x`` is always trivially equal to ``x``, or how the binary representation of the negation of a number can be obtained by adding one to its bitwise complement:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This may have been useful to educate beginner users on how bitwise binary operations work, for example showing how ``-1 & x`` is always trivially equal to ``x``, or how the binary representation of the negation of a number can be obtained by adding one to its bitwise complement:
This may have been useful to educate beginners on how bitwise binary operations work, for example showing how ``-1 & x`` is always trivially equal to ``x``, or how the binary representation of the negation of a number can be obtained by adding one to its bitwise complement:


Verdict:

- Whilst graphically attractive, ``!`` would add too much more clutter to the format specification for a purpose that can be achieved by overloading the preexisting ``z`` flag.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"too much" or "much more" instead of "too much more"?

Suggested change
- Whilst graphically attractive, ``!`` would add too much more clutter to the format specification for a purpose that can be achieved by overloading the preexisting ``z`` flag.
- Whilst graphically attractive, ``!`` would add too much clutter to the format specification for a purpose that can be achieved by overloading the preexisting ``z`` flag.
Suggested change
- Whilst graphically attractive, ``!`` would add too much more clutter to the format specification for a purpose that can be achieved by overloading the preexisting ``z`` flag.
- Whilst graphically attractive, ``!`` would add much more clutter to the format specification for a purpose that can be achieved by overloading the preexisting ``z`` flag.

Backwards Compatibility
=======================

To quote :pep:`682`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To quote :pep:`682`
To quote :pep:`682`:


To quote :pep:`682`

The new formatting behavior is opt-in, so numerical formatting of existing programs will not be affected
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The new formatting behavior is opt-in, so numerical formatting of existing programs will not be affected
The new formatting behavior is opt-in, so numerical formatting of existing programs will not be affected.


The new formatting behavior is opt-in, so numerical formatting of existing programs will not be affected

unless someone out there is specifically relying upon ``.`` raising a ``ValueError`` for integers as it currently does, but to quote :pep:`475`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
unless someone out there is specifically relying upon ``.`` raising a ``ValueError`` for integers as it currently does, but to quote :pep:`475`
unless someone out there is specifically relying upon ``.`` raising a ``ValueError`` for integers as it currently does, but to quote :pep:`475`:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-pep A new draft PEP submitted for initial review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants