This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: decimal C module's exceptions don't match the Python version
Type: enhancement Stage: needs patch
Components: Library (Lib) Versions: Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: skrah Nosy List: ced, const, mark.dickinson, pekka.klarck, petr.viktorin, rhettinger, skrah
Priority: normal Keywords:

Created on 2016-01-26 17:46 by petr.viktorin, last changed 2022-04-11 14:58 by admin.

Messages (7)
msg258965 - (view) Author: Petr Viktorin (petr.viktorin) * (Python committer) Date: 2016-01-26 17:46
Exceptions from the decimal module are quite unfriendly:

    >>> Decimal(42) / Decimal(0)
    ...
    decimal.DivisionByZero: [<class 'decimal.DivisionByZero'>]

    >>> huge = Decimal('9' * 99)
    >>> huge.quantize(Decimal('0.1'))
    ...
    decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]


compared to the pure Python implementation:

    decimal.DivisionByZero: x / 0

    decimal.InvalidOperation: quantize result has too many digits for current context


If I'm reading http://bugs.python.org/issue21227 right, the exception argument is a of signals, and indicates the complete set of signals raised by the operation. However, this is (AFAICS) not documented, and not portable (since it's not present in the Python version).

I believe this behavior should be
- either dropped in favor of friendlier error messages (or possibly moved to a more internal attribute of the exception, and documented as an optional CPython feature),
- or documented, and implemented in _pydecimal as well.

Which of those actions would be right seems to be a question of whether the exception argument is part of the API.
msg258970 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2016-01-26 19:46
If it doesn't take too much effort, I would like the see the exception messages made more user friendly and kept more in-sync with the pure Python version.
msg258972 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2016-01-26 20:54
Yes, ideally the exceptions should be in sync. I don't find the list
of signals entirely uninteresting, but implementing it in _pydecimal
would require #8613 to be solved, which is unlikely to happen.


In _decimal the exceptions come directly from libmpdec, so in order
to have the same error messages as _pydecimal I'd need to implement
detailed error codes and store them somewhere in the context.
msg324666 - (view) Author: Pekka Klärck (pekka.klarck) Date: 2018-09-06 07:29
Just noticed this myself when testing with Python 3.5-3.7:

    >>> from decimal import Decimal
    >>> d = Decimal('foo')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    decimal.InvalidOperation: [<class 'decimal.ConversionSyntax'>]


With Python 2.7 I get this error instead:

    decimal.InvalidOperation: Invalid literal for Decimal: 'foo'


I'm writing type conversion code and was planning to include the error message by Python along with some higher level explanation when reporting errors. `[<class 'decimal.ConversionSyntax'>]` would be such a strange message that I need to make a special case with decimal.
msg324673 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2018-09-06 08:26
The thing is that Python explicitly supports any object as the "message".

I was quite pleased when I discovered that because it provides a way
to include both signals and the condition list in the "message", which can be used in programs for dispatching on the condition, not only
on the signal.

Signals directly map to the exceptions, but there can be more than one
condition that caused the signal.
msg324696 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2018-09-06 14:43
pypy3 actually took over the terse exceptions, but without the conditions.  They'd also need error codes from libmpdec now.

>>>> huge = Decimal('9' * 99)
>>>> huge.quantize(Decimal('0.1'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/stefan/tmp/pypy3-v6.0.0-linux64/lib_pypy/_decimal.py", line 842, in quantize
    workctx._ctx, status_ptr)
  File "/home/stefan/tmp/pypy3-v6.0.0-linux64/lib_pypy/_decimal.py", line 1631, in __exit__
    self.context._add_status(status)
  File "/home/stefan/tmp/pypy3-v6.0.0-linux64/lib_pypy/_decimal.py", line 1263, in _add_status
    raise exception
decimal.InvalidOperation
msg414392 - (view) Author: Constantine Evans (const) Date: 2022-03-02 23:45
Some other non-matching exceptions are unfriendly, but do not come from libmpdec and could be made to match without, I think, causing problems.  For example:

    >>> format(_decimal.Decimal(1), "invalid")
    ...
    ValueError: invalid format string
    >>> format(_pydecimal.Decimal(1), "invalid")
    ...
    ValueError: Invalid format specifier: invalid

Would it make sense to make a patch to make these match?
History
Date User Action Args
2022-04-11 14:58:26adminsetgithub: 70396
2022-03-02 23:45:33constsetnosy: + const
messages: + msg414392
2022-01-04 14:59:55cedsetnosy: + ced
2018-09-06 14:43:47skrahsetmessages: + msg324696
2018-09-06 08:26:47skrahsetmessages: + msg324673
2018-09-06 07:29:10pekka.klarcksetnosy: + pekka.klarck
messages: + msg324666
2017-12-07 09:45:41skrahlinkissue32239 superseder
2016-09-02 17:49:17mark.dickinsonsetnosy: + mark.dickinson
2016-09-02 16:53:05skrahlinkissue27941 superseder
2016-01-26 20:54:46skrahsetstage: needs patch
type: enhancement
versions: + Python 3.6
2016-01-26 20:54:11skrahsetmessages: + msg258972
2016-01-26 19:46:03rhettingersetassignee: skrah

messages: + msg258970
nosy: + rhettinger
2016-01-26 17:46:59petr.viktorincreate