diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 7e1809cfb98..89924b205f9 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -39,6 +39,12 @@ #include "docstrings.h" +#ifdef EXTRA_FUNCTIONALITY + #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD +#else + #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1) +#endif + struct PyDecContextObject; typedef struct { @@ -68,6 +74,13 @@ typedef struct { /* Basic and extended context templates */ PyObject *basic_context_template; PyObject *extended_context_template; + + PyObject *round_map[_PY_DEC_ROUND_GUARD]; + + /* Convert rationals for comparison */ + PyObject *Rational; + + PyObject *SignalTuple; } decimal_state; static decimal_state global_state; @@ -216,13 +229,6 @@ static const char *dec_signal_string[MPD_NUM_FLAGS] = { "Underflow", }; -#ifdef EXTRA_FUNCTIONALITY - #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD -#else - #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1) -#endif -static PyObject *round_map[_PY_DEC_ROUND_GUARD]; - static const char *invalid_rounding_err = "valid values for rounding are:\n\ [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\ @@ -520,15 +526,16 @@ static int getround(PyObject *v) { int i; + decimal_state *state = GLOBAL_STATE(); if (PyUnicode_Check(v)) { for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { - if (v == round_map[i]) { + if (v == state->round_map[i]) { return i; } } for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { - if (PyUnicode_Compare(v, round_map[i]) == 0) { + if (PyUnicode_Compare(v, state->round_map[i]) == 0) { return i; } } @@ -561,11 +568,11 @@ signaldict_len(PyObject *self UNUSED) return SIGNAL_MAP_LEN; } -static PyObject *SignalTuple; static PyObject * signaldict_iter(PyObject *self UNUSED) { - return PyTuple_Type.tp_iter(SignalTuple); + decimal_state *state = GLOBAL_STATE(); + return PyTuple_Type.tp_iter(state->SignalTuple); } static PyObject * @@ -754,8 +761,9 @@ static PyObject * context_getround(PyObject *self, void *closure UNUSED) { int i = mpd_getround(CTX(self)); + decimal_state *state = GLOBAL_STATE(); - return Py_NewRef(round_map[i]); + return Py_NewRef(state->round_map[i]); } static PyObject * @@ -2987,8 +2995,6 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) /* Implicit conversions to Decimal for comparison */ /******************************************************************************/ -/* Convert rationals for comparison */ -static PyObject *Rational = NULL; static PyObject * multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context) { @@ -3117,7 +3123,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, } } else { - int is_rational = PyObject_IsInstance(w, Rational); + int is_rational = PyObject_IsInstance(w, state->Rational); if (is_rational < 0) { *wcmp = NULL; } @@ -5865,7 +5871,7 @@ PyInit__decimal(void) (PyObject *)state->PyDec_Type)); Py_CLEAR(obj); /* Rational is a global variable used for fraction comparisons. */ - ASSIGN_PTR(Rational, PyObject_GetAttrString(numbers, "Rational")); + ASSIGN_PTR(state->Rational, PyObject_GetAttrString(numbers, "Rational")); /* Done with numbers, Number */ Py_CLEAR(numbers); Py_CLEAR(Number); @@ -5912,7 +5918,7 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddType(m, (PyTypeObject *)state->DecimalException)); /* Create signal tuple */ - ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN)); + ASSIGN_PTR(state->SignalTuple, PyTuple_New(SIGNAL_MAP_LEN)); /* Add exceptions that correspond to IEEE signals */ for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) { @@ -5953,7 +5959,7 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddObject(m, cm->name, Py_NewRef(cm->ex))); /* add to signal tuple */ - PyTuple_SET_ITEM(SignalTuple, i, Py_NewRef(cm->ex)); + PyTuple_SET_ITEM(state->SignalTuple, i, Py_NewRef(cm->ex)); } /* @@ -6029,8 +6035,8 @@ PyInit__decimal(void) /* Init string constants */ for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { - ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i])); - CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], Py_NewRef(round_map[i]))); + ASSIGN_PTR(state->round_map[i], PyUnicode_InternFromString(mpd_round_string[i])); + CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], Py_NewRef(state->round_map[i]))); } /* Add specification version number */ @@ -6045,11 +6051,11 @@ error: Py_CLEAR(obj); /* GCOV_NOT_REACHED */ Py_CLEAR(numbers); /* GCOV_NOT_REACHED */ Py_CLEAR(Number); /* GCOV_NOT_REACHED */ - Py_CLEAR(Rational); /* GCOV_NOT_REACHED */ + Py_CLEAR(state->Rational); /* GCOV_NOT_REACHED */ Py_CLEAR(collections); /* GCOV_NOT_REACHED */ Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */ Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */ - Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */ + Py_CLEAR(state->SignalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(state->DecimalTuple); /* GCOV_NOT_REACHED */ Py_CLEAR(state->default_context_template); /* GCOV_NOT_REACHED */ #ifndef WITH_DECIMAL_CONTEXTVAR diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 12f91726b2d..38b47d06e4a 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -422,9 +422,6 @@ Modules/_datetimemodule.c - us_per_day - Modules/_datetimemodule.c - us_per_week - Modules/_datetimemodule.c - seconds_per_day - Modules/_decimal/_decimal.c - global_state - -Modules/_decimal/_decimal.c - round_map - -Modules/_decimal/_decimal.c - Rational - -Modules/_decimal/_decimal.c - SignalTuple - ## state Modules/_asynciomodule.c - fi_freelist -