[pypy-issue] Issue #2583: decimal.py: overflow in fraction comparisons (pypy/pypy)

Stefan Krah issues-reply at bitbucket.org
Mon Jun 19 19:34:45 EDT 2017

New issue 2583: decimal.py: overflow in fraction comparisons

Stefan Krah:

_convert_for_comparison() should use a maxcontext for a couple of internal
operations in order to prevent overflow. Example:

>>>> from decimal import *
>>>> from fractions import Fraction
>>>> c = getcontext()
>>>> c.Emax = 1
>>>> c.Emin = -1
>>>> Fraction(1000, 5) == Decimal(200)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/stefan/usr/pypy3-v5.8.0-linux64/lib_pypy/_decimal.py", line 607, in __eq__
    r = self._cmp(other, 'eq')
  File "/home/stefan/usr/pypy3-v5.8.0-linux64/lib_pypy/_decimal.py", line 586, in _cmp
    a, b = self._convert_for_comparison(other, op)
  File "/home/stefan/usr/pypy3-v5.8.0-linux64/lib_pypy/_decimal.py", line 494, in _convert_for_comparison
    ctx, status_ptr)
  File "/home/stefan/usr/pypy3-v5.8.0-linux64/lib_pypy/_decimal.py", line 1628, in __exit__
  File "/home/stefan/usr/pypy3-v5.8.0-linux64/lib_pypy/_decimal.py", line 1260, in _add_status
    raise exception

Relatedly, there is a comment  "XXX probably a bug in _decimal.c" in that function.
The multiplication is on two integers with a guaranteed exponent of 0.

We have two cases:

  a) The result does not have an exponent of 0.  In this case "status" is set and the
       ValueError is triggered.

  b) The result has an exponent of zero and the multiplication was exact.  The previous
       exponent is restored, so that the result can have a combination of coefficient and
       exponent that *could* overflow, if finalized. But this result is only used in mpd_qcmp(),
       which is safe.

So while the code is a bit tricky, there is no bug here.

More information about the pypy-issue mailing list