39
39
40
40
#include "docstrings.h"
41
41
42
+ #ifdef EXTRA_FUNCTIONALITY
43
+ #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD
44
+ #else
45
+ #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1)
46
+ #endif
47
+
42
48
struct PyDecContextObject ;
43
49
44
50
typedef struct {
@@ -68,6 +74,13 @@ typedef struct {
68
74
/* Basic and extended context templates */
69
75
PyObject * basic_context_template ;
70
76
PyObject * extended_context_template ;
77
+
78
+ PyObject * round_map [_PY_DEC_ROUND_GUARD ];
79
+
80
+ /* Convert rationals for comparison */
81
+ PyObject * Rational ;
82
+
83
+ PyObject * SignalTuple ;
71
84
} decimal_state ;
72
85
73
86
static decimal_state global_state ;
@@ -216,13 +229,6 @@ static const char *dec_signal_string[MPD_NUM_FLAGS] = {
216
229
"Underflow" ,
217
230
};
218
231
219
- #ifdef EXTRA_FUNCTIONALITY
220
- #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD
221
- #else
222
- #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1)
223
- #endif
224
- static PyObject * round_map [_PY_DEC_ROUND_GUARD ];
225
-
226
232
static const char * invalid_rounding_err =
227
233
"valid values for rounding are:\n\
228
234
[ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\
@@ -520,15 +526,16 @@ static int
520
526
getround (PyObject * v )
521
527
{
522
528
int i ;
529
+ decimal_state * state = GLOBAL_STATE ();
523
530
524
531
if (PyUnicode_Check (v )) {
525
532
for (i = 0 ; i < _PY_DEC_ROUND_GUARD ; i ++ ) {
526
- if (v == round_map [i ]) {
533
+ if (v == state -> round_map [i ]) {
527
534
return i ;
528
535
}
529
536
}
530
537
for (i = 0 ; i < _PY_DEC_ROUND_GUARD ; i ++ ) {
531
- if (PyUnicode_Compare (v , round_map [i ]) == 0 ) {
538
+ if (PyUnicode_Compare (v , state -> round_map [i ]) == 0 ) {
532
539
return i ;
533
540
}
534
541
}
@@ -561,11 +568,11 @@ signaldict_len(PyObject *self UNUSED)
561
568
return SIGNAL_MAP_LEN ;
562
569
}
563
570
564
- static PyObject * SignalTuple ;
565
571
static PyObject *
566
572
signaldict_iter (PyObject * self UNUSED )
567
573
{
568
- return PyTuple_Type .tp_iter (SignalTuple );
574
+ decimal_state * state = GLOBAL_STATE ();
575
+ return PyTuple_Type .tp_iter (state -> SignalTuple );
569
576
}
570
577
571
578
static PyObject *
@@ -754,8 +761,9 @@ static PyObject *
754
761
context_getround (PyObject * self , void * closure UNUSED )
755
762
{
756
763
int i = mpd_getround (CTX (self ));
764
+ decimal_state * state = GLOBAL_STATE ();
757
765
758
- return Py_NewRef (round_map [i ]);
766
+ return Py_NewRef (state -> round_map [i ]);
759
767
}
760
768
761
769
static PyObject *
@@ -2987,8 +2995,6 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context)
2987
2995
/* Implicit conversions to Decimal for comparison */
2988
2996
/******************************************************************************/
2989
2997
2990
- /* Convert rationals for comparison */
2991
- static PyObject * Rational = NULL ;
2992
2998
static PyObject *
2993
2999
multiply_by_denominator (PyObject * v , PyObject * r , PyObject * context )
2994
3000
{
@@ -3117,7 +3123,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w,
3117
3123
}
3118
3124
}
3119
3125
else {
3120
- int is_rational = PyObject_IsInstance (w , Rational );
3126
+ int is_rational = PyObject_IsInstance (w , state -> Rational );
3121
3127
if (is_rational < 0 ) {
3122
3128
* wcmp = NULL ;
3123
3129
}
@@ -5865,7 +5871,7 @@ PyInit__decimal(void)
5865
5871
(PyObject * )state -> PyDec_Type ));
5866
5872
Py_CLEAR (obj );
5867
5873
/* Rational is a global variable used for fraction comparisons. */
5868
- ASSIGN_PTR (Rational , PyObject_GetAttrString (numbers , "Rational" ));
5874
+ ASSIGN_PTR (state -> Rational , PyObject_GetAttrString (numbers , "Rational" ));
5869
5875
/* Done with numbers, Number */
5870
5876
Py_CLEAR (numbers );
5871
5877
Py_CLEAR (Number );
@@ -5912,7 +5918,7 @@ PyInit__decimal(void)
5912
5918
CHECK_INT (PyModule_AddType (m , (PyTypeObject * )state -> DecimalException ));
5913
5919
5914
5920
/* Create signal tuple */
5915
- ASSIGN_PTR (SignalTuple , PyTuple_New (SIGNAL_MAP_LEN ));
5921
+ ASSIGN_PTR (state -> SignalTuple , PyTuple_New (SIGNAL_MAP_LEN ));
5916
5922
5917
5923
/* Add exceptions that correspond to IEEE signals */
5918
5924
for (i = SIGNAL_MAP_LEN - 1 ; i >= 0 ; i -- ) {
@@ -5953,7 +5959,7 @@ PyInit__decimal(void)
5953
5959
CHECK_INT (PyModule_AddObject (m , cm -> name , Py_NewRef (cm -> ex )));
5954
5960
5955
5961
/* add to signal tuple */
5956
- PyTuple_SET_ITEM (SignalTuple , i , Py_NewRef (cm -> ex ));
5962
+ PyTuple_SET_ITEM (state -> SignalTuple , i , Py_NewRef (cm -> ex ));
5957
5963
}
5958
5964
5959
5965
/*
@@ -6029,8 +6035,8 @@ PyInit__decimal(void)
6029
6035
6030
6036
/* Init string constants */
6031
6037
for (i = 0 ; i < _PY_DEC_ROUND_GUARD ; i ++ ) {
6032
- ASSIGN_PTR (round_map [i ], PyUnicode_InternFromString (mpd_round_string [i ]));
6033
- CHECK_INT (PyModule_AddObject (m , mpd_round_string [i ], Py_NewRef (round_map [i ])));
6038
+ ASSIGN_PTR (state -> round_map [i ], PyUnicode_InternFromString (mpd_round_string [i ]));
6039
+ CHECK_INT (PyModule_AddObject (m , mpd_round_string [i ], Py_NewRef (state -> round_map [i ])));
6034
6040
}
6035
6041
6036
6042
/* Add specification version number */
@@ -6045,11 +6051,11 @@ PyInit__decimal(void)
6045
6051
Py_CLEAR (obj ); /* GCOV_NOT_REACHED */
6046
6052
Py_CLEAR (numbers ); /* GCOV_NOT_REACHED */
6047
6053
Py_CLEAR (Number ); /* GCOV_NOT_REACHED */
6048
- Py_CLEAR (Rational ); /* GCOV_NOT_REACHED */
6054
+ Py_CLEAR (state -> Rational ); /* GCOV_NOT_REACHED */
6049
6055
Py_CLEAR (collections ); /* GCOV_NOT_REACHED */
6050
6056
Py_CLEAR (collections_abc ); /* GCOV_NOT_REACHED */
6051
6057
Py_CLEAR (MutableMapping ); /* GCOV_NOT_REACHED */
6052
- Py_CLEAR (SignalTuple ); /* GCOV_NOT_REACHED */
6058
+ Py_CLEAR (state -> SignalTuple ); /* GCOV_NOT_REACHED */
6053
6059
Py_CLEAR (state -> DecimalTuple ); /* GCOV_NOT_REACHED */
6054
6060
Py_CLEAR (state -> default_context_template ); /* GCOV_NOT_REACHED */
6055
6061
#ifndef WITH_DECIMAL_CONTEXTVAR
0 commit comments