@@ -143,7 +143,10 @@ typedef struct {
143143/* Top level Exception; inherits from ArithmeticError */
144144static PyObject * DecimalException = NULL ;
145145
146- /* Exceptions that correspond to IEEE signals; inherit from DecimalException */
146+ /* Exceptions that correspond to IEEE signals */
147+ #define SUBNORMAL 5
148+ #define INEXACT 6
149+ #define ROUNDED 7
147150#define SIGNAL_MAP_LEN 9
148151static DecCondMap signal_map [] = {
149152 {"InvalidOperation" , "decimal.InvalidOperation" , MPD_IEEE_Invalid_operation , NULL },
@@ -5403,9 +5406,38 @@ PyInit__decimal(void)
54035406 ASSIGN_PTR (SignalTuple , PyTuple_New (SIGNAL_MAP_LEN ));
54045407
54055408 /* Add exceptions that correspond to IEEE signals */
5406- for (cm = signal_map , i = 0 ; cm -> name != NULL ; cm ++ , i ++ ) {
5407- ASSIGN_PTR (cm -> ex , PyErr_NewException ((char * )cm -> fqname ,
5408- DecimalException , NULL ));
5409+ for (i = SIGNAL_MAP_LEN - 1 ; i >= 0 ; i -- ) {
5410+ PyObject * base ;
5411+
5412+ cm = signal_map + i ;
5413+
5414+ switch (cm -> flag ) {
5415+ case MPD_Float_operation :
5416+ base = PyTuple_Pack (2 , DecimalException , PyExc_TypeError );
5417+ break ;
5418+ case MPD_Division_by_zero :
5419+ base = PyTuple_Pack (2 , DecimalException , PyExc_ZeroDivisionError );
5420+ break ;
5421+ case MPD_Overflow :
5422+ base = PyTuple_Pack (2 , signal_map [INEXACT ].ex ,
5423+ signal_map [ROUNDED ].ex );
5424+ break ;
5425+ case MPD_Underflow :
5426+ base = PyTuple_Pack (3 , signal_map [INEXACT ].ex ,
5427+ signal_map [ROUNDED ].ex ,
5428+ signal_map [SUBNORMAL ].ex );
5429+ break ;
5430+ default :
5431+ base = PyTuple_Pack (1 , DecimalException );
5432+ break ;
5433+ }
5434+
5435+ if (base == NULL ) {
5436+ goto error ;
5437+ }
5438+
5439+ ASSIGN_PTR (cm -> ex , PyErr_NewException ((char * )cm -> fqname , base , NULL ));
5440+ Py_DECREF (base );
54095441
54105442 /* add to module */
54115443 Py_INCREF (cm -> ex );
@@ -5425,8 +5457,20 @@ PyInit__decimal(void)
54255457
54265458 /* Add remaining exceptions, inherit from InvalidOperation */
54275459 for (cm = cond_map + 1 ; cm -> name != NULL ; cm ++ ) {
5428- ASSIGN_PTR (cm -> ex , PyErr_NewException ((char * )cm -> fqname ,
5429- signal_map [0 ].ex , NULL ));
5460+ PyObject * base ;
5461+ if (cm -> flag == MPD_Division_undefined ) {
5462+ base = PyTuple_Pack (2 , signal_map [0 ].ex , PyExc_ZeroDivisionError );
5463+ }
5464+ else {
5465+ base = PyTuple_Pack (1 , signal_map [0 ].ex );
5466+ }
5467+ if (base == NULL ) {
5468+ goto error ;
5469+ }
5470+
5471+ ASSIGN_PTR (cm -> ex , PyErr_NewException ((char * )cm -> fqname , base , NULL ));
5472+ Py_DECREF (base );
5473+
54305474 Py_INCREF (cm -> ex );
54315475 CHECK_INT (PyModule_AddObject (m , cm -> name , cm -> ex ));
54325476 }
@@ -5472,6 +5516,7 @@ PyInit__decimal(void)
54725516 for (ssize_cm = ssize_constants ; ssize_cm -> name != NULL ; ssize_cm ++ ) {
54735517 ASSIGN_PTR (obj , PyLong_FromSsize_t (ssize_cm -> val ));
54745518 CHECK_INT (PyModule_AddObject (m , ssize_cm -> name , obj ));
5519+ obj = NULL ;
54755520 }
54765521
54775522 /* Init int constants */
@@ -5488,23 +5533,23 @@ PyInit__decimal(void)
54885533
54895534
54905535error :
5491- Py_XDECREF (obj ); /* GCOV_NOT_REACHED */
5492- Py_XDECREF (numbers ); /* GCOV_NOT_REACHED */
5493- Py_XDECREF (Number ); /* GCOV_NOT_REACHED */
5494- Py_XDECREF (Rational ); /* GCOV_NOT_REACHED */
5495- Py_XDECREF (collections ); /* GCOV_NOT_REACHED */
5496- Py_XDECREF (MutableMapping ); /* GCOV_NOT_REACHED */
5497- Py_XDECREF (SignalTuple ); /* GCOV_NOT_REACHED */
5498- Py_XDECREF (DecimalTuple ); /* GCOV_NOT_REACHED */
5536+ Py_CLEAR (obj ); /* GCOV_NOT_REACHED */
5537+ Py_CLEAR (numbers ); /* GCOV_NOT_REACHED */
5538+ Py_CLEAR (Number ); /* GCOV_NOT_REACHED */
5539+ Py_CLEAR (Rational ); /* GCOV_NOT_REACHED */
5540+ Py_CLEAR (collections ); /* GCOV_NOT_REACHED */
5541+ Py_CLEAR (MutableMapping ); /* GCOV_NOT_REACHED */
5542+ Py_CLEAR (SignalTuple ); /* GCOV_NOT_REACHED */
5543+ Py_CLEAR (DecimalTuple ); /* GCOV_NOT_REACHED */
54995544#ifdef WITHOUT_THREADS
5500- Py_XDECREF (module_context ); /* GCOV_NOT_REACHED */
5545+ Py_CLEAR (module_context ); /* GCOV_NOT_REACHED */
55015546#else
5502- Py_XDECREF (default_context_template ); /* GCOV_NOT_REACHED */
5503- Py_XDECREF (tls_context_key ); /* GCOV_NOT_REACHED */
5547+ Py_CLEAR (default_context_template ); /* GCOV_NOT_REACHED */
5548+ Py_CLEAR (tls_context_key ); /* GCOV_NOT_REACHED */
55045549#endif
5505- Py_XDECREF (basic_context_template ); /* GCOV_NOT_REACHED */
5506- Py_XDECREF (extended_context_template ); /* GCOV_NOT_REACHED */
5507- Py_XDECREF (m ); /* GCOV_NOT_REACHED */
5550+ Py_CLEAR (basic_context_template ); /* GCOV_NOT_REACHED */
5551+ Py_CLEAR (extended_context_template ); /* GCOV_NOT_REACHED */
5552+ Py_CLEAR (m ); /* GCOV_NOT_REACHED */
55085553
55095554 return NULL ; /* GCOV_NOT_REACHED */
55105555}
0 commit comments