[Python-checkins] gh-106078: Prepare to isolate decimal module (#106880)

kumaraditya303 webhook-mailer at python.org
Thu Jul 20 05:24:39 EDT 2023


https://github.com/python/cpython/commit/a1620dd7b70abfceba6cda76efe5a14468f87f1d
commit: a1620dd7b70abfceba6cda76efe5a14468f87f1d
branch: main
author: Charlie Zhao <zhaoyu_hit at qq.com>
committer: kumaraditya303 <kumaraditya at python.org>
date: 2023-07-20T09:24:35Z
summary:

gh-106078: Prepare to isolate decimal module (#106880)

* move signal_map to global_state

* move cond_map to global_state

files:
M Modules/_decimal/_decimal.c
M Tools/c-analyzer/cpython/ignored.tsv

diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index f9dc6e875fa5f..f531def7b3a33 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -46,6 +46,7 @@
 #endif
 
 struct PyDecContextObject;
+struct DecCondMap;
 
 typedef struct {
     PyTypeObject *PyDecContextManager_Type;
@@ -82,6 +83,9 @@ typedef struct {
 
     PyObject *SignalTuple;
 
+    struct DecCondMap *signal_map;
+    struct DecCondMap *cond_map;
+
     /* External C-API functions */
     binaryfunc _py_long_multiply;
     binaryfunc _py_long_floor_divide;
@@ -181,7 +185,7 @@ incr_false(void)
 #define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1)
 #define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED)
 
-typedef struct {
+typedef struct DecCondMap {
     const char *name;   /* condition or signal name */
     const char *fqname; /* fully qualified name */
     uint32_t flag;      /* libmpdec flag */
@@ -193,7 +197,7 @@ typedef struct {
 #define INEXACT 6
 #define ROUNDED 7
 #define SIGNAL_MAP_LEN 9
-static DecCondMap signal_map[] = {
+static DecCondMap signal_map_template[] = {
   {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL},
   {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL},
   {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL},
@@ -207,7 +211,7 @@ static DecCondMap signal_map[] = {
 };
 
 /* Exceptions that inherit from InvalidOperation */
-static DecCondMap cond_map[] = {
+static DecCondMap cond_map_template[] = {
   {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL},
   {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL},
   {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL},
@@ -219,6 +223,21 @@ static DecCondMap cond_map[] = {
   {NULL}
 };
 
+/* Return a duplicate of DecCondMap template */
+static inline DecCondMap *
+dec_cond_map_init(DecCondMap *template, Py_ssize_t size)
+{
+    DecCondMap *cm;
+    cm = PyMem_Malloc(size);
+    if (cm == NULL) {
+        PyErr_NoMemory();
+        return NULL;
+    }
+
+    memcpy(cm, template, size);
+    return cm;
+}
+
 static const char *dec_signal_string[MPD_NUM_FLAGS] = {
     "Clamped",
     "InvalidOperation",
@@ -312,8 +331,9 @@ static PyObject *
 flags_as_exception(uint32_t flags)
 {
     DecCondMap *cm;
+    decimal_state *state = GLOBAL_STATE();
 
-    for (cm = signal_map; cm->name != NULL; cm++) {
+    for (cm = state->signal_map; cm->name != NULL; cm++) {
         if (flags&cm->flag) {
             return cm->ex;
         }
@@ -326,8 +346,9 @@ Py_LOCAL_INLINE(uint32_t)
 exception_as_flag(PyObject *ex)
 {
     DecCondMap *cm;
+    decimal_state *state = GLOBAL_STATE();
 
-    for (cm = signal_map; cm->name != NULL; cm++) {
+    for (cm = state->signal_map; cm->name != NULL; cm++) {
         if (cm->ex == ex) {
             return cm->flag;
         }
@@ -342,20 +363,21 @@ flags_as_list(uint32_t flags)
 {
     PyObject *list;
     DecCondMap *cm;
+    decimal_state *state = GLOBAL_STATE();
 
     list = PyList_New(0);
     if (list == NULL) {
         return NULL;
     }
 
-    for (cm = cond_map; cm->name != NULL; cm++) {
+    for (cm = state->cond_map; cm->name != NULL; cm++) {
         if (flags&cm->flag) {
             if (PyList_Append(list, cm->ex) < 0) {
                 goto error;
             }
         }
     }
-    for (cm = signal_map+1; cm->name != NULL; cm++) {
+    for (cm = state->signal_map+1; cm->name != NULL; cm++) {
         if (flags&cm->flag) {
             if (PyList_Append(list, cm->ex) < 0) {
                 goto error;
@@ -375,13 +397,14 @@ signals_as_list(uint32_t flags)
 {
     PyObject *list;
     DecCondMap *cm;
+    decimal_state *state = GLOBAL_STATE();
 
     list = PyList_New(0);
     if (list == NULL) {
         return NULL;
     }
 
-    for (cm = signal_map; cm->name != NULL; cm++) {
+    for (cm = state->signal_map; cm->name != NULL; cm++) {
         if (flags&cm->flag) {
             if (PyList_Append(list, cm->ex) < 0) {
                 Py_DECREF(list);
@@ -421,13 +444,14 @@ flags_as_dict(uint32_t flags)
 {
     DecCondMap *cm;
     PyObject *dict;
+    decimal_state *state = GLOBAL_STATE();
 
     dict = PyDict_New();
     if (dict == NULL) {
         return NULL;
     }
 
-    for (cm = signal_map; cm->name != NULL; cm++) {
+    for (cm = state->signal_map; cm->name != NULL; cm++) {
         PyObject *b = flags&cm->flag ? Py_True : Py_False;
         if (PyDict_SetItem(dict, cm->ex, b) < 0) {
             Py_DECREF(dict);
@@ -445,6 +469,7 @@ dict_as_flags(PyObject *val)
     DecCondMap *cm;
     uint32_t flags = 0;
     int x;
+    decimal_state *state = GLOBAL_STATE();
 
     if (!PyDict_Check(val)) {
         PyErr_SetString(PyExc_TypeError,
@@ -458,7 +483,7 @@ dict_as_flags(PyObject *val)
         return DEC_INVALID_SIGNALS;
     }
 
-    for (cm = signal_map; cm->name != NULL; cm++) {
+    for (cm = state->signal_map; cm->name != NULL; cm++) {
         b = PyDict_GetItemWithError(val, cm->ex);
         if (b == NULL) {
             if (PyErr_Occurred()) {
@@ -652,7 +677,8 @@ signaldict_repr(PyObject *self)
 
     assert(SIGNAL_MAP_LEN == 9);
 
-    for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
+    decimal_state *state = GLOBAL_STATE();
+    for (cm=state->signal_map, i=0; cm->name != NULL; cm++, i++) {
         n[i] = cm->fqname;
         b[i] = SdFlags(self)&cm->flag ? "True" : "False";
     }
@@ -5922,10 +5948,12 @@ PyInit__decimal(void)
     ASSIGN_PTR(state->SignalTuple, PyTuple_New(SIGNAL_MAP_LEN));
 
     /* Add exceptions that correspond to IEEE signals */
+    ASSIGN_PTR(state->signal_map, dec_cond_map_init(signal_map_template,
+                                                    sizeof(signal_map_template)));
     for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) {
         PyObject *base;
 
-        cm = signal_map + i;
+        cm = state->signal_map + i;
 
         switch (cm->flag) {
         case MPD_Float_operation:
@@ -5936,13 +5964,13 @@ PyInit__decimal(void)
                                 PyExc_ZeroDivisionError);
             break;
         case MPD_Overflow:
-            base = PyTuple_Pack(2, signal_map[INEXACT].ex,
-                                   signal_map[ROUNDED].ex);
+            base = PyTuple_Pack(2, state->signal_map[INEXACT].ex,
+                                   state->signal_map[ROUNDED].ex);
             break;
         case MPD_Underflow:
-            base = PyTuple_Pack(3, signal_map[INEXACT].ex,
-                                   signal_map[ROUNDED].ex,
-                                   signal_map[SUBNORMAL].ex);
+            base = PyTuple_Pack(3, state->signal_map[INEXACT].ex,
+                                   state->signal_map[ROUNDED].ex,
+                                   state->signal_map[SUBNORMAL].ex);
             break;
         default:
             base = PyTuple_Pack(1, state->DecimalException);
@@ -5968,16 +5996,18 @@ PyInit__decimal(void)
      * several conditions, including InvalidOperation! Naming the
      * signal IEEEInvalidOperation would prevent the confusion.
      */
-    cond_map[0].ex = signal_map[0].ex;
+    ASSIGN_PTR(state->cond_map, dec_cond_map_init(cond_map_template,
+                                                  sizeof(cond_map_template)));
+    state->cond_map[0].ex = state->signal_map[0].ex;
 
     /* Add remaining exceptions, inherit from InvalidOperation */
-    for (cm = cond_map+1; cm->name != NULL; cm++) {
+    for (cm = state->cond_map+1; cm->name != NULL; cm++) {
         PyObject *base;
         if (cm->flag == MPD_Division_undefined) {
-            base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError);
+            base = PyTuple_Pack(2, state->signal_map[0].ex, PyExc_ZeroDivisionError);
         }
         else {
-            base = PyTuple_Pack(1, signal_map[0].ex);
+            base = PyTuple_Pack(1, state->signal_map[0].ex);
         }
         if (base == NULL) {
             goto error; /* GCOV_NOT_REACHED */
@@ -6057,6 +6087,8 @@ PyInit__decimal(void)
     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 */
 #ifndef WITH_DECIMAL_CONTEXTVAR
diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv
index 73eec6631d951..228ca8648a2f3 100644
--- a/Tools/c-analyzer/cpython/ignored.tsv
+++ b/Tools/c-analyzer/cpython/ignored.tsv
@@ -205,13 +205,13 @@ Modules/_datetimemodule.c	-	max_fold_seconds	-
 Modules/_datetimemodule.c	datetime_isoformat	specs	-
 Modules/_datetimemodule.c	parse_hh_mm_ss_ff	correction	-
 Modules/_datetimemodule.c	time_isoformat	specs	-
-Modules/_decimal/_decimal.c	-	cond_map	-
+Modules/_decimal/_decimal.c	-	cond_map_template	-
 Modules/_decimal/_decimal.c	-	dec_signal_string	-
 Modules/_decimal/_decimal.c	-	dflt_ctx	-
 Modules/_decimal/_decimal.c	-	int_constants	-
 Modules/_decimal/_decimal.c	-	invalid_rounding_err	-
 Modules/_decimal/_decimal.c	-	invalid_signals_err	-
-Modules/_decimal/_decimal.c	-	signal_map	-
+Modules/_decimal/_decimal.c	-	signal_map_template	-
 Modules/_decimal/_decimal.c	-	ssize_constants	-
 Modules/_elementtree.c	-	ExpatMemoryHandler	-
 Modules/_hashopenssl.c	-	py_hashes	-



More information about the Python-checkins mailing list