Skip to content

Commit 9384665

Browse files
gh-106078: Move static variables initialized once to decimal module global state (#106475)
1 parent 43389e4 commit 9384665

File tree

2 files changed

+28
-25
lines changed

2 files changed

+28
-25
lines changed

Modules/_decimal/_decimal.c

+28-22
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@
3939

4040
#include "docstrings.h"
4141

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+
4248
struct PyDecContextObject;
4349

4450
typedef struct {
@@ -68,6 +74,13 @@ typedef struct {
6874
/* Basic and extended context templates */
6975
PyObject *basic_context_template;
7076
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;
7184
} decimal_state;
7285

7386
static decimal_state global_state;
@@ -216,13 +229,6 @@ static const char *dec_signal_string[MPD_NUM_FLAGS] = {
216229
"Underflow",
217230
};
218231

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-
226232
static const char *invalid_rounding_err =
227233
"valid values for rounding are:\n\
228234
[ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\
@@ -520,15 +526,16 @@ static int
520526
getround(PyObject *v)
521527
{
522528
int i;
529+
decimal_state *state = GLOBAL_STATE();
523530

524531
if (PyUnicode_Check(v)) {
525532
for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
526-
if (v == round_map[i]) {
533+
if (v == state->round_map[i]) {
527534
return i;
528535
}
529536
}
530537
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) {
532539
return i;
533540
}
534541
}
@@ -561,11 +568,11 @@ signaldict_len(PyObject *self UNUSED)
561568
return SIGNAL_MAP_LEN;
562569
}
563570

564-
static PyObject *SignalTuple;
565571
static PyObject *
566572
signaldict_iter(PyObject *self UNUSED)
567573
{
568-
return PyTuple_Type.tp_iter(SignalTuple);
574+
decimal_state *state = GLOBAL_STATE();
575+
return PyTuple_Type.tp_iter(state->SignalTuple);
569576
}
570577

571578
static PyObject *
@@ -754,8 +761,9 @@ static PyObject *
754761
context_getround(PyObject *self, void *closure UNUSED)
755762
{
756763
int i = mpd_getround(CTX(self));
764+
decimal_state *state = GLOBAL_STATE();
757765

758-
return Py_NewRef(round_map[i]);
766+
return Py_NewRef(state->round_map[i]);
759767
}
760768

761769
static PyObject *
@@ -2987,8 +2995,6 @@ convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context)
29872995
/* Implicit conversions to Decimal for comparison */
29882996
/******************************************************************************/
29892997

2990-
/* Convert rationals for comparison */
2991-
static PyObject *Rational = NULL;
29922998
static PyObject *
29932999
multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context)
29943000
{
@@ -3117,7 +3123,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w,
31173123
}
31183124
}
31193125
else {
3120-
int is_rational = PyObject_IsInstance(w, Rational);
3126+
int is_rational = PyObject_IsInstance(w, state->Rational);
31213127
if (is_rational < 0) {
31223128
*wcmp = NULL;
31233129
}
@@ -5865,7 +5871,7 @@ PyInit__decimal(void)
58655871
(PyObject *)state->PyDec_Type));
58665872
Py_CLEAR(obj);
58675873
/* 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"));
58695875
/* Done with numbers, Number */
58705876
Py_CLEAR(numbers);
58715877
Py_CLEAR(Number);
@@ -5912,7 +5918,7 @@ PyInit__decimal(void)
59125918
CHECK_INT(PyModule_AddType(m, (PyTypeObject *)state->DecimalException));
59135919

59145920
/* Create signal tuple */
5915-
ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN));
5921+
ASSIGN_PTR(state->SignalTuple, PyTuple_New(SIGNAL_MAP_LEN));
59165922

59175923
/* Add exceptions that correspond to IEEE signals */
59185924
for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) {
@@ -5953,7 +5959,7 @@ PyInit__decimal(void)
59535959
CHECK_INT(PyModule_AddObject(m, cm->name, Py_NewRef(cm->ex)));
59545960

59555961
/* 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));
59575963
}
59585964

59595965
/*
@@ -6029,8 +6035,8 @@ PyInit__decimal(void)
60296035

60306036
/* Init string constants */
60316037
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])));
60346040
}
60356041

60366042
/* Add specification version number */
@@ -6045,11 +6051,11 @@ PyInit__decimal(void)
60456051
Py_CLEAR(obj); /* GCOV_NOT_REACHED */
60466052
Py_CLEAR(numbers); /* GCOV_NOT_REACHED */
60476053
Py_CLEAR(Number); /* GCOV_NOT_REACHED */
6048-
Py_CLEAR(Rational); /* GCOV_NOT_REACHED */
6054+
Py_CLEAR(state->Rational); /* GCOV_NOT_REACHED */
60496055
Py_CLEAR(collections); /* GCOV_NOT_REACHED */
60506056
Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */
60516057
Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */
6052-
Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */
6058+
Py_CLEAR(state->SignalTuple); /* GCOV_NOT_REACHED */
60536059
Py_CLEAR(state->DecimalTuple); /* GCOV_NOT_REACHED */
60546060
Py_CLEAR(state->default_context_template); /* GCOV_NOT_REACHED */
60556061
#ifndef WITH_DECIMAL_CONTEXTVAR

Tools/c-analyzer/cpython/globals-to-fix.tsv

-3
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,6 @@ Modules/_datetimemodule.c - us_per_day -
422422
Modules/_datetimemodule.c - us_per_week -
423423
Modules/_datetimemodule.c - seconds_per_day -
424424
Modules/_decimal/_decimal.c - global_state -
425-
Modules/_decimal/_decimal.c - round_map -
426-
Modules/_decimal/_decimal.c - Rational -
427-
Modules/_decimal/_decimal.c - SignalTuple -
428425

429426
## state
430427
Modules/_asynciomodule.c - fi_freelist -

0 commit comments

Comments
 (0)