Improve `printf`-style formatting docs for non-built-in types
Open
Nobody has claimed this yet.
docs
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
Add a description about how Decimal behaves differently with format and % formatting in https://docs.python.org/3/library/string.html#format-specification-mini-language
For __format__, Decimal is formatted with the highest possible precision as it is.
For % formatting, Decimal is converted to float before formatting.
These behaviors have not changed since they were added.
- The Decimal class was added in Python 2.4 (https://docs.python.org/2.4/whatsnew/whatsnew24.html).
- The __format__ method was added in Python 2.6 (https://docs.python.org/2.6/whatsnew/2.6.html).
Compare:
sys.version |
'%f' % 11111111111111111111.0 |
'%f' % Decimal('11111111111111111111.0') |
Decimal('11111111111111111111.0').__format__('f') |
'%e' % 0.0 |
'%e' % Decimal('0.0') |
Decimal('0.0').__format__('e') |
'%.20e' % 11111111111111111111.0 |
'%.20e' % Decimal('11111111111111111111.0') |
Decimal('11111111111111111111.0').__format__('.20e') |
'%.20g' % 11111111111111111111.0 |
'%.20g' % Decimal('11111111111111111111.0') |
Decimal('11111111111111111111.0').__format__('.20g') |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| '2.4.4 (#71, Oct 18 2006, 08:34:43) [MSC v.1310 32 bit (Intel)]' | '11111111111111111000.000000' | '11111111111111111000.000000' | Exception | '0.000000e+000' | '0.000000e+000' | Exception | '1.11111111111111110000e+019' | '1.11111111111111110000e+019' | Exception | '11111111111111111000' | '11111111111111111000' | Exception |
| '2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)]' | '11111111111111111000.000000' | '11111111111111111000.000000' | '11111111111111111111.0' | '0.000000e+00' | '0.000000e+00' | '0e-1' | '1.11111111111111110000e+19' | '1.11111111111111110000e+19' | '1.11111111111111111110e+19' | '11111111111111111000' | '11111111111111111000' | '11111111111111111111' |
| '2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)]' | '11111111111111110656.000000' | '11111111111111110656.000000' | '11111111111111111111.0' | '0.000000e+00' | '0.000000e+00' | '0e-1' | '1.11111111111111106560e+19' | '1.11111111111111106560e+19' | '1.11111111111111111110e+19' | '11111111111111110656' | '11111111111111110656' | '11111111111111111111' |
| '3.14.0 (tags/v3.14.0:ebf955d, Oct 7 2025, 10:06:33) [MSC v.1944 32 bit (Intel)]' | '11111111111111110656.000000' | '11111111111111110656.000000' | '11111111111111111111.0' | '0.000000e+00' | '0.000000e+00' | '0e-1' | '1.11111111111111106560e+19' | '1.11111111111111106560e+19' | '1.11111111111111111110e+19' | '11111111111111110656' | '11111111111111110656' | '11111111111111111111' |
| '3.14.0 (tags/v3.14.0:ebf955d, Oct 7 2025, 10:15:03) [MSC v.1944 64 bit (AMD64)]' | '11111111111111110656.000000' | '11111111111111110656.000000' | '11111111111111111111.0' | '0.000000e+00' | '0.000000e+00' | '0e-1' | '1.11111111111111106560e+19' | '1.11111111111111106560e+19' | '1.11111111111111111110e+19' | '11111111111111110656' | '11111111111111110656' | '11111111111111111111' |
| '3.15.0a2 (tags/v3.15.0a2:a625628, Nov 18 2025, 18:12:01) [MSC v.1944 64 bit (AMD64)]' | '11111111111111110656.000000' | '11111111111111110656.000000' | '11111111111111111111.0' | '0.000000e+00' | '0.000000e+00' | '0e-1' | '1.11111111111111106560e+19' | '1.11111111111111106560e+19' | '1.11111111111111111110e+19' | '11111111111111110656' | '11111111111111110656' | '11111111111111111111' |
# ./test.py
import sys
from decimal import Decimal
for expr in (
"sys.version",
"'%f' % 12345123451234512345.0",
"'%f' % Decimal('12345123451234512345.0')",
"Decimal('12345123451234512345.0').__format__('f')",
"'%e' % 0.0",
"'%e' % Decimal('0.0')",
"Decimal('0.0').__format__('e')",
"'%.20e' % 12345123451234512345.0",
"'%.20e' % Decimal('12345123451234512345.0')",
"Decimal('12345123451234512345.0').__format__('.20e')",
"'%.20g' % 12345123451234512345.0",
"'%.20g' % Decimal('12345123451234512345.0')",
"Decimal('12345123451234512345.0').__format__('.20g')",
):
print(expr)
try:
print(repr(eval(expr)))
except Exception:
print('Exception')
print('')
# ./test_runner.py
from pathlib import Path
from subprocess import run, PIPE
PYTHON_DIR_ROOT = r"C:\python_dir_root"
def print_row(row, file):
for v in row: print(f"| {v} ", end='', file=file)
print("|", file=file)
def print_md_table(headers, rows, file):
print_row(headers, file=file)
print_row(['---:'] * len(headers), file=file)
for row in rows: print_row(row, file=file)
print(file=file)
rows = []
for dir in Path(PYTHON_DIR_ROOT).iterdir():
out = run([str(dir/"python.exe"), "./test.py"], stdout=PIPE).stdout
out = out.decode('utf-8').splitlines()
headers = [f"`{h}`" for h in out[::3]]
rows.append(out[1::3])
with open("./test_result.md", 'w', encoding='utf-8') as fp:
print_md_table(headers, rows, file=fp)
Linked PRs
- gh-142117
- gh-142126
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the format specification mini-language section of docs.python.org/3/library/string.html and review the Decimal examples and formatting behavior described in the issue. Check linked PRs gh-142117 and gh-142126 first; the work is done when the documentation clearly distinguishes format from % formatting for Decimal.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100