cpython icon indicating copy to clipboard operation
cpython copied to clipboard

Decimal class allows underscores that are not PEP 515 compliant

Open treyhunner opened this issue 1 year ago • 0 comments

Bug report

Bug description:

The decimal.Decimal class allows for underscores around numbers.

>>> Decimal("_1_")  # 1 with wings
Decimal('1')
>>> Decimal("____0____.____0____")  # Totoro's 0
Decimal('0.0')

This has not caused an issue for me in my own code. I am simply reporting this as a minor implementation bug.

Background

PEP 515 notes that underscore separators in numeric literals are only allowed between digits (no leading/trailing underscores allowed) and consecutive underscores are not allowed.

The current proposal is to allow one underscore between digits, and after base specifiers in numeric literals. The underscores have no semantic meaning, and literals are parsed as if the underscores were absent.

Non-issue elsewhere

The built-in float, int, and complex are compliant with the PEP.

>>> float("_1_")
Traceback (most recent call last):
  File "<python-input-14>", line 1, in <module>
    float("_1_")
    ~~~~~^^^^^^^
ValueError: could not convert string to float: '_1_'
>>> int("_1_")
Traceback (most recent call last):
  File "<python-input-15>", line 1, in <module>
    int("_1_")
    ~~~^^^^^^^
ValueError: invalid literal for int() with base 10: '_1_'
>>> complex("_1_")
Traceback (most recent call last):
  File "<python-input-16>", line 1, in <module>
    complex("_1_")
    ~~~~~~~^^^^^^^
ValueError: could not convert string to complex: '_1_'

Possible cause

It looks like _decimal.c skips over _.

Likewise, _pydecimal.py strips all _.

CPython versions tested on:

3.8, 3.9, 3.10, 3.11, 3.12, 3.13, CPython main branch

Operating systems tested on:

Linux

treyhunner avatar Jul 04 '24 21:07 treyhunner