Skip to content

Failed doctest test for decimal.Decimal.__round__ #109861

Closed

Description

@serhiy-storchaka

Bug report

Bug description:

$ ./python -m test -v test_decimal -m __round__
...
======================================================================
FAIL: __round__ (decimal.Decimal)
Doctest: decimal.Decimal.__round__
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/serhiy/py/cpython/Lib/doctest.py", line 2250, in runTest
    raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for decimal.Decimal.__round__
  File "/home/serhiy/py/cpython/Lib/decimal.py", line unknown line number, in __round__

----------------------------------------------------------------------
File "/home/serhiy/py/cpython/Lib/decimal.py", line ?, in decimal.Decimal.__round__
Failed example:
    round(Decimal('-Infinity'), 37)
Exception raised:
    Traceback (most recent call last):
      File "/home/serhiy/py/cpython/Lib/doctest.py", line 1374, in __run
        exec(compile(example.source, filename, "single",
      File "<doctest decimal.Decimal.__round__[10]>", line 1, in <module>
        round(Decimal('-Infinity'), 37)
      File "/home/serhiy/py/cpython/Lib/_pydecimal.py", line 1892, in __round__
        return self.quantize(exp)
               ^^^^^^^^^^^^^^^^^^
      File "/home/serhiy/py/cpython/Lib/_pydecimal.py", line 2566, in quantize
        return context._raise_error(InvalidOperation,
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/serhiy/py/cpython/Lib/_pydecimal.py", line 4058, in _raise_error
        raise error(explanation)
    decimal.InvalidOperation: quantize with one INF
----------------------------------------------------------------------
File "/home/serhiy/py/cpython/Lib/decimal.py", line ?, in decimal.Decimal.__round__
Failed example:
    round(Decimal('sNaN123'), 0)
Exception raised:
    Traceback (most recent call last):
      File "/home/serhiy/py/cpython/Lib/doctest.py", line 1374, in __run
        exec(compile(example.source, filename, "single",
      File "<doctest decimal.Decimal.__round__[11]>", line 1, in <module>
        round(Decimal('sNaN123'), 0)
      File "/home/serhiy/py/cpython/Lib/_pydecimal.py", line 1892, in __round__
        return self.quantize(exp)
               ^^^^^^^^^^^^^^^^^^
      File "/home/serhiy/py/cpython/Lib/_pydecimal.py", line 2559, in quantize
        ans = self._check_nans(exp, context)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/serhiy/py/cpython/Lib/_pydecimal.py", line 776, in _check_nans
        return context._raise_error(InvalidOperation, 'sNaN',
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "/home/serhiy/py/cpython/Lib/_pydecimal.py", line 4058, in _raise_error
        raise error(explanation)
    decimal.InvalidOperation: sNaN


----------------------------------------------------------------------

CPython versions tested on:

3.11, 3.12, CPython main branch

Operating systems tested on:

No response

Linked PRs

Activity

  1. added
    type-bugAn unexpected behavior, bug, or error
    testsTests in the Lib/test dir
    3.11only security fixes
    3.12only security fixes
    3.13only security fixes
    on Sep 25, 2023
  2. serhiy-storchaka commented on Sep 25, 2023

    @serhiy-storchaka
    MemberAuthor
  3. skirpichev commented on Oct 13, 2024

    @skirpichev
    Member

    Fixed by 2d7ff6e

  4. mbyrnepr2 commented on Oct 14, 2024

    @mbyrnepr2
    Contributor

    The fix appears to work perfectly when using ./python.exe -m test -v test_decimal -m __round__ but
    I see a couple of failing doctests when running it directly with the following commands:

    ./python.exe -m doctest Lib/decimal.py
    markbyrne@Marks-Air-2 cpython % ./python.exe -m doctest Lib/decimal.py
    **********************************************************************
    File "/Users/markbyrne/programming/cpython/Lib/decimal.py", line 66, in decimal
    Failed example:
        print(dig / 0)
    Expected:
        Traceback (most recent call last):
          ...
          ...
          ...
        decimal.DivisionByZero: x / 0
    Got:
        Traceback (most recent call last):
          File "/Users/markbyrne/programming/cpython/Lib/doctest.py", line 1395, in __run
            exec(compile(example.source, filename, "single",
            ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                         compileflags, True), test.globs)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "<doctest decimal[24]>", line 1, in <module>
            print(dig / 0)
                  ~~~~^~~
        decimal.DivisionByZero: [<class 'decimal.DivisionByZero'>]
    **********************************************************************
    File "/Users/markbyrne/programming/cpython/Lib/decimal.py", line 84, in decimal
    Failed example:
        print(c.divide(Decimal(0), Decimal(0)))
    Expected:
        Traceback (most recent call last):
          ...
          ...
          ...
        decimal.InvalidOperation: 0 / 0
    Got:
        Traceback (most recent call last):
          File "/Users/markbyrne/programming/cpython/Lib/doctest.py", line 1395, in __run
            exec(compile(example.source, filename, "single",
            ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                         compileflags, True), test.globs)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "<doctest decimal[33]>", line 1, in <module>
            print(c.divide(Decimal(0), Decimal(0)))
                  ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^
        decimal.InvalidOperation: [<class 'decimal.DivisionUndefined'>]
    **********************************************************************
    1 item had failures:
       2 of  39 in decimal
    ***Test Failed*** 2 failures.
    ./python.exe -m doctest Lib/_pydecimal.py
    markbyrne@Marks-Air-2 cpython % ./python.exe -m doctest Lib/_pydecimal.py
    **********************************************************************
    File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 1799, in decimal.Decimal.__round__
    Failed example:
        round(Decimal('-Infinity'), 37)
    Exception raised:
        Traceback (most recent call last):
          File "/Users/markbyrne/programming/cpython/Lib/doctest.py", line 1395, in __run
            exec(compile(example.source, filename, "single",
            ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                         compileflags, True), test.globs)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "<doctest decimal.Decimal.__round__[10]>", line 1, in <module>
            round(Decimal('-Infinity'), 37)
            ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 1810, in __round__
            return self.quantize(exp)
                   ~~~~~~~~~~~~~^^^^^
          File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 2495, in quantize
            return context._raise_error(InvalidOperation,
                   ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^
                                    'quantize with one INF')
                                    ^^^^^^^^^^^^^^^^^^^^^^^^
          File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 3987, in _raise_error
            raise error(explanation)
        decimal.InvalidOperation: quantize with one INF
    **********************************************************************
    File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 1801, in decimal.Decimal.__round__
    Failed example:
        round(Decimal('sNaN123'), 0)
    Exception raised:
        Traceback (most recent call last):
          File "/Users/markbyrne/programming/cpython/Lib/doctest.py", line 1395, in __run
            exec(compile(example.source, filename, "single",
            ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                         compileflags, True), test.globs)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "<doctest decimal.Decimal.__round__[11]>", line 1, in <module>
            round(Decimal('sNaN123'), 0)
            ~~~~~^^^^^^^^^^^^^^^^^^^^^^^
          File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 1810, in __round__
            return self.quantize(exp)
                   ~~~~~~~~~~~~~^^^^^
          File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 2488, in quantize
            ans = self._check_nans(exp, context)
          File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 694, in _check_nans
            return context._raise_error(InvalidOperation, 'sNaN',
                   ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
                                    self)
                                    ^^^^^
          File "/Users/markbyrne/programming/cpython/Lib/_pydecimal.py", line 3987, in _raise_error
            raise error(explanation)
        decimal.InvalidOperation: sNaN
    **********************************************************************
    1 item had failures:
       2 of  12 in decimal.Decimal.__round__
    ***Test Failed*** 2 failures.
    Patch which makes the above two commands succeed
    markbyrne@Marks-Air-2 cpython % git diff
    diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
    index 5b60570c6c5..81bb04363f9 100644
    --- a/Lib/_pydecimal.py
    +++ b/Lib/_pydecimal.py
    @@ -1796,9 +1796,10 @@ def __round__(self, n=None):
             Decimal('123.46')
             >>> round(Decimal('123.456'), -2)
             Decimal('1E+2')
    -        >>> round(Decimal('-Infinity'), 37)
    +        >>> with localcontext(ExtendedContext):
    +        ...     round(Decimal('-Infinity'), 37)
    +        ...     round(Decimal('sNaN123'), 0)
             Decimal('NaN')
    -        >>> round(Decimal('sNaN123'), 0)
             Decimal('NaN123')
     
             """
    diff --git a/Lib/decimal.py b/Lib/decimal.py
    index 530bdfb3895..5fde9b1584f 100644
    --- a/Lib/decimal.py
    +++ b/Lib/decimal.py
    @@ -68,7 +68,7 @@
       ...
       ...
       ...
    -decimal.DivisionByZero: x / 0
    +decimal.DivisionByZero: [<class 'decimal.DivisionByZero'>]
     >>> c = Context()
     >>> c.traps[InvalidOperation] = 0
     >>> print(c.flags[InvalidOperation])
    @@ -86,7 +86,7 @@
       ...
       ...
       ...
    -decimal.InvalidOperation: 0 / 0
    +decimal.InvalidOperation: [<class 'decimal.DivisionUndefined'>]

    Do you think it deserves a separate issue?

  5. skirpichev commented on Oct 14, 2024

    @skirpichev
    Member

    Do you think it deserves a separate issue?

    Probably, no.

    ./python.exe -m doctest Lib/decimal.py

    In this case you should override default options to IGNORE_EXCEPTION_DETAIL.

    ./python.exe -m doctest Lib/_pydecimal.py

    Works for me with

    diff --git a/Lib/_pydecimal.py b/Lib/_pydecimal.py
    index 75df3db262..241ec4e118 100644
    --- a/Lib/_pydecimal.py
    +++ b/Lib/_pydecimal.py
    @@ -1749,6 +1749,7 @@ def __round__(self, n=None):
             and lies exactly halfway between two integers then it is
             rounded to the integer with even last digit.
     
    +        >>> setcontext(ExtendedContext)
             >>> round(Decimal('123.456'))
             123
             >>> round(Decimal('-456.789'))
  6. added
    3.14bugs and security fixes
    and removed
    3.11only security fixes
    3.12only security fixes
    on Jan 28, 2026
  7. added a commit that references this issue on Aug 6, 2026
  8. added 2 commits that reference this issue on Aug 6, 2026
  9. added a commit that references this issue on Aug 14, 2026
  10. added a commit that references this issue on Oct 10, 2026
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

    3.13only security fixes3.14bugs and security fixestestsTests in the Lib/test dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions