Skip to content

Inconsistency in fractions.Fraction() initialization error with invalid string #114014

Description

Bug description:

The fractions.Fraction() error message differs when, for example, 123.dd is done instead of 123.aa; they should be equal.

>>> from fractions import Fraction
>>> Fraction("123.dd")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    Fraction("123.dd")
  File "C:\Program Files\Python313\Lib\fractions.py", line 251, in __new__
    numerator = numerator * scale + int(decimal)
                                    ^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'dd'
>>> Fraction("123.aa")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    Fraction("123.aa")
  File "C:\Program Files\Python313\Lib\fractions.py", line 239, in __new__
    raise ValueError('Invalid literal for Fraction: %r' %
ValueError: Invalid literal for Fraction: '123.aa'

I discovered this bug while inspecting the rational parsing regex.

cpython/Lib/fractions.py

Lines 57 to 69 in dac1da2

_RATIONAL_FORMAT = re.compile(r"""
\A\s* # optional whitespace at the start,
(?P<sign>[-+]?) # an optional sign, then
(?=\d|\.\d) # lookahead for digit or .digit
(?P<num>\d*|\d+(_\d+)*) # numerator (possibly empty)
(?: # followed by
(?:\s*/\s*(?P<denom>\d+(_\d+)*))? # an optional denominator
| # or
(?:\.(?P<decimal>d*|\d+(_\d+)*))? # an optional fractional part
(?:E(?P<exp>[-+]?\d+(_\d+)*))? # and optional exponent
)
\s*\Z # and optional whitespace to finish
""", re.VERBOSE | re.IGNORECASE)

I think the bug stems from line 65's matching of d* instead of \d*.

CPython versions tested on:

3.13

Operating systems tested on:

Windows

Linked PRs

Activity

  1. added a commit that references this issue on Jan 13, 2024
    4f550ea
  2. terryjreedy commented on Jan 13, 2024

    @terryjreedy
    Member

    @mdickinson fractions issue

  3. added
    stdlibStandard Library Python modules in the Lib/ directory
    on Jan 13, 2024
  4. mdickinson commented on Jan 13, 2024

    @mdickinson
    Member

    Nice find! Agreed that this is a clear bug. Looks like it was introduced in #26422, so the bug is present in 3.11 onwards; the fix should be backported to 3.12 and 3.11.

  5. added a commit that references this issue on Jan 13, 2024
  6. added a commit that references this issue on Jan 13, 2024
  7. added a commit that references this issue on Jan 13, 2024
  8. added 2 commits that reference this issue on Jan 13, 2024
  9. added a commit that references this issue on Jan 22, 2024
  10. added a commit that references this issue on Feb 11, 2024
  11. added a commit that references this issue on Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions