summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorCharlie Zhao <zhaoyu_hit@qq.com>2023-07-28 05:58:14 (GMT)
committerGitHub <noreply@github.com>2023-07-28 05:58:14 (GMT)
commita43cc3fa1ffebfd15eff2c6d8e5433a17969e348 (patch)
tree813af448d855ffd9f1136d01da591ef5cd5fa60c /Modules
parent3dcac785810df4d9db50abe90847eaf03bbdaaf4 (diff)
downloadcpython-a43cc3fa1ffebfd15eff2c6d8e5433a17969e348.zip
cpython-a43cc3fa1ffebfd15eff2c6d8e5433a17969e348.tar.gz
cpython-a43cc3fa1ffebfd15eff2c6d8e5433a17969e348.tar.bz2
gh-106078: Isolate `decimal` module (#107287)
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_decimal/_decimal.c451
1 files changed, 269 insertions, 182 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index 671976a..7a20697 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -95,9 +95,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"
@@ -328,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) {
@@ -343,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) {
@@ -359,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) {
@@ -393,11 +417,10 @@ error:
}
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) {
@@ -417,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;
@@ -429,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;
}
@@ -440,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) {
@@ -463,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,
@@ -529,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)) {
@@ -539,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;
}
@@ -556,11 +578,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]) {
@@ -602,9 +622,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);
}
@@ -612,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;
}
@@ -627,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;
}
@@ -677,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";
@@ -696,7 +718,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) {
@@ -704,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 */
@@ -726,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));
}
@@ -795,7 +818,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]);
}
@@ -954,7 +977,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;
}
@@ -1012,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;
}
@@ -1032,12 +1056,12 @@ 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);
}
else {
- flags = dict_as_flags(value);
+ flags = dict_as_flags(state, value);
if (flags & DEC_ERRORS) {
return -1;
}
@@ -1077,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;
}
@@ -1097,12 +1122,12 @@ 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);
}
else {
- flags = dict_as_flags(value);
+ flags = dict_as_flags(state, value);
if (flags & DEC_ERRORS) {
return -1;
}
@@ -1288,7 +1313,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);
}
@@ -1353,7 +1378,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;
}
@@ -1405,7 +1430,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);
@@ -1473,7 +1498,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;
@@ -1496,7 +1521,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;
@@ -1516,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;
@@ -1568,7 +1594,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, \
@@ -1591,10 +1617,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);
@@ -1643,45 +1668,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();
@@ -1717,9 +1738,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;
@@ -1737,10 +1757,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;
}
@@ -1749,12 +1768,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; \
} \
@@ -1762,16 +1781,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.
@@ -1804,7 +1824,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)
{
static char *kwlist[] = {
"ctx", "prec", "rounding",
@@ -1824,8 +1844,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;
@@ -1902,7 +1922,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;
}
@@ -1917,7 +1937,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;
}
@@ -1960,7 +1980,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);
}
@@ -2347,8 +2367,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
@@ -2485,7 +2505,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);
}
@@ -2760,8 +2780,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));
@@ -2774,7 +2794,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);
}
@@ -2785,7 +2805,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;
@@ -2812,7 +2832,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);
}
@@ -2847,7 +2867,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);
}
@@ -2903,7 +2923,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);
@@ -2934,7 +2954,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;
@@ -3037,7 +3057,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) {
@@ -3092,7 +3112,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;
@@ -3111,7 +3131,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);
}
@@ -3209,7 +3229,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();
@@ -3227,8 +3248,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();
@@ -3389,7 +3410,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;
}
@@ -3652,9 +3674,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;
@@ -3745,12 +3767,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;
}
@@ -3787,12 +3809,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;
}
@@ -3855,7 +3877,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;
}
@@ -3875,7 +3898,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;
@@ -3977,7 +3999,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);
@@ -4004,8 +4026,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; \
} \
@@ -4029,8 +4051,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) { \
@@ -4070,7 +4092,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(); \
@@ -4090,7 +4112,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) { \
@@ -4122,7 +4145,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); \
\
@@ -4160,7 +4184,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); \
\
@@ -4193,7 +4218,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); \
\
@@ -4236,8 +4261,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);
}
@@ -4256,10 +4281,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);
@@ -4297,7 +4322,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) {
@@ -4308,7 +4334,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);
@@ -4406,11 +4431,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;
@@ -4426,7 +4451,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;
}
@@ -4447,7 +4472,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;
}
@@ -4477,7 +4502,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));
@@ -4497,7 +4522,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));
@@ -4530,7 +4555,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);
@@ -4565,7 +4590,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);
@@ -4600,12 +4625,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;
}
@@ -4644,12 +4669,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));
@@ -4700,7 +4725,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);
}
@@ -4738,7 +4764,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);
}
@@ -4902,7 +4929,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);
}
@@ -4918,7 +4946,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;
@@ -5117,7 +5145,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; \
@@ -5148,7 +5177,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); \
@@ -5183,7 +5213,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); \
@@ -5212,7 +5243,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); \
@@ -5278,7 +5309,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);
@@ -5333,7 +5364,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);
@@ -5383,9 +5414,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");
@@ -5409,9 +5440,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");
@@ -5428,7 +5459,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);
@@ -5461,7 +5492,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);
@@ -5558,7 +5589,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);
@@ -5747,17 +5778,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 [] = {
@@ -5833,10 +5853,9 @@ error:
}
-PyMODINIT_FUNC
-PyInit__decimal(void)
+static int
+_decimal_exec(PyObject *m)
{
- PyObject *m = NULL;
PyObject *numbers = NULL;
PyObject *Number = NULL;
PyObject *collections = NULL;
@@ -5857,7 +5876,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;
@@ -5929,10 +5948,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));
@@ -6073,31 +6088,103 @@ 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 */
- PyMem_Free(state->signal_map); /* GCOV_NOT_REACHED */
- PyMem_Free(state->cond_map); /* GCOV_NOT_REACHED */
- Py_CLEAR(state->DecimalTuple); /* GCOV_NOT_REACHED */
- Py_CLEAR(state->default_context_template); /* GCOV_NOT_REACHED */
+
+ return -1;
+}
+
+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_VISIT(state->tls_context_key);
+ Py_VISIT(state->cached_context);
+#else
+ Py_VISIT(state->current_context_var);
+#endif
+
+ 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); /* GCOV_NOT_REACHED */
+ Py_CLEAR(state->tls_context_key);
+ Py_CLEAR(state->cached_context);
#else
- Py_CLEAR(state->current_context_var); /* GCOV_NOT_REACHED */
+ Py_CLEAR(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_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);
+
+ PyMem_Free(state->signal_map);
+ PyMem_Free(state->cond_map);
+ 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);
}