From f3da37af0e126f30b4cd9323fb721dad6d180d8e Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Fri, 14 Jul 2023 17:18:42 +0800 Subject: [PATCH 1/4] Convert global state to module state --- Modules/_decimal/_decimal.c | 389 ++++++++++++++++++++++-------------- 1 file changed, 237 insertions(+), 152 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index e3dc304066b45b..f3f01f65a5cbbc 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -91,9 +91,36 @@ typedef struct { PyCFunction _py_float_as_integer_ratio; } decimal_state; -static decimal_state global_state; +static inline decimal_state * +get_module_state(PyObject *mod) +{ + decimal_state *state = _PyModule_GetState(mod); + assert(state != NULL); + return state; +} + +static struct PyModuleDef _decimal_module; + +static inline decimal_state * +get_module_state_by_def(PyTypeObject *tp) +{ + PyObject *mod = PyType_GetModuleByDef(tp, &_decimal_module); + assert(mod != NULL); + return get_module_state(mod); +} + +static inline decimal_state * +find_state_left_or_right(PyObject *left, PyObject *right) +{ + PyObject *mod = PyType_GetModuleByDef(Py_TYPE(left), &_decimal_module); + if (mod == NULL) { + PyErr_Clear(); + mod = PyType_GetModuleByDef(Py_TYPE(right), &_decimal_module); + } + assert(mod != NULL); + return get_module_state(mod); +} -#define GLOBAL_STATE() (&global_state) #if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02050000 #error "libmpdec version >= 2.5.0 required" @@ -531,11 +558,9 @@ dec_addstatus(PyObject *context, uint32_t status) } static int -getround(PyObject *v) +getround(decimal_state *state, PyObject *v) { int i; - decimal_state *state = GLOBAL_STATE(); - if (PyUnicode_Check(v)) { for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) { if (v == state->round_map[i]) { @@ -577,9 +602,9 @@ signaldict_len(PyObject *self UNUSED) } static PyObject * -signaldict_iter(PyObject *self UNUSED) +signaldict_iter(PyObject *self) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); return PyTuple_Type.tp_iter(state->SignalTuple); } @@ -670,7 +695,7 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) { PyObject *res = Py_NotImplemented; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = find_state_left_or_right(v, w); assert(PyDecSignalDict_Check(state, v)); if (op == Py_EQ || op == Py_NE) { @@ -769,7 +794,7 @@ static PyObject * context_getround(PyObject *self, void *closure UNUSED) { int i = mpd_getround(CTX(self)); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); return Py_NewRef(state->round_map[i]); } @@ -928,7 +953,8 @@ context_setround(PyObject *self, PyObject *value, void *closure UNUSED) mpd_context_t *ctx; int x; - x = getround(value); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + x = getround(state, value); if (x == -1) { return -1; } @@ -1006,7 +1032,7 @@ context_settraps_dict(PyObject *self, PyObject *value) mpd_context_t *ctx; uint32_t flags; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if (PyDecSignalDict_Check(state, value)) { flags = SdFlags(value); } @@ -1071,7 +1097,7 @@ context_setstatus_dict(PyObject *self, PyObject *value) mpd_context_t *ctx; uint32_t flags; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if (PyDecSignalDict_Check(state, value)) { flags = SdFlags(value); } @@ -1262,7 +1288,7 @@ context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED) PyDecContextObject *self = NULL; mpd_context_t *ctx; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (type == state->PyDecContext_Type) { self = PyObject_GC_New(PyDecContextObject, state->PyDecContext_Type); } @@ -1327,7 +1353,7 @@ context_dealloc(PyDecContextObject *self) PyTypeObject *tp = Py_TYPE(self); PyObject_GC_UnTrack(self); #ifndef WITH_DECIMAL_CONTEXTVAR - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if (self == state->cached_context) { state->cached_context = NULL; } @@ -1379,7 +1405,7 @@ context_repr(PyDecContextObject *self) int n, mem; #ifdef Py_DEBUG - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); assert(PyDecContext_Check(state, self)); #endif ctx = CTX(self); @@ -1447,7 +1473,7 @@ ieee_context(PyObject *dummy UNUSED, PyObject *v) goto error; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(v)); context = PyObject_CallObject((PyObject *)state->PyDecContext_Type, NULL); if (context == NULL) { return NULL; @@ -1470,7 +1496,7 @@ context_copy(PyObject *self, PyObject *args UNUSED) { PyObject *copy; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); copy = PyObject_CallObject((PyObject *)state->PyDecContext_Type, NULL); if (copy == NULL) { return NULL; @@ -1542,7 +1568,7 @@ static PyGetSetDef context_getsets [] = #define CONTEXT_CHECK_VA(state, obj) \ if (obj == Py_None) { \ - CURRENT_CONTEXT(obj); \ + CURRENT_CONTEXT(state, obj); \ } \ else if (!PyDecContext_Check(state, obj)) { \ PyErr_SetString(PyExc_TypeError, \ @@ -1565,10 +1591,9 @@ static PyGetSetDef context_getsets [] = #ifndef WITH_DECIMAL_CONTEXTVAR /* Get the context from the thread state dictionary. */ static PyObject * -current_context_from_dict(void) +current_context_from_dict(decimal_state *modstate) { PyThreadState *tstate = _PyThreadState_GET(); - decimal_state *modstate = GLOBAL_STATE(); #ifdef Py_DEBUG // The caller must hold the GIL _Py_EnsureTstateNotNULL(tstate); @@ -1617,45 +1642,41 @@ current_context_from_dict(void) /* Return borrowed reference to thread local context. */ static PyObject * -current_context(void) +current_context(decimal_state *modstate) { PyThreadState *tstate = _PyThreadState_GET(); - decimal_state *modstate = GLOBAL_STATE(); if (modstate->cached_context && modstate->cached_context->tstate == tstate) { return (PyObject *)(modstate->cached_context); } - return current_context_from_dict(); + return current_context_from_dict(modstate); } /* ctxobj := borrowed reference to the current context */ -#define CURRENT_CONTEXT(ctxobj) \ - ctxobj = current_context(); \ +#define CURRENT_CONTEXT(state, ctxobj) \ + ctxobj = current_context(state); \ if (ctxobj == NULL) { \ return NULL; \ } /* Return a new reference to the current context */ static PyObject * -PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +PyDec_GetCurrentContext(PyObject *self, PyObject *args UNUSED) { PyObject *context; + decimal_state *state = get_module_state(self); - context = current_context(); - if (context == NULL) { - return NULL; - } - + CURRENT_CONTEXT(state, context); return Py_NewRef(context); } /* Set the thread local context to a new context, decrement old reference */ static PyObject * -PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +PyDec_SetCurrentContext(PyObject *self, PyObject *v) { PyObject *dict; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state(self); CONTEXT_CHECK(state, v); dict = PyThreadState_GetDict(); @@ -1691,9 +1712,8 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) } #else static PyObject * -init_current_context(void) +init_current_context(decimal_state *state) { - decimal_state *state = GLOBAL_STATE(); PyObject *tl_context = context_copy(state->default_context_template, NULL); if (tl_context == NULL) { return NULL; @@ -1711,10 +1731,9 @@ init_current_context(void) } static inline PyObject * -current_context(void) +current_context(decimal_state *state) { PyObject *tl_context; - decimal_state *state = GLOBAL_STATE(); if (PyContextVar_Get(state->current_context_var, NULL, &tl_context) < 0) { return NULL; } @@ -1723,12 +1742,12 @@ current_context(void) return tl_context; } - return init_current_context(); + return init_current_context(state); } /* ctxobj := borrowed reference to the current context */ -#define CURRENT_CONTEXT(ctxobj) \ - ctxobj = current_context(); \ +#define CURRENT_CONTEXT(state, ctxobj) \ + ctxobj = current_context(state); \ if (ctxobj == NULL) { \ return NULL; \ } \ @@ -1736,16 +1755,17 @@ current_context(void) /* Return a new reference to the current context */ static PyObject * -PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED) +PyDec_GetCurrentContext(PyObject *self, PyObject *args UNUSED) { - return current_context(); + decimal_state *state = get_module_state(self); + return current_context(state); } /* Set the thread local context to a new context, decrement old reference */ static PyObject * -PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) +PyDec_SetCurrentContext(PyObject *self, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state(self); CONTEXT_CHECK(state, v); /* If the new context is one of the templates, make a copy. @@ -1778,7 +1798,7 @@ PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v) * owns one reference to the global (outer) context and one * to the local (inner) context. */ static PyObject * -ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) +ctxmanager_new(PyObject *m, PyObject *args, PyObject *kwds) // TODO: check params { static char *kwlist[] = { "ctx", "prec", "rounding", @@ -1798,8 +1818,8 @@ ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds) PyObject *flags = Py_None; PyObject *traps = Py_None; - decimal_state *state = GLOBAL_STATE(); - CURRENT_CONTEXT(global); + decimal_state *state = get_module_state(m); + CURRENT_CONTEXT(state, global); if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOOOO", kwlist, &local, &prec, &rounding, &Emin, &Emax, &capitals, &clamp, &flags, &traps)) { return NULL; @@ -1876,7 +1896,7 @@ ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED) { PyObject *ret; - ret = PyDec_SetCurrentContext(NULL, self->local); + ret = PyDec_SetCurrentContext(PyType_GetModule(Py_TYPE(self)), self->local); if (ret == NULL) { return NULL; } @@ -1891,7 +1911,7 @@ ctxmanager_restore_global(PyDecContextManagerObject *self, { PyObject *ret; - ret = PyDec_SetCurrentContext(NULL, self->global); + ret = PyDec_SetCurrentContext(PyType_GetModule(Py_TYPE(self)), self->global); if (ret == NULL) { return NULL; } @@ -1934,7 +1954,7 @@ PyDecType_New(PyTypeObject *type) { PyDecObject *dec; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (type == state->PyDec_Type) { dec = PyObject_GC_New(PyDecObject, state->PyDec_Type); } @@ -2321,8 +2341,8 @@ PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v, mpd_t *d1, *d2; uint32_t status = 0; mpd_context_t maxctx; + decimal_state *state = get_module_state_by_def(type); - decimal_state *state = GLOBAL_STATE(); #ifdef Py_DEBUG assert(PyType_IsSubtype(type, state->PyDec_Type)); #endif @@ -2459,7 +2479,7 @@ PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context) PyObject *dec; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (type == state->PyDec_Type && PyDec_CheckExact(state, v)) { return Py_NewRef(v); } @@ -2734,8 +2754,8 @@ dec_from_float(PyObject *type, PyObject *pyfloat) PyObject *context; PyObject *result; - CURRENT_CONTEXT(context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def((PyTypeObject *)type); + CURRENT_CONTEXT(state, context); result = PyDecType_FromFloatExact(state->PyDec_Type, pyfloat, context); if (type != (PyObject *)state->PyDec_Type && result != NULL) { Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL)); @@ -2748,7 +2768,7 @@ dec_from_float(PyObject *type, PyObject *pyfloat) static PyObject * ctx_from_float(PyObject *context, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); return PyDec_FromFloat(state, v, context); } @@ -2759,7 +2779,7 @@ dec_apply(PyObject *v, PyObject *context) PyObject *result; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -2786,7 +2806,7 @@ dec_apply(PyObject *v, PyObject *context) static PyObject * PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); if (v == NULL) { return PyDecType_FromSsizeExact(type, 0, context); } @@ -2821,7 +2841,7 @@ PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context) static PyObject * PyDec_FromObject(PyObject *v, PyObject *context) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (v == NULL) { return PyDec_FromSsize(state, 0, context); } @@ -2877,7 +2897,7 @@ dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds) &v, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(type); CONTEXT_CHECK_VA(state, context); return PyDecType_FromObjectExact(type, v, context); @@ -2908,7 +2928,7 @@ ctx_create_decimal(PyObject *context, PyObject *args) Py_LOCAL_INLINE(int) convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (PyDec_Check(state, v)) { *conv = Py_NewRef(v); return 1; @@ -3011,7 +3031,7 @@ multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context) if (tmp == NULL) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); denom = PyDec_FromLongExact(state, tmp, context); Py_DECREF(tmp); if (denom == NULL) { @@ -3066,7 +3086,7 @@ numerator_as_decimal(PyObject *r, PyObject *context) return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); num = PyDec_FromLongExact(state, tmp, context); Py_DECREF(tmp); return num; @@ -3085,7 +3105,7 @@ convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w, *vcmp = v; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (PyDec_Check(state, w)) { *wcmp = Py_NewRef(w); } @@ -3183,7 +3203,8 @@ dec_str(PyObject *dec) mpd_ssize_t size; char *cp; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context)); if (size < 0) { PyErr_NoMemory(); @@ -3201,8 +3222,8 @@ dec_repr(PyObject *dec) { PyObject *res, *context; char *cp; - - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); cp = mpd_to_sci(MPD(dec), CtxCaps(context)); if (cp == NULL) { PyErr_NoMemory(); @@ -3363,7 +3384,8 @@ dec_format(PyObject *dec, PyObject *args) mpd_t tmp = {MPD_STATIC|MPD_STATIC_DATA,0,0,0,MPD_MINALLOC_MAX,dt}; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { return NULL; } @@ -3626,9 +3648,9 @@ dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED) return NULL; } - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); - decimal_state *state = GLOBAL_STATE(); tmp = dec_alloc(state); if (tmp == NULL) { return NULL; @@ -3719,12 +3741,12 @@ PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds) &rounding, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); CONTEXT_CHECK_VA(state, context); workctx = *CTX(context); if (rounding != Py_None) { - int round = getround(rounding); + int round = getround(state, rounding); if (round < 0) { return NULL; } @@ -3761,12 +3783,12 @@ PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds) &rounding, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); CONTEXT_CHECK_VA(state, context); workctx = *CTX(context); if (rounding != Py_None) { - int round = getround(rounding); + int round = getround(state, rounding); if (round < 0) { return NULL; } @@ -3829,7 +3851,8 @@ PyDec_Round(PyObject *dec, PyObject *args) uint32_t status = 0; PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); if (!PyArg_ParseTuple(args, "|O", &x)) { return NULL; } @@ -3849,7 +3872,6 @@ PyDec_Round(PyObject *dec, PyObject *args) if (y == -1 && PyErr_Occurred()) { return NULL; } - decimal_state *state = GLOBAL_STATE(); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -3951,7 +3973,7 @@ PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED) } } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); result = PyObject_CallFunctionObjArgs((PyObject *)state->DecimalTuple, sign, coeff, expt, NULL); @@ -3978,8 +4000,8 @@ nm_##MPDFUNC(PyObject *self) \ PyObject *context; \ uint32_t status = 0; \ \ - decimal_state *state = GLOBAL_STATE(); \ - CURRENT_CONTEXT(context); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ + CURRENT_CONTEXT(state, context); \ if ((result = dec_alloc(state)) == NULL) { \ return NULL; \ } \ @@ -4003,8 +4025,8 @@ nm_##MPDFUNC(PyObject *self, PyObject *other) \ PyObject *context; \ uint32_t status = 0; \ \ - decimal_state *state = GLOBAL_STATE(); \ - CURRENT_CONTEXT(context) ; \ + decimal_state *state = find_state_left_or_right(self, other); \ + CURRENT_CONTEXT(state, context) ; \ CONVERT_BINOP(&a, &b, self, other, context); \ \ if ((result = dec_alloc(state)) == NULL) { \ @@ -4044,7 +4066,7 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ \ return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \ @@ -4064,7 +4086,8 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ \ if ((result = dec_alloc(state)) == NULL) { \ @@ -4096,7 +4119,8 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &other, &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ \ @@ -4134,7 +4158,8 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &other, &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_BINOP_RAISE(&a, &b, self, other, context); \ \ @@ -4167,7 +4192,7 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ &other, &third, &context)) { \ return NULL; \ } \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context); \ \ @@ -4210,8 +4235,8 @@ static PyObject * nm_dec_as_long(PyObject *dec) { PyObject *context; - - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); + CURRENT_CONTEXT(state, context); return dec_as_long(dec, context, MPD_ROUND_DOWN); } @@ -4230,10 +4255,10 @@ nm_mpd_qdivmod(PyObject *v, PyObject *w) uint32_t status = 0; PyObject *ret; - CURRENT_CONTEXT(context); + decimal_state *state = find_state_left_or_right(v, w); + CURRENT_CONTEXT(state, context); CONVERT_BINOP(&a, &b, v, w, context); - decimal_state *state = GLOBAL_STATE(); q = dec_alloc(state); if (q == NULL) { Py_DECREF(a); @@ -4271,7 +4296,8 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) PyObject *context; uint32_t status = 0; - CURRENT_CONTEXT(context); + decimal_state *state = find_state_left_or_right(base, exp); + CURRENT_CONTEXT(state, context); CONVERT_BINOP(&a, &b, base, exp, context); if (mod != Py_None) { @@ -4282,7 +4308,6 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod) } } - decimal_state *state = GLOBAL_STATE(); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -4380,11 +4405,11 @@ dec_conjugate(PyObject *self, PyObject *dummy UNUSED) } static PyObject * -dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED) +dec_mpd_radix(PyObject *self, PyObject *dummy UNUSED) { PyObject *result; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -4400,7 +4425,7 @@ dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED) PyObject *result; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if ((result = dec_alloc(state)) == NULL) { return NULL; } @@ -4421,7 +4446,7 @@ dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED) PyObject *result; uint32_t status = 0; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if ((result = dec_alloc(state)) == NULL) { return NULL; } @@ -4451,7 +4476,7 @@ dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds) &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); cp = mpd_class(MPD(self), CTX(context)); @@ -4471,7 +4496,7 @@ dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds) &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context)); @@ -4504,7 +4529,7 @@ dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds) &other, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); CONVERT_BINOP_RAISE(&a, &b, self, other, context); @@ -4539,7 +4564,7 @@ dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds) &other, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); CONTEXT_CHECK_VA(state, context); CONVERT_BINOP_RAISE(&a, &b, self, other, context); @@ -4574,12 +4599,12 @@ dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds) &w, &rounding, &context)) { return NULL; } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(v)); CONTEXT_CHECK_VA(state, context); workctx = *CTX(context); if (rounding != Py_None) { - int round = getround(rounding); + int round = getround(state, rounding); if (round < 0) { return NULL; } @@ -4618,12 +4643,12 @@ dec_richcompare(PyObject *v, PyObject *w, int op) uint32_t status = 0; int a_issnan, b_issnan; int r; + decimal_state *state = find_state_left_or_right(v, w); #ifdef Py_DEBUG - decimal_state *state = GLOBAL_STATE(); assert(PyDec_Check(state, v)); #endif - CURRENT_CONTEXT(context); + CURRENT_CONTEXT(state, context); CONVERT_BINOP_CMP(&a, &b, v, w, op, context); a_issnan = mpd_issnan(MPD(a)); @@ -4674,7 +4699,8 @@ dec_ceil(PyObject *self, PyObject *dummy UNUSED) { PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); return dec_as_long(self, context, MPD_ROUND_CEILING); } @@ -4712,7 +4738,8 @@ dec_floor(PyObject *self, PyObject *dummy UNUSED) { PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); return dec_as_long(self, context, MPD_ROUND_FLOOR); } @@ -4876,7 +4903,8 @@ dec_trunc(PyObject *self, PyObject *dummy UNUSED) { PyObject *context; - CURRENT_CONTEXT(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + CURRENT_CONTEXT(state, context); return dec_as_long(self, context, MPD_ROUND_DOWN); } @@ -4892,7 +4920,7 @@ dec_imag(PyObject *self UNUSED, void *closure UNUSED) { PyObject *result; - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); result = dec_alloc(state); if (result == NULL) { return NULL; @@ -5091,7 +5119,8 @@ ctx_##MPDFUNC(PyObject *context, PyObject *v) \ uint32_t status = 0; \ \ CONVERT_OP_RAISE(&a, v, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ return NULL; \ @@ -5122,7 +5151,8 @@ ctx_##MPDFUNC(PyObject *context, PyObject *args) \ } \ \ CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ Py_DECREF(b); \ @@ -5157,7 +5187,8 @@ ctx_##MPDFUNC(PyObject *context, PyObject *args) \ } \ \ CONVERT_BINOP_RAISE(&a, &b, v, w, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = \ + get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ Py_DECREF(b); \ @@ -5186,7 +5217,7 @@ ctx_##MPDFUNC(PyObject *context, PyObject *args) \ } \ \ CONVERT_TERNOP_RAISE(&a, &b, &c, v, w, x, context); \ - decimal_state *state = GLOBAL_STATE(); \ + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); \ if ((result = dec_alloc(state)) == NULL) { \ Py_DECREF(a); \ Py_DECREF(b); \ @@ -5252,7 +5283,7 @@ ctx_mpd_qdivmod(PyObject *context, PyObject *args) } CONVERT_BINOP_RAISE(&a, &b, v, w, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); q = dec_alloc(state); if (q == NULL) { Py_DECREF(a); @@ -5307,7 +5338,7 @@ ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds) } } - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5357,9 +5388,9 @@ DecCtx_BoolFunc_NO_CTX(mpd_issnan) DecCtx_BoolFunc_NO_CTX(mpd_iszero) static PyObject * -ctx_iscanonical(PyObject *context UNUSED, PyObject *v) +ctx_iscanonical(PyObject *context, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (!PyDec_Check(state, v)) { PyErr_SetString(PyExc_TypeError, "argument must be a Decimal"); @@ -5383,9 +5414,9 @@ PyDecContext_Apply(PyObject *context, PyObject *v) } static PyObject * -ctx_canonical(PyObject *context UNUSED, PyObject *v) +ctx_canonical(PyObject *context, PyObject *v) { - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); if (!PyDec_Check(state, v)) { PyErr_SetString(PyExc_TypeError, "argument must be a Decimal"); @@ -5402,7 +5433,7 @@ ctx_mpd_qcopy_abs(PyObject *context, PyObject *v) uint32_t status = 0; CONVERT_OP_RAISE(&a, v, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5435,7 +5466,7 @@ ctx_mpd_qcopy_negate(PyObject *context, PyObject *v) uint32_t status = 0; CONVERT_OP_RAISE(&a, v, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5532,7 +5563,7 @@ ctx_mpd_qcopy_sign(PyObject *context, PyObject *args) } CONVERT_BINOP_RAISE(&a, &b, v, w, context); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); result = dec_alloc(state); if (result == NULL) { Py_DECREF(a); @@ -5721,17 +5752,6 @@ static PyMethodDef _decimal_methods [] = { NULL, NULL, 1, NULL } }; -static struct PyModuleDef _decimal_module = { - PyModuleDef_HEAD_INIT, - "decimal", - doc__decimal, - -1, - _decimal_methods, - NULL, - NULL, - NULL, - NULL -}; struct ssize_constmap { const char *name; mpd_ssize_t val; }; static struct ssize_constmap ssize_constants [] = { @@ -5807,10 +5827,9 @@ cfunc_noargs(PyTypeObject *t, const char *name) } -PyMODINIT_FUNC -PyInit__decimal(void) +static int +_decimal_exec(PyObject *m) { - PyObject *m = NULL; PyObject *numbers = NULL; PyObject *Number = NULL; PyObject *collections = NULL; @@ -5831,7 +5850,7 @@ PyInit__decimal(void) mpd_free = PyMem_Free; mpd_setminalloc(_Py_DEC_MINALLOC); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state(m); /* Init external C-API functions */ state->_py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; @@ -5903,10 +5922,6 @@ PyInit__decimal(void) Py_CLEAR(collections_abc); Py_CLEAR(MutableMapping); - - /* Create the module */ - ASSIGN_PTR(m, PyModule_Create(&_decimal_module)); - /* Add types to the module */ CHECK_INT(PyModule_AddType(m, state->PyDec_Type)); CHECK_INT(PyModule_AddType(m, state->PyDecContext_Type)); @@ -6044,29 +6059,99 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70")); CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version())); - - return m; - + return 0; error: Py_CLEAR(obj); /* GCOV_NOT_REACHED */ Py_CLEAR(numbers); /* GCOV_NOT_REACHED */ Py_CLEAR(Number); /* 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(state->SignalTuple); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->DecimalTuple); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->default_context_template); /* GCOV_NOT_REACHED */ + + return -1; /* GCOV_NOT_REACHED */ +} + +static int +decimal_traverse(PyObject *module, visitproc visit, void *arg) +{ + decimal_state *state = get_module_state(module); + Py_VISIT(state->PyDecContextManager_Type); + Py_VISIT(state->PyDecContext_Type); + Py_VISIT(state->PyDecSignalDictMixin_Type); + Py_VISIT(state->PyDec_Type); + Py_VISIT(state->PyDecSignalDict_Type); + Py_VISIT(state->DecimalTuple); + Py_VISIT(state->DecimalException); + #ifndef WITH_DECIMAL_CONTEXTVAR - Py_CLEAR(state->tls_context_key); /* GCOV_NOT_REACHED */ + Py_VISIT(state->tls_context_key); + Py_VISIT(state->cached_context); #else - Py_CLEAR(state->current_context_var); /* GCOV_NOT_REACHED */ + Py_VISIT(state->current_context_var); #endif - Py_CLEAR(state->basic_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(state->extended_context_template); /* GCOV_NOT_REACHED */ - Py_CLEAR(m); /* GCOV_NOT_REACHED */ - return NULL; /* GCOV_NOT_REACHED */ + Py_VISIT(state->default_context_template); + Py_VISIT(state->basic_context_template); + Py_VISIT(state->extended_context_template); + Py_VISIT(state->Rational); + Py_VISIT(state->SignalTuple); + return 0; +} + +static int +decimal_clear(PyObject *module) +{ + decimal_state *state = get_module_state(module); + Py_CLEAR(state->PyDecContextManager_Type); + Py_CLEAR(state->PyDecContext_Type); + Py_CLEAR(state->PyDecSignalDictMixin_Type); + Py_CLEAR(state->PyDec_Type); + Py_CLEAR(state->PyDecSignalDict_Type); + Py_CLEAR(state->DecimalTuple); + Py_CLEAR(state->DecimalException); + +#ifndef WITH_DECIMAL_CONTEXTVAR + Py_CLEAR(state->tls_context_key); + Py_CLEAR(state->cached_context); +#else + Py_CLEAR(state->current_context_var); +#endif + + Py_CLEAR(state->default_context_template); + Py_CLEAR(state->basic_context_template); + Py_CLEAR(state->extended_context_template); + Py_CLEAR(state->Rational); + Py_CLEAR(state->SignalTuple); + return 0; +} + +static void +decimal_free(void *module) +{ + (void)decimal_clear((PyObject *)module); +} + +static struct PyModuleDef_Slot _decimal_slots[] = { + {Py_mod_exec, _decimal_exec}, + {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED}, + {0, NULL}, +}; + +static struct PyModuleDef _decimal_module = { + PyModuleDef_HEAD_INIT, + .m_name = "decimal", + .m_doc = doc__decimal, + .m_size = sizeof(decimal_state), + .m_methods = _decimal_methods, + .m_slots = _decimal_slots, + .m_traverse = decimal_traverse, + .m_clear = decimal_clear, + .m_free = decimal_free, +}; + +PyMODINIT_FUNC +PyInit__decimal(void) +{ + return PyModuleDef_Init(&_decimal_module); } From 821c398c786959af2b6c36b7d6297fc9506ec0eb Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Wed, 26 Jul 2023 16:45:47 +0800 Subject: [PATCH 2/4] Fix function signature --- Modules/_decimal/_decimal.c | 64 +++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index a2ebf254b4ded1..167a200be8b435 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -355,10 +355,9 @@ dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */ } static PyObject * -flags_as_exception(uint32_t flags) +flags_as_exception(decimal_state *state, uint32_t flags) { DecCondMap *cm; - decimal_state *state = GLOBAL_STATE(); for (cm = state->signal_map; cm->name != NULL; cm++) { if (flags&cm->flag) { @@ -370,10 +369,9 @@ flags_as_exception(uint32_t flags) } Py_LOCAL_INLINE(uint32_t) -exception_as_flag(PyObject *ex) +exception_as_flag(decimal_state *state, PyObject *ex) { DecCondMap *cm; - decimal_state *state = GLOBAL_STATE(); for (cm = state->signal_map; cm->name != NULL; cm++) { if (cm->ex == ex) { @@ -386,11 +384,10 @@ exception_as_flag(PyObject *ex) } static PyObject * -flags_as_list(uint32_t flags) +flags_as_list(decimal_state *state, uint32_t flags) { PyObject *list; DecCondMap *cm; - decimal_state *state = GLOBAL_STATE(); list = PyList_New(0); if (list == NULL) { @@ -420,11 +417,10 @@ flags_as_list(uint32_t flags) } static PyObject * -signals_as_list(uint32_t flags) +signals_as_list(decimal_state *state, uint32_t flags) { PyObject *list; DecCondMap *cm; - decimal_state *state = GLOBAL_STATE(); list = PyList_New(0); if (list == NULL) { @@ -444,7 +440,7 @@ signals_as_list(uint32_t flags) } static uint32_t -list_as_flags(PyObject *list) +list_as_flags(decimal_state *state, PyObject *list) { PyObject *item; uint32_t flags, x; @@ -456,7 +452,7 @@ list_as_flags(PyObject *list) flags = 0; for (j = 0; j < n; j++) { item = PyList_GetItem(list, j); - x = exception_as_flag(item); + x = exception_as_flag(state, item); if (x & DEC_ERRORS) { return x; } @@ -467,11 +463,10 @@ list_as_flags(PyObject *list) } static PyObject * -flags_as_dict(uint32_t flags) +flags_as_dict(decimal_state *state, uint32_t flags) { DecCondMap *cm; PyObject *dict; - decimal_state *state = GLOBAL_STATE(); dict = PyDict_New(); if (dict == NULL) { @@ -490,13 +485,12 @@ flags_as_dict(uint32_t flags) } static uint32_t -dict_as_flags(PyObject *val) +dict_as_flags(decimal_state *state, PyObject *val) { PyObject *b; DecCondMap *cm; uint32_t flags = 0; int x; - decimal_state *state = GLOBAL_STATE(); if (!PyDict_Check(val)) { PyErr_SetString(PyExc_TypeError, @@ -556,6 +550,7 @@ static int dec_addstatus(PyObject *context, uint32_t status) { mpd_context_t *ctx = CTX(context); + decimal_state *state = get_module_state_by_def(Py_TYPE(context)); ctx->status |= status; if (status & (ctx->traps|MPD_Malloc_error)) { @@ -566,11 +561,11 @@ dec_addstatus(PyObject *context, uint32_t status) return 1; } - ex = flags_as_exception(ctx->traps&status); + ex = flags_as_exception(state, ctx->traps&status); if (ex == NULL) { return 1; /* GCOV_NOT_REACHED */ } - siglist = flags_as_list(ctx->traps&status); + siglist = flags_as_list(state, ctx->traps&status); if (siglist == NULL) { return 1; } @@ -637,8 +632,9 @@ static PyObject * signaldict_getitem(PyObject *self, PyObject *key) { uint32_t flag; + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); - flag = exception_as_flag(key); + flag = exception_as_flag(state, key); if (flag & DEC_ERRORS) { return NULL; } @@ -652,11 +648,12 @@ signaldict_setitem(PyObject *self, PyObject *key, PyObject *value) uint32_t flag; int x; + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); if (value == NULL) { return value_error_int("signal keys cannot be deleted"); } - flag = exception_as_flag(key); + flag = exception_as_flag(state, key); if (flag & DEC_ERRORS) { return -1; } @@ -702,7 +699,7 @@ signaldict_repr(PyObject *self) assert(SIGNAL_MAP_LEN == 9); - decimal_state *state = GLOBAL_STATE(); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); for (cm=state->signal_map, i=0; cm->name != NULL; cm++, i++) { n[i] = cm->fqname; b[i] = SdFlags(self)&cm->flag ? "True" : "False"; @@ -729,7 +726,7 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False; } else if (PyDict_Check(w)) { - uint32_t flags = dict_as_flags(w); + uint32_t flags = dict_as_flags(state, w); if (flags & DEC_ERRORS) { if (flags & DEC_INVALID_SIGNALS) { /* non-comparable: Py_NotImplemented */ @@ -751,7 +748,8 @@ signaldict_richcompare(PyObject *v, PyObject *w, int op) static PyObject * signaldict_copy(PyObject *self, PyObject *args UNUSED) { - return flags_as_dict(SdFlags(self)); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + return flags_as_dict(state, SdFlags(self)); } @@ -1038,8 +1036,8 @@ context_settraps_list(PyObject *self, PyObject *value) { mpd_context_t *ctx; uint32_t flags; - - flags = list_as_flags(value); + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); + flags = list_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1063,7 +1061,7 @@ context_settraps_dict(PyObject *self, PyObject *value) flags = SdFlags(value); } else { - flags = dict_as_flags(value); + flags = dict_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1103,8 +1101,9 @@ context_setstatus_list(PyObject *self, PyObject *value) { mpd_context_t *ctx; uint32_t flags; + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); - flags = list_as_flags(value); + flags = list_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1128,7 +1127,7 @@ context_setstatus_dict(PyObject *self, PyObject *value) flags = SdFlags(value); } else { - flags = dict_as_flags(value); + flags = dict_as_flags(state, value); if (flags & DEC_ERRORS) { return -1; } @@ -1542,14 +1541,15 @@ context_reduce(PyObject *self, PyObject *args UNUSED) PyObject *traps; PyObject *ret; mpd_context_t *ctx; + decimal_state *state = get_module_state_by_def(Py_TYPE(self)); ctx = CTX(self); - flags = signals_as_list(ctx->status); + flags = signals_as_list(state, ctx->status); if (flags == NULL) { return NULL; } - traps = signals_as_list(ctx->traps); + traps = signals_as_list(state, ctx->traps); if (traps == NULL) { Py_DECREF(flags); return NULL; @@ -6098,10 +6098,8 @@ _decimal_exec(PyObject *m) Py_CLEAR(collections); /* GCOV_NOT_REACHED */ Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */ Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */ - PyMem_Free(state->signal_map); /* GCOV_NOT_REACHED */ - PyMem_Free(state->cond_map); /* GCOV_NOT_REACHED */ - return -1; /* GCOV_NOT_REACHED */ + return -1; } static int @@ -6128,6 +6126,7 @@ decimal_traverse(PyObject *module, visitproc visit, void *arg) Py_VISIT(state->extended_context_template); Py_VISIT(state->Rational); Py_VISIT(state->SignalTuple); + return 0; } @@ -6155,6 +6154,9 @@ decimal_clear(PyObject *module) Py_CLEAR(state->extended_context_template); Py_CLEAR(state->Rational); Py_CLEAR(state->SignalTuple); + + PyMem_Free(state->signal_map); + PyMem_Free(state->cond_map); return 0; } From b137f1833880a30c3abc3e0a16c332914df72b56 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Thu, 27 Jul 2023 10:51:19 +0800 Subject: [PATCH 3/4] Update comment --- Modules/_decimal/_decimal.c | 2 +- Tools/c-analyzer/cpython/globals-to-fix.tsv | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 167a200be8b435..27399604725b8a 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -1824,7 +1824,7 @@ PyDec_SetCurrentContext(PyObject *self, PyObject *v) * owns one reference to the global (outer) context and one * to the local (inner) context. */ static PyObject * -ctxmanager_new(PyObject *m, PyObject *args, PyObject *kwds) // TODO: check params +ctxmanager_new(PyObject *m, PyObject *args, PyObject *kwds) { static char *kwlist[] = { "ctx", "prec", "rounding", diff --git a/Tools/c-analyzer/cpython/globals-to-fix.tsv b/Tools/c-analyzer/cpython/globals-to-fix.tsv index 90bbc8928b428a..1e041257879c3b 100644 --- a/Tools/c-analyzer/cpython/globals-to-fix.tsv +++ b/Tools/c-analyzer/cpython/globals-to-fix.tsv @@ -421,7 +421,6 @@ Modules/_datetimemodule.c - us_per_hour - Modules/_datetimemodule.c - us_per_day - Modules/_datetimemodule.c - us_per_week - Modules/_datetimemodule.c - seconds_per_day - -Modules/_decimal/_decimal.c - global_state - ## state Modules/_asynciomodule.c - fi_freelist - From 50d524327fa82d740ae4968b796b0fe3fffd6669 Mon Sep 17 00:00:00 2001 From: CharlieZhao Date: Thu, 27 Jul 2023 11:22:19 +0800 Subject: [PATCH 4/4] Add NEWS --- .../2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst b/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst new file mode 100644 index 00000000000000..f5a0e539e5d05f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-07-27-11-18-04.gh-issue-106078.WEy2Yn.rst @@ -0,0 +1 @@ +Isolate :mod:`!_decimal` (apply :pep:`687`). Patch by Charlie Zhao. \ No newline at end of file