1/*
2 * Copyright (c) 2008-2012 Stefan Krah. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#ifndef Py_BUILD_CORE_BUILTIN
29#  define Py_BUILD_CORE_MODULE 1
30#endif
31
32#include <Python.h>
33#include "pycore_pystate.h"       // _PyThreadState_GET()
34#include "complexobject.h"
35#include "mpdecimal.h"
36
37#include <stdlib.h>
38
39#include "docstrings.h"
40
41
42#if !defined(MPD_VERSION_HEX) || MPD_VERSION_HEX < 0x02050000
43  #error "libmpdec version >= 2.5.0 required"
44#endif
45
46
47/*
48 * Type sizes with assertions in mpdecimal.h and pyport.h:
49 *    sizeof(size_t) == sizeof(Py_ssize_t)
50 *    sizeof(size_t) == sizeof(mpd_uint_t) == sizeof(mpd_ssize_t)
51 */
52
53#ifdef TEST_COVERAGE
54  #undef Py_LOCAL_INLINE
55  #define Py_LOCAL_INLINE Py_LOCAL
56#endif
57
58#define MPD_Float_operation MPD_Not_implemented
59
60#define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x
61
62#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
63  #define UNUSED __attribute__((unused))
64#else
65  #define UNUSED
66#endif
67
68/* _Py_DEC_MINALLOC >= MPD_MINALLOC */
69#define _Py_DEC_MINALLOC 4
70
71typedef struct {
72    PyObject_HEAD
73    Py_hash_t hash;
74    mpd_t dec;
75    mpd_uint_t data[_Py_DEC_MINALLOC];
76} PyDecObject;
77
78typedef struct {
79    PyObject_HEAD
80    uint32_t *flags;
81} PyDecSignalDictObject;
82
83typedef struct {
84    PyObject_HEAD
85    mpd_context_t ctx;
86    PyObject *traps;
87    PyObject *flags;
88    int capitals;
89    PyThreadState *tstate;
90} PyDecContextObject;
91
92typedef struct {
93    PyObject_HEAD
94    PyObject *local;
95    PyObject *global;
96} PyDecContextManagerObject;
97
98
99#undef MPD
100#undef CTX
101static PyTypeObject PyDec_Type;
102static PyTypeObject *PyDecSignalDict_Type;
103static PyTypeObject PyDecContext_Type;
104static PyTypeObject PyDecContextManager_Type;
105#define PyDec_CheckExact(v) Py_IS_TYPE(v, &PyDec_Type)
106#define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type)
107#define PyDecSignalDict_Check(v) Py_IS_TYPE(v, PyDecSignalDict_Type)
108#define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type)
109#define MPD(v) (&((PyDecObject *)v)->dec)
110#define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags)
111#define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags)
112#define CTX(v) (&((PyDecContextObject *)v)->ctx)
113#define CtxCaps(v) (((PyDecContextObject *)v)->capitals)
114
115
116Py_LOCAL_INLINE(PyObject *)
117incr_true(void)
118{
119    Py_INCREF(Py_True);
120    return Py_True;
121}
122
123Py_LOCAL_INLINE(PyObject *)
124incr_false(void)
125{
126    Py_INCREF(Py_False);
127    return Py_False;
128}
129
130
131#ifndef WITH_DECIMAL_CONTEXTVAR
132/* Key for thread state dictionary */
133static PyObject *tls_context_key = NULL;
134/* Invariant: NULL or the most recently accessed thread local context */
135static PyDecContextObject *cached_context = NULL;
136#else
137static PyObject *current_context_var = NULL;
138#endif
139
140/* Template for creating new thread contexts, calling Context() without
141 * arguments and initializing the module_context on first access. */
142static PyObject *default_context_template = NULL;
143/* Basic and extended context templates */
144static PyObject *basic_context_template = NULL;
145static PyObject *extended_context_template = NULL;
146
147
148/* Error codes for functions that return signals or conditions */
149#define DEC_INVALID_SIGNALS (MPD_Max_status+1U)
150#define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1)
151#define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED)
152
153typedef struct {
154    const char *name;   /* condition or signal name */
155    const char *fqname; /* fully qualified name */
156    uint32_t flag;      /* libmpdec flag */
157    PyObject *ex;       /* corresponding exception */
158} DecCondMap;
159
160/* Top level Exception; inherits from ArithmeticError */
161static PyObject *DecimalException = NULL;
162
163/* Exceptions that correspond to IEEE signals */
164#define SUBNORMAL 5
165#define INEXACT 6
166#define ROUNDED 7
167#define SIGNAL_MAP_LEN 9
168static DecCondMap signal_map[] = {
169  {"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL},
170  {"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL},
171  {"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL},
172  {"Overflow", "decimal.Overflow", MPD_Overflow, NULL},
173  {"Underflow", "decimal.Underflow", MPD_Underflow, NULL},
174  {"Subnormal", "decimal.Subnormal", MPD_Subnormal, NULL},
175  {"Inexact", "decimal.Inexact", MPD_Inexact, NULL},
176  {"Rounded", "decimal.Rounded", MPD_Rounded, NULL},
177  {"Clamped", "decimal.Clamped", MPD_Clamped, NULL},
178  {NULL}
179};
180
181/* Exceptions that inherit from InvalidOperation */
182static DecCondMap cond_map[] = {
183  {"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL},
184  {"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL},
185  {"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL},
186  {"DivisionUndefined", "decimal.DivisionUndefined", MPD_Division_undefined, NULL},
187  {"InvalidContext", "decimal.InvalidContext", MPD_Invalid_context, NULL},
188#ifdef EXTRA_FUNCTIONALITY
189  {"MallocError", "decimal.MallocError", MPD_Malloc_error, NULL},
190#endif
191  {NULL}
192};
193
194static const char *dec_signal_string[MPD_NUM_FLAGS] = {
195    "Clamped",
196    "InvalidOperation",
197    "DivisionByZero",
198    "InvalidOperation",
199    "InvalidOperation",
200    "InvalidOperation",
201    "Inexact",
202    "InvalidOperation",
203    "InvalidOperation",
204    "InvalidOperation",
205    "FloatOperation",
206    "Overflow",
207    "Rounded",
208    "Subnormal",
209    "Underflow",
210};
211
212#ifdef EXTRA_FUNCTIONALITY
213  #define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD
214#else
215  #define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1)
216#endif
217static PyObject *round_map[_PY_DEC_ROUND_GUARD];
218
219static const char *invalid_rounding_err =
220"valid values for rounding are:\n\
221  [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\
222   ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\
223   ROUND_05UP]";
224
225static const char *invalid_signals_err =
226"valid values for signals are:\n\
227  [InvalidOperation, FloatOperation, DivisionByZero,\n\
228   Overflow, Underflow, Subnormal, Inexact, Rounded,\n\
229   Clamped]";
230
231#ifdef EXTRA_FUNCTIONALITY
232static const char *invalid_flags_err =
233"valid values for _flags or _traps are:\n\
234  signals:\n\
235    [DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\
236     DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\
237     DecClamped]\n\
238  conditions which trigger DecIEEEInvalidOperation:\n\
239    [DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\
240     DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]";
241#endif
242
243static int
244value_error_int(const char *mesg)
245{
246    PyErr_SetString(PyExc_ValueError, mesg);
247    return -1;
248}
249
250#ifdef CONFIG_32
251static PyObject *
252value_error_ptr(const char *mesg)
253{
254    PyErr_SetString(PyExc_ValueError, mesg);
255    return NULL;
256}
257#endif
258
259static int
260type_error_int(const char *mesg)
261{
262    PyErr_SetString(PyExc_TypeError, mesg);
263    return -1;
264}
265
266static int
267runtime_error_int(const char *mesg)
268{
269    PyErr_SetString(PyExc_RuntimeError, mesg);
270    return -1;
271}
272#define INTERNAL_ERROR_INT(funcname) \
273    return runtime_error_int("internal error in " funcname)
274
275static PyObject *
276runtime_error_ptr(const char *mesg)
277{
278    PyErr_SetString(PyExc_RuntimeError, mesg);
279    return NULL;
280}
281#define INTERNAL_ERROR_PTR(funcname) \
282    return runtime_error_ptr("internal error in " funcname)
283
284static void
285dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */
286{ /* GCOV_NOT_REACHED */
287    return; /* GCOV_NOT_REACHED */
288}
289
290static PyObject *
291flags_as_exception(uint32_t flags)
292{
293    DecCondMap *cm;
294
295    for (cm = signal_map; cm->name != NULL; cm++) {
296        if (flags&cm->flag) {
297            return cm->ex;
298        }
299    }
300
301    INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */
302}
303
304Py_LOCAL_INLINE(uint32_t)
305exception_as_flag(PyObject *ex)
306{
307    DecCondMap *cm;
308
309    for (cm = signal_map; cm->name != NULL; cm++) {
310        if (cm->ex == ex) {
311            return cm->flag;
312        }
313    }
314
315    PyErr_SetString(PyExc_KeyError, invalid_signals_err);
316    return DEC_INVALID_SIGNALS;
317}
318
319static PyObject *
320flags_as_list(uint32_t flags)
321{
322    PyObject *list;
323    DecCondMap *cm;
324
325    list = PyList_New(0);
326    if (list == NULL) {
327        return NULL;
328    }
329
330    for (cm = cond_map; cm->name != NULL; cm++) {
331        if (flags&cm->flag) {
332            if (PyList_Append(list, cm->ex) < 0) {
333                goto error;
334            }
335        }
336    }
337    for (cm = signal_map+1; cm->name != NULL; cm++) {
338        if (flags&cm->flag) {
339            if (PyList_Append(list, cm->ex) < 0) {
340                goto error;
341            }
342        }
343    }
344
345    return list;
346
347error:
348    Py_DECREF(list);
349    return NULL;
350}
351
352static PyObject *
353signals_as_list(uint32_t flags)
354{
355    PyObject *list;
356    DecCondMap *cm;
357
358    list = PyList_New(0);
359    if (list == NULL) {
360        return NULL;
361    }
362
363    for (cm = signal_map; cm->name != NULL; cm++) {
364        if (flags&cm->flag) {
365            if (PyList_Append(list, cm->ex) < 0) {
366                Py_DECREF(list);
367                return NULL;
368            }
369        }
370    }
371
372    return list;
373}
374
375static uint32_t
376list_as_flags(PyObject *list)
377{
378    PyObject *item;
379    uint32_t flags, x;
380    Py_ssize_t n, j;
381
382    assert(PyList_Check(list));
383
384    n = PyList_Size(list);
385    flags = 0;
386    for (j = 0; j < n; j++) {
387        item = PyList_GetItem(list, j);
388        x = exception_as_flag(item);
389        if (x & DEC_ERRORS) {
390            return x;
391        }
392        flags |= x;
393    }
394
395    return flags;
396}
397
398static PyObject *
399flags_as_dict(uint32_t flags)
400{
401    DecCondMap *cm;
402    PyObject *dict;
403
404    dict = PyDict_New();
405    if (dict == NULL) {
406        return NULL;
407    }
408
409    for (cm = signal_map; cm->name != NULL; cm++) {
410        PyObject *b = flags&cm->flag ? Py_True : Py_False;
411        if (PyDict_SetItem(dict, cm->ex, b) < 0) {
412            Py_DECREF(dict);
413            return NULL;
414        }
415    }
416
417    return dict;
418}
419
420static uint32_t
421dict_as_flags(PyObject *val)
422{
423    PyObject *b;
424    DecCondMap *cm;
425    uint32_t flags = 0;
426    int x;
427
428    if (!PyDict_Check(val)) {
429        PyErr_SetString(PyExc_TypeError,
430            "argument must be a signal dict");
431        return DEC_INVALID_SIGNALS;
432    }
433
434    if (PyDict_Size(val) != SIGNAL_MAP_LEN) {
435        PyErr_SetString(PyExc_KeyError,
436            "invalid signal dict");
437        return DEC_INVALID_SIGNALS;
438    }
439
440    for (cm = signal_map; cm->name != NULL; cm++) {
441        b = PyDict_GetItemWithError(val, cm->ex);
442        if (b == NULL) {
443            if (PyErr_Occurred()) {
444                return DEC_ERR_OCCURRED;
445            }
446            PyErr_SetString(PyExc_KeyError,
447                "invalid signal dict");
448            return DEC_INVALID_SIGNALS;
449        }
450
451        x = PyObject_IsTrue(b);
452        if (x < 0) {
453            return DEC_ERR_OCCURRED;
454        }
455        if (x == 1) {
456            flags |= cm->flag;
457        }
458    }
459
460    return flags;
461}
462
463#ifdef EXTRA_FUNCTIONALITY
464static uint32_t
465long_as_flags(PyObject *v)
466{
467    long x;
468
469    x = PyLong_AsLong(v);
470    if (x == -1 && PyErr_Occurred()) {
471        return DEC_ERR_OCCURRED;
472    }
473    if (x < 0 || x > (long)MPD_Max_status) {
474        PyErr_SetString(PyExc_TypeError, invalid_flags_err);
475        return DEC_INVALID_SIGNALS;
476    }
477
478    return x;
479}
480#endif
481
482static int
483dec_addstatus(PyObject *context, uint32_t status)
484{
485    mpd_context_t *ctx = CTX(context);
486
487    ctx->status |= status;
488    if (status & (ctx->traps|MPD_Malloc_error)) {
489        PyObject *ex, *siglist;
490
491        if (status & MPD_Malloc_error) {
492            PyErr_NoMemory();
493            return 1;
494        }
495
496        ex = flags_as_exception(ctx->traps&status);
497        if (ex == NULL) {
498            return 1; /* GCOV_NOT_REACHED */
499        }
500        siglist = flags_as_list(ctx->traps&status);
501        if (siglist == NULL) {
502            return 1;
503        }
504
505        PyErr_SetObject(ex, siglist);
506        Py_DECREF(siglist);
507        return 1;
508    }
509    return 0;
510}
511
512static int
513getround(PyObject *v)
514{
515    int i;
516
517    if (PyUnicode_Check(v)) {
518        for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
519            if (v == round_map[i]) {
520                return i;
521            }
522        }
523        for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
524            if (PyUnicode_Compare(v, round_map[i]) == 0) {
525                return i;
526            }
527        }
528    }
529
530    return type_error_int(invalid_rounding_err);
531}
532
533
534/******************************************************************************/
535/*                            SignalDict Object                               */
536/******************************************************************************/
537
538/* The SignalDict is a MutableMapping that provides access to the
539   mpd_context_t flags, which reside in the context object. When a
540   new context is created, context.traps and context.flags are
541   initialized to new SignalDicts. Once a SignalDict is tied to
542   a context, it cannot be deleted. */
543
544static int
545signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
546{
547    SdFlagAddr(self) = NULL;
548    return 0;
549}
550
551static Py_ssize_t
552signaldict_len(PyObject *self UNUSED)
553{
554    return SIGNAL_MAP_LEN;
555}
556
557static PyObject *SignalTuple;
558static PyObject *
559signaldict_iter(PyObject *self UNUSED)
560{
561    return PyTuple_Type.tp_iter(SignalTuple);
562}
563
564static PyObject *
565signaldict_getitem(PyObject *self, PyObject *key)
566{
567    uint32_t flag;
568
569    flag = exception_as_flag(key);
570    if (flag & DEC_ERRORS) {
571        return NULL;
572    }
573
574    return SdFlags(self)&flag ? incr_true() : incr_false();
575}
576
577static int
578signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
579{
580    uint32_t flag;
581    int x;
582
583    if (value == NULL) {
584        return value_error_int("signal keys cannot be deleted");
585    }
586
587    flag = exception_as_flag(key);
588    if (flag & DEC_ERRORS) {
589        return -1;
590    }
591
592    x = PyObject_IsTrue(value);
593    if (x < 0) {
594        return -1;
595    }
596
597    if (x == 1) {
598        SdFlags(self) |= flag;
599    }
600    else {
601        SdFlags(self) &= ~flag;
602    }
603
604    return 0;
605}
606
607static PyObject *
608signaldict_repr(PyObject *self)
609{
610    DecCondMap *cm;
611    const char *n[SIGNAL_MAP_LEN]; /* name */
612    const char *b[SIGNAL_MAP_LEN]; /* bool */
613    int i;
614
615    assert(SIGNAL_MAP_LEN == 9);
616
617    for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
618        n[i] = cm->fqname;
619        b[i] = SdFlags(self)&cm->flag ? "True" : "False";
620    }
621    return PyUnicode_FromFormat(
622        "{<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
623         "<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
624         "<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s}",
625            n[0], b[0], n[1], b[1], n[2], b[2],
626            n[3], b[3], n[4], b[4], n[5], b[5],
627            n[6], b[6], n[7], b[7], n[8], b[8]);
628}
629
630static PyObject *
631signaldict_richcompare(PyObject *v, PyObject *w, int op)
632{
633    PyObject *res = Py_NotImplemented;
634
635    assert(PyDecSignalDict_Check(v));
636
637    if (op == Py_EQ || op == Py_NE) {
638        if (PyDecSignalDict_Check(w)) {
639            res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False;
640        }
641        else if (PyDict_Check(w)) {
642            uint32_t flags = dict_as_flags(w);
643            if (flags & DEC_ERRORS) {
644                if (flags & DEC_INVALID_SIGNALS) {
645                    /* non-comparable: Py_NotImplemented */
646                    PyErr_Clear();
647                }
648                else {
649                    return NULL;
650                }
651            }
652            else {
653                res = (SdFlags(v)==flags) ^ (op==Py_NE) ? Py_True : Py_False;
654            }
655        }
656    }
657
658    Py_INCREF(res);
659    return res;
660}
661
662static PyObject *
663signaldict_copy(PyObject *self, PyObject *args UNUSED)
664{
665    return flags_as_dict(SdFlags(self));
666}
667
668
669static PyMappingMethods signaldict_as_mapping = {
670    (lenfunc)signaldict_len,          /* mp_length */
671    (binaryfunc)signaldict_getitem,   /* mp_subscript */
672    (objobjargproc)signaldict_setitem /* mp_ass_subscript */
673};
674
675static PyMethodDef signaldict_methods[] = {
676    { "copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL},
677    {NULL, NULL}
678};
679
680
681static PyTypeObject PyDecSignalDictMixin_Type =
682{
683    PyVarObject_HEAD_INIT(0, 0)
684    "decimal.SignalDictMixin",                /* tp_name */
685    sizeof(PyDecSignalDictObject),            /* tp_basicsize */
686    0,                                        /* tp_itemsize */
687    0,                                        /* tp_dealloc */
688    0,                                        /* tp_vectorcall_offset */
689    (getattrfunc) 0,                          /* tp_getattr */
690    (setattrfunc) 0,                          /* tp_setattr */
691    0,                                        /* tp_as_async */
692    (reprfunc) signaldict_repr,               /* tp_repr */
693    0,                                        /* tp_as_number */
694    0,                                        /* tp_as_sequence */
695    &signaldict_as_mapping,                   /* tp_as_mapping */
696    PyObject_HashNotImplemented,              /* tp_hash */
697    0,                                        /* tp_call */
698    (reprfunc) 0,                             /* tp_str */
699    PyObject_GenericGetAttr,                  /* tp_getattro */
700    (setattrofunc) 0,                         /* tp_setattro */
701    (PyBufferProcs *) 0,                      /* tp_as_buffer */
702    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,   /* tp_flags */
703    0,                                        /* tp_doc */
704    0,                                        /* tp_traverse */
705    0,                                        /* tp_clear */
706    signaldict_richcompare,                   /* tp_richcompare */
707    0,                                        /* tp_weaklistoffset */
708    (getiterfunc)signaldict_iter,             /* tp_iter */
709    0,                                        /* tp_iternext */
710    signaldict_methods,                       /* tp_methods */
711    0,                                        /* tp_members */
712    0,                                        /* tp_getset */
713    0,                                        /* tp_base */
714    0,                                        /* tp_dict */
715    0,                                        /* tp_descr_get */
716    0,                                        /* tp_descr_set */
717    0,                                        /* tp_dictoffset */
718    (initproc)signaldict_init,                /* tp_init */
719    0,                                        /* tp_alloc */
720    PyType_GenericNew,                        /* tp_new */
721};
722
723
724/******************************************************************************/
725/*                         Context Object, Part 1                             */
726/******************************************************************************/
727
728#define Dec_CONTEXT_GET_SSIZE(mem) \
729static PyObject *                                       \
730context_get##mem(PyObject *self, void *closure UNUSED)  \
731{                                                       \
732    return PyLong_FromSsize_t(mpd_get##mem(CTX(self))); \
733}
734
735#define Dec_CONTEXT_GET_ULONG(mem) \
736static PyObject *                                            \
737context_get##mem(PyObject *self, void *closure UNUSED)       \
738{                                                            \
739    return PyLong_FromUnsignedLong(mpd_get##mem(CTX(self))); \
740}
741
742Dec_CONTEXT_GET_SSIZE(prec)
743Dec_CONTEXT_GET_SSIZE(emax)
744Dec_CONTEXT_GET_SSIZE(emin)
745Dec_CONTEXT_GET_SSIZE(clamp)
746
747#ifdef EXTRA_FUNCTIONALITY
748Dec_CONTEXT_GET_ULONG(traps)
749Dec_CONTEXT_GET_ULONG(status)
750#endif
751
752static PyObject *
753context_getround(PyObject *self, void *closure UNUSED)
754{
755    int i = mpd_getround(CTX(self));
756
757    Py_INCREF(round_map[i]);
758    return round_map[i];
759}
760
761static PyObject *
762context_getcapitals(PyObject *self, void *closure UNUSED)
763{
764    return PyLong_FromLong(CtxCaps(self));
765}
766
767#ifdef EXTRA_FUNCTIONALITY
768static PyObject *
769context_getallcr(PyObject *self, void *closure UNUSED)
770{
771    return PyLong_FromLong(mpd_getcr(CTX(self)));
772}
773#endif
774
775static PyObject *
776context_getetiny(PyObject *self, PyObject *dummy UNUSED)
777{
778    return PyLong_FromSsize_t(mpd_etiny(CTX(self)));
779}
780
781static PyObject *
782context_getetop(PyObject *self, PyObject *dummy UNUSED)
783{
784    return PyLong_FromSsize_t(mpd_etop(CTX(self)));
785}
786
787static int
788context_setprec(PyObject *self, PyObject *value, void *closure UNUSED)
789{
790    mpd_context_t *ctx;
791    mpd_ssize_t x;
792
793    x = PyLong_AsSsize_t(value);
794    if (x == -1 && PyErr_Occurred()) {
795        return -1;
796    }
797
798    ctx = CTX(self);
799    if (!mpd_qsetprec(ctx, x)) {
800        return value_error_int(
801            "valid range for prec is [1, MAX_PREC]");
802    }
803
804    return 0;
805}
806
807static int
808context_setemin(PyObject *self, PyObject *value, void *closure UNUSED)
809{
810    mpd_context_t *ctx;
811    mpd_ssize_t x;
812
813    x = PyLong_AsSsize_t(value);
814    if (x == -1 && PyErr_Occurred()) {
815        return -1;
816    }
817
818    ctx = CTX(self);
819    if (!mpd_qsetemin(ctx, x)) {
820        return value_error_int(
821            "valid range for Emin is [MIN_EMIN, 0]");
822    }
823
824    return 0;
825}
826
827static int
828context_setemax(PyObject *self, PyObject *value, void *closure UNUSED)
829{
830    mpd_context_t *ctx;
831    mpd_ssize_t x;
832
833    x = PyLong_AsSsize_t(value);
834    if (x == -1 && PyErr_Occurred()) {
835        return -1;
836    }
837
838    ctx = CTX(self);
839    if (!mpd_qsetemax(ctx, x)) {
840        return value_error_int(
841            "valid range for Emax is [0, MAX_EMAX]");
842    }
843
844    return 0;
845}
846
847#ifdef CONFIG_32
848static PyObject *
849context_unsafe_setprec(PyObject *self, PyObject *value)
850{
851    mpd_context_t *ctx = CTX(self);
852    mpd_ssize_t x;
853
854    x = PyLong_AsSsize_t(value);
855    if (x == -1 && PyErr_Occurred()) {
856        return NULL;
857    }
858
859    if (x < 1 || x > 1070000000L) {
860        return value_error_ptr(
861            "valid range for unsafe prec is [1, 1070000000]");
862    }
863
864    ctx->prec = x;
865    Py_RETURN_NONE;
866}
867
868static PyObject *
869context_unsafe_setemin(PyObject *self, PyObject *value)
870{
871    mpd_context_t *ctx = CTX(self);
872    mpd_ssize_t x;
873
874    x = PyLong_AsSsize_t(value);
875    if (x == -1 && PyErr_Occurred()) {
876        return NULL;
877    }
878
879    if (x < -1070000000L || x > 0) {
880        return value_error_ptr(
881            "valid range for unsafe emin is [-1070000000, 0]");
882    }
883
884    ctx->emin = x;
885    Py_RETURN_NONE;
886}
887
888static PyObject *
889context_unsafe_setemax(PyObject *self, PyObject *value)
890{
891    mpd_context_t *ctx = CTX(self);
892    mpd_ssize_t x;
893
894    x = PyLong_AsSsize_t(value);
895    if (x == -1 && PyErr_Occurred()) {
896        return NULL;
897    }
898
899    if (x < 0 || x > 1070000000L) {
900        return value_error_ptr(
901            "valid range for unsafe emax is [0, 1070000000]");
902    }
903
904    ctx->emax = x;
905    Py_RETURN_NONE;
906}
907#endif
908
909static int
910context_setround(PyObject *self, PyObject *value, void *closure UNUSED)
911{
912    mpd_context_t *ctx;
913    int x;
914
915    x = getround(value);
916    if (x == -1) {
917        return -1;
918    }
919
920    ctx = CTX(self);
921    if (!mpd_qsetround(ctx, x)) {
922        INTERNAL_ERROR_INT("context_setround"); /* GCOV_NOT_REACHED */
923    }
924
925    return 0;
926}
927
928static int
929context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED)
930{
931    mpd_ssize_t x;
932
933    x = PyLong_AsSsize_t(value);
934    if (x == -1 && PyErr_Occurred()) {
935        return -1;
936    }
937
938    if (x != 0 && x != 1) {
939        return value_error_int(
940            "valid values for capitals are 0 or 1");
941    }
942    CtxCaps(self) = (int)x;
943
944    return 0;
945}
946
947#ifdef EXTRA_FUNCTIONALITY
948static int
949context_settraps(PyObject *self, PyObject *value, void *closure UNUSED)
950{
951    mpd_context_t *ctx;
952    uint32_t flags;
953
954    flags = long_as_flags(value);
955    if (flags & DEC_ERRORS) {
956        return -1;
957    }
958
959    ctx = CTX(self);
960    if (!mpd_qsettraps(ctx, flags)) {
961        INTERNAL_ERROR_INT("context_settraps");
962    }
963
964    return 0;
965}
966#endif
967
968static int
969context_settraps_list(PyObject *self, PyObject *value)
970{
971    mpd_context_t *ctx;
972    uint32_t flags;
973
974    flags = list_as_flags(value);
975    if (flags & DEC_ERRORS) {
976        return -1;
977    }
978
979    ctx = CTX(self);
980    if (!mpd_qsettraps(ctx, flags)) {
981        INTERNAL_ERROR_INT("context_settraps_list");
982    }
983
984    return 0;
985}
986
987static int
988context_settraps_dict(PyObject *self, PyObject *value)
989{
990    mpd_context_t *ctx;
991    uint32_t flags;
992
993    if (PyDecSignalDict_Check(value)) {
994        flags = SdFlags(value);
995    }
996    else {
997        flags = dict_as_flags(value);
998        if (flags & DEC_ERRORS) {
999            return -1;
1000        }
1001    }
1002
1003    ctx = CTX(self);
1004    if (!mpd_qsettraps(ctx, flags)) {
1005        INTERNAL_ERROR_INT("context_settraps_dict");
1006    }
1007
1008    return 0;
1009}
1010
1011#ifdef EXTRA_FUNCTIONALITY
1012static int
1013context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED)
1014{
1015    mpd_context_t *ctx;
1016    uint32_t flags;
1017
1018    flags = long_as_flags(value);
1019    if (flags & DEC_ERRORS) {
1020        return -1;
1021    }
1022
1023    ctx = CTX(self);
1024    if (!mpd_qsetstatus(ctx, flags)) {
1025        INTERNAL_ERROR_INT("context_setstatus");
1026    }
1027
1028    return 0;
1029}
1030#endif
1031
1032static int
1033context_setstatus_list(PyObject *self, PyObject *value)
1034{
1035    mpd_context_t *ctx;
1036    uint32_t flags;
1037
1038    flags = list_as_flags(value);
1039    if (flags & DEC_ERRORS) {
1040        return -1;
1041    }
1042
1043    ctx = CTX(self);
1044    if (!mpd_qsetstatus(ctx, flags)) {
1045        INTERNAL_ERROR_INT("context_setstatus_list");
1046    }
1047
1048    return 0;
1049}
1050
1051static int
1052context_setstatus_dict(PyObject *self, PyObject *value)
1053{
1054    mpd_context_t *ctx;
1055    uint32_t flags;
1056
1057    if (PyDecSignalDict_Check(value)) {
1058        flags = SdFlags(value);
1059    }
1060    else {
1061        flags = dict_as_flags(value);
1062        if (flags & DEC_ERRORS) {
1063            return -1;
1064        }
1065    }
1066
1067    ctx = CTX(self);
1068    if (!mpd_qsetstatus(ctx, flags)) {
1069        INTERNAL_ERROR_INT("context_setstatus_dict");
1070    }
1071
1072    return 0;
1073}
1074
1075static int
1076context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED)
1077{
1078    mpd_context_t *ctx;
1079    mpd_ssize_t x;
1080
1081    x = PyLong_AsSsize_t(value);
1082    if (x == -1 && PyErr_Occurred()) {
1083        return -1;
1084    }
1085    BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1086
1087    ctx = CTX(self);
1088    if (!mpd_qsetclamp(ctx, (int)x)) {
1089        return value_error_int("valid values for clamp are 0 or 1");
1090    }
1091
1092    return 0;
1093}
1094
1095#ifdef EXTRA_FUNCTIONALITY
1096static int
1097context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED)
1098{
1099    mpd_context_t *ctx;
1100    mpd_ssize_t x;
1101
1102    x = PyLong_AsSsize_t(value);
1103    if (x == -1 && PyErr_Occurred()) {
1104        return -1;
1105    }
1106    BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1107
1108    ctx = CTX(self);
1109    if (!mpd_qsetcr(ctx, (int)x)) {
1110        return value_error_int("valid values for _allcr are 0 or 1");
1111    }
1112
1113    return 0;
1114}
1115#endif
1116
1117static PyObject *
1118context_getattr(PyObject *self, PyObject *name)
1119{
1120    PyObject *retval;
1121
1122    if (PyUnicode_Check(name)) {
1123        if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1124            retval = ((PyDecContextObject *)self)->traps;
1125            Py_INCREF(retval);
1126            return retval;
1127        }
1128        if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1129            retval = ((PyDecContextObject *)self)->flags;
1130            Py_INCREF(retval);
1131            return retval;
1132        }
1133    }
1134
1135    return PyObject_GenericGetAttr(self, name);
1136}
1137
1138static int
1139context_setattr(PyObject *self, PyObject *name, PyObject *value)
1140{
1141    if (value == NULL) {
1142        PyErr_SetString(PyExc_AttributeError,
1143            "context attributes cannot be deleted");
1144        return -1;
1145    }
1146
1147    if (PyUnicode_Check(name)) {
1148        if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1149            return context_settraps_dict(self, value);
1150        }
1151        if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1152            return context_setstatus_dict(self, value);
1153        }
1154    }
1155
1156    return PyObject_GenericSetAttr(self, name, value);
1157}
1158
1159static int
1160context_setattrs(PyObject *self, PyObject *prec, PyObject *rounding,
1161                 PyObject *emin, PyObject *emax, PyObject *capitals,
1162                 PyObject *clamp, PyObject *status, PyObject *traps) {
1163
1164    int ret;
1165    if (prec != Py_None && context_setprec(self, prec, NULL) < 0) {
1166        return -1;
1167    }
1168    if (rounding != Py_None && context_setround(self, rounding, NULL) < 0) {
1169        return -1;
1170    }
1171    if (emin != Py_None && context_setemin(self, emin, NULL) < 0) {
1172        return -1;
1173    }
1174    if (emax != Py_None && context_setemax(self, emax, NULL) < 0) {
1175        return -1;
1176    }
1177    if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) {
1178        return -1;
1179    }
1180    if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) {
1181       return -1;
1182    }
1183
1184    if (traps != Py_None) {
1185        if (PyList_Check(traps)) {
1186            ret = context_settraps_list(self, traps);
1187        }
1188#ifdef EXTRA_FUNCTIONALITY
1189        else if (PyLong_Check(traps)) {
1190            ret = context_settraps(self, traps, NULL);
1191        }
1192#endif
1193        else {
1194            ret = context_settraps_dict(self, traps);
1195        }
1196        if (ret < 0) {
1197            return ret;
1198        }
1199    }
1200    if (status != Py_None) {
1201        if (PyList_Check(status)) {
1202            ret = context_setstatus_list(self, status);
1203        }
1204#ifdef EXTRA_FUNCTIONALITY
1205        else if (PyLong_Check(status)) {
1206            ret = context_setstatus(self, status, NULL);
1207        }
1208#endif
1209        else {
1210            ret = context_setstatus_dict(self, status);
1211        }
1212        if (ret < 0) {
1213            return ret;
1214        }
1215    }
1216
1217    return 0;
1218}
1219
1220static PyObject *
1221context_clear_traps(PyObject *self, PyObject *dummy UNUSED)
1222{
1223    CTX(self)->traps = 0;
1224    Py_RETURN_NONE;
1225}
1226
1227static PyObject *
1228context_clear_flags(PyObject *self, PyObject *dummy UNUSED)
1229{
1230    CTX(self)->status = 0;
1231    Py_RETURN_NONE;
1232}
1233
1234#define DEC_DFLT_EMAX 999999
1235#define DEC_DFLT_EMIN -999999
1236
1237static mpd_context_t dflt_ctx = {
1238  28, DEC_DFLT_EMAX, DEC_DFLT_EMIN,
1239  MPD_IEEE_Invalid_operation|MPD_Division_by_zero|MPD_Overflow,
1240  0, 0, MPD_ROUND_HALF_EVEN, 0, 1
1241};
1242
1243static PyObject *
1244context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED)
1245{
1246    PyDecContextObject *self = NULL;
1247    mpd_context_t *ctx;
1248
1249    if (type == &PyDecContext_Type) {
1250        self = PyObject_New(PyDecContextObject, &PyDecContext_Type);
1251    }
1252    else {
1253        self = (PyDecContextObject *)type->tp_alloc(type, 0);
1254    }
1255
1256    if (self == NULL) {
1257        return NULL;
1258    }
1259
1260    self->traps = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL);
1261    if (self->traps == NULL) {
1262        self->flags = NULL;
1263        Py_DECREF(self);
1264        return NULL;
1265    }
1266    self->flags = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL);
1267    if (self->flags == NULL) {
1268        Py_DECREF(self);
1269        return NULL;
1270    }
1271
1272    ctx = CTX(self);
1273
1274    if (default_context_template) {
1275        *ctx = *CTX(default_context_template);
1276    }
1277    else {
1278        *ctx = dflt_ctx;
1279    }
1280
1281    SdFlagAddr(self->traps) = &ctx->traps;
1282    SdFlagAddr(self->flags) = &ctx->status;
1283
1284    CtxCaps(self) = 1;
1285    self->tstate = NULL;
1286
1287    return (PyObject *)self;
1288}
1289
1290static void
1291context_dealloc(PyDecContextObject *self)
1292{
1293#ifndef WITH_DECIMAL_CONTEXTVAR
1294    if (self == cached_context) {
1295        cached_context = NULL;
1296    }
1297#endif
1298
1299    Py_XDECREF(self->traps);
1300    Py_XDECREF(self->flags);
1301    Py_TYPE(self)->tp_free(self);
1302}
1303
1304static int
1305context_init(PyObject *self, PyObject *args, PyObject *kwds)
1306{
1307    static char *kwlist[] = {
1308      "prec", "rounding", "Emin", "Emax", "capitals", "clamp",
1309      "flags", "traps", NULL
1310    };
1311    PyObject *prec = Py_None;
1312    PyObject *rounding = Py_None;
1313    PyObject *emin = Py_None;
1314    PyObject *emax = Py_None;
1315    PyObject *capitals = Py_None;
1316    PyObject *clamp = Py_None;
1317    PyObject *status = Py_None;
1318    PyObject *traps = Py_None;
1319
1320    assert(PyTuple_Check(args));
1321
1322    if (!PyArg_ParseTupleAndKeywords(
1323            args, kwds,
1324            "|OOOOOOOO", kwlist,
1325            &prec, &rounding, &emin, &emax, &capitals, &clamp, &status, &traps
1326         )) {
1327        return -1;
1328    }
1329
1330    return context_setattrs(
1331        self, prec, rounding,
1332        emin, emax, capitals,
1333        clamp, status, traps
1334    );
1335}
1336
1337static PyObject *
1338context_repr(PyDecContextObject *self)
1339{
1340    mpd_context_t *ctx;
1341    char flags[MPD_MAX_SIGNAL_LIST];
1342    char traps[MPD_MAX_SIGNAL_LIST];
1343    int n, mem;
1344
1345    assert(PyDecContext_Check(self));
1346    ctx = CTX(self);
1347
1348    mem = MPD_MAX_SIGNAL_LIST;
1349    n = mpd_lsnprint_signals(flags, mem, ctx->status, dec_signal_string);
1350    if (n < 0 || n >= mem) {
1351        INTERNAL_ERROR_PTR("context_repr");
1352    }
1353
1354    n = mpd_lsnprint_signals(traps, mem, ctx->traps, dec_signal_string);
1355    if (n < 0 || n >= mem) {
1356        INTERNAL_ERROR_PTR("context_repr");
1357    }
1358
1359    return PyUnicode_FromFormat(
1360        "Context(prec=%zd, rounding=%s, Emin=%zd, Emax=%zd, "
1361                "capitals=%d, clamp=%d, flags=%s, traps=%s)",
1362         ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1363         self->capitals, ctx->clamp, flags, traps);
1364}
1365
1366static void
1367init_basic_context(PyObject *v)
1368{
1369    mpd_context_t ctx = dflt_ctx;
1370
1371    ctx.prec = 9;
1372    ctx.traps |= (MPD_Underflow|MPD_Clamped);
1373    ctx.round = MPD_ROUND_HALF_UP;
1374
1375    *CTX(v) = ctx;
1376    CtxCaps(v) = 1;
1377}
1378
1379static void
1380init_extended_context(PyObject *v)
1381{
1382    mpd_context_t ctx = dflt_ctx;
1383
1384    ctx.prec = 9;
1385    ctx.traps = 0;
1386
1387    *CTX(v) = ctx;
1388    CtxCaps(v) = 1;
1389}
1390
1391#ifdef EXTRA_FUNCTIONALITY
1392/* Factory function for creating IEEE interchange format contexts */
1393static PyObject *
1394ieee_context(PyObject *dummy UNUSED, PyObject *v)
1395{
1396    PyObject *context;
1397    mpd_ssize_t bits;
1398    mpd_context_t ctx;
1399
1400    bits = PyLong_AsSsize_t(v);
1401    if (bits == -1 && PyErr_Occurred()) {
1402        return NULL;
1403    }
1404    if (bits <= 0 || bits > INT_MAX) {
1405        goto error;
1406    }
1407    if (mpd_ieee_context(&ctx, (int)bits) < 0) {
1408        goto error;
1409    }
1410
1411    context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1412    if (context == NULL) {
1413        return NULL;
1414    }
1415    *CTX(context) = ctx;
1416
1417    return context;
1418
1419error:
1420    PyErr_Format(PyExc_ValueError,
1421        "argument must be a multiple of 32, with a maximum of %d",
1422        MPD_IEEE_CONTEXT_MAX_BITS);
1423
1424    return NULL;
1425}
1426#endif
1427
1428static PyObject *
1429context_copy(PyObject *self, PyObject *args UNUSED)
1430{
1431    PyObject *copy;
1432
1433    copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1434    if (copy == NULL) {
1435        return NULL;
1436    }
1437
1438    *CTX(copy) = *CTX(self);
1439    CTX(copy)->newtrap = 0;
1440    CtxCaps(copy) = CtxCaps(self);
1441
1442    return copy;
1443}
1444
1445static PyObject *
1446context_reduce(PyObject *self, PyObject *args UNUSED)
1447{
1448    PyObject *flags;
1449    PyObject *traps;
1450    PyObject *ret;
1451    mpd_context_t *ctx;
1452
1453    ctx = CTX(self);
1454
1455    flags = signals_as_list(ctx->status);
1456    if (flags == NULL) {
1457        return NULL;
1458    }
1459    traps = signals_as_list(ctx->traps);
1460    if (traps == NULL) {
1461        Py_DECREF(flags);
1462        return NULL;
1463    }
1464
1465    ret = Py_BuildValue(
1466            "O(nsnniiOO)",
1467            Py_TYPE(self),
1468            ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1469            CtxCaps(self), ctx->clamp, flags, traps
1470    );
1471
1472    Py_DECREF(flags);
1473    Py_DECREF(traps);
1474    return ret;
1475}
1476
1477
1478static PyGetSetDef context_getsets [] =
1479{
1480  { "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL},
1481  { "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL},
1482  { "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL},
1483  { "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL},
1484  { "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL},
1485  { "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL},
1486#ifdef EXTRA_FUNCTIONALITY
1487  { "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL},
1488  { "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL},
1489  { "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL},
1490#endif
1491  {NULL}
1492};
1493
1494
1495#define CONTEXT_CHECK(obj) \
1496    if (!PyDecContext_Check(obj)) {        \
1497        PyErr_SetString(PyExc_TypeError,   \
1498            "argument must be a context"); \
1499        return NULL;                       \
1500    }
1501
1502#define CONTEXT_CHECK_VA(obj) \
1503    if (obj == Py_None) {                           \
1504        CURRENT_CONTEXT(obj);                       \
1505    }                                               \
1506    else if (!PyDecContext_Check(obj)) {            \
1507        PyErr_SetString(PyExc_TypeError,            \
1508            "optional argument must be a context"); \
1509        return NULL;                                \
1510    }
1511
1512
1513/******************************************************************************/
1514/*                Global, thread local and temporary contexts                 */
1515/******************************************************************************/
1516
1517/*
1518 * Thread local storage currently has a speed penalty of about 4%.
1519 * All functions that map Python's arithmetic operators to mpdecimal
1520 * functions have to look up the current context for each and every
1521 * operation.
1522 */
1523
1524#ifndef WITH_DECIMAL_CONTEXTVAR
1525/* Get the context from the thread state dictionary. */
1526static PyObject *
1527current_context_from_dict(void)
1528{
1529    PyThreadState *tstate = _PyThreadState_GET();
1530#ifdef Py_DEBUG
1531    // The caller must hold the GIL
1532    _Py_EnsureTstateNotNULL(tstate);
1533#endif
1534
1535    PyObject *dict = _PyThreadState_GetDict(tstate);
1536    if (dict == NULL) {
1537        PyErr_SetString(PyExc_RuntimeError,
1538            "cannot get thread state");
1539        return NULL;
1540    }
1541
1542    PyObject *tl_context = PyDict_GetItemWithError(dict, tls_context_key);
1543    if (tl_context != NULL) {
1544        /* We already have a thread local context. */
1545        CONTEXT_CHECK(tl_context);
1546    }
1547    else {
1548        if (PyErr_Occurred()) {
1549            return NULL;
1550        }
1551
1552        /* Set up a new thread local context. */
1553        tl_context = context_copy(default_context_template, NULL);
1554        if (tl_context == NULL) {
1555            return NULL;
1556        }
1557        CTX(tl_context)->status = 0;
1558
1559        if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) {
1560            Py_DECREF(tl_context);
1561            return NULL;
1562        }
1563        Py_DECREF(tl_context);
1564    }
1565
1566    /* Cache the context of the current thread, assuming that it
1567     * will be accessed several times before a thread switch. */
1568    cached_context = (PyDecContextObject *)tl_context;
1569    cached_context->tstate = tstate;
1570
1571    /* Borrowed reference with refcount==1 */
1572    return tl_context;
1573}
1574
1575/* Return borrowed reference to thread local context. */
1576static PyObject *
1577current_context(void)
1578{
1579    PyThreadState *tstate = _PyThreadState_GET();
1580    if (cached_context && cached_context->tstate == tstate) {
1581        return (PyObject *)cached_context;
1582    }
1583
1584    return current_context_from_dict();
1585}
1586
1587/* ctxobj := borrowed reference to the current context */
1588#define CURRENT_CONTEXT(ctxobj) \
1589    ctxobj = current_context(); \
1590    if (ctxobj == NULL) {       \
1591        return NULL;            \
1592    }
1593
1594/* Return a new reference to the current context */
1595static PyObject *
1596PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
1597{
1598    PyObject *context;
1599
1600    context = current_context();
1601    if (context == NULL) {
1602        return NULL;
1603    }
1604
1605    Py_INCREF(context);
1606    return context;
1607}
1608
1609/* Set the thread local context to a new context, decrement old reference */
1610static PyObject *
1611PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1612{
1613    PyObject *dict;
1614
1615    CONTEXT_CHECK(v);
1616
1617    dict = PyThreadState_GetDict();
1618    if (dict == NULL) {
1619        PyErr_SetString(PyExc_RuntimeError,
1620            "cannot get thread state");
1621        return NULL;
1622    }
1623
1624    /* If the new context is one of the templates, make a copy.
1625     * This is the current behavior of decimal.py. */
1626    if (v == default_context_template ||
1627        v == basic_context_template ||
1628        v == extended_context_template) {
1629        v = context_copy(v, NULL);
1630        if (v == NULL) {
1631            return NULL;
1632        }
1633        CTX(v)->status = 0;
1634    }
1635    else {
1636        Py_INCREF(v);
1637    }
1638
1639    cached_context = NULL;
1640    if (PyDict_SetItem(dict, tls_context_key, v) < 0) {
1641        Py_DECREF(v);
1642        return NULL;
1643    }
1644
1645    Py_DECREF(v);
1646    Py_RETURN_NONE;
1647}
1648#else
1649static PyObject *
1650init_current_context(void)
1651{
1652    PyObject *tl_context = context_copy(default_context_template, NULL);
1653    if (tl_context == NULL) {
1654        return NULL;
1655    }
1656    CTX(tl_context)->status = 0;
1657
1658    PyObject *tok = PyContextVar_Set(current_context_var, tl_context);
1659    if (tok == NULL) {
1660        Py_DECREF(tl_context);
1661        return NULL;
1662    }
1663    Py_DECREF(tok);
1664
1665    return tl_context;
1666}
1667
1668static inline PyObject *
1669current_context(void)
1670{
1671    PyObject *tl_context;
1672    if (PyContextVar_Get(current_context_var, NULL, &tl_context) < 0) {
1673        return NULL;
1674    }
1675
1676    if (tl_context != NULL) {
1677        return tl_context;
1678    }
1679
1680    return init_current_context();
1681}
1682
1683/* ctxobj := borrowed reference to the current context */
1684#define CURRENT_CONTEXT(ctxobj) \
1685    ctxobj = current_context(); \
1686    if (ctxobj == NULL) {       \
1687        return NULL;            \
1688    }                           \
1689    Py_DECREF(ctxobj);
1690
1691/* Return a new reference to the current context */
1692static PyObject *
1693PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
1694{
1695    return current_context();
1696}
1697
1698/* Set the thread local context to a new context, decrement old reference */
1699static PyObject *
1700PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1701{
1702    CONTEXT_CHECK(v);
1703
1704    /* If the new context is one of the templates, make a copy.
1705     * This is the current behavior of decimal.py. */
1706    if (v == default_context_template ||
1707        v == basic_context_template ||
1708        v == extended_context_template) {
1709        v = context_copy(v, NULL);
1710        if (v == NULL) {
1711            return NULL;
1712        }
1713        CTX(v)->status = 0;
1714    }
1715    else {
1716        Py_INCREF(v);
1717    }
1718
1719    PyObject *tok = PyContextVar_Set(current_context_var, v);
1720    Py_DECREF(v);
1721    if (tok == NULL) {
1722        return NULL;
1723    }
1724    Py_DECREF(tok);
1725
1726    Py_RETURN_NONE;
1727}
1728#endif
1729
1730/* Context manager object for the 'with' statement. The manager
1731 * owns one reference to the global (outer) context and one
1732 * to the local (inner) context. */
1733static PyObject *
1734ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds)
1735{
1736    static char *kwlist[] = {
1737      "ctx", "prec", "rounding",
1738      "Emin", "Emax", "capitals",
1739      "clamp", "flags", "traps",
1740      NULL
1741    };
1742    PyDecContextManagerObject *self;
1743    PyObject *local = Py_None;
1744    PyObject *global;
1745
1746    PyObject *prec = Py_None;
1747    PyObject *rounding = Py_None;
1748    PyObject *Emin = Py_None;
1749    PyObject *Emax = Py_None;
1750    PyObject *capitals = Py_None;
1751    PyObject *clamp = Py_None;
1752    PyObject *flags = Py_None;
1753    PyObject *traps = Py_None;
1754
1755    CURRENT_CONTEXT(global);
1756    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOOOO", kwlist, &local,
1757          &prec, &rounding, &Emin, &Emax, &capitals, &clamp, &flags, &traps)) {
1758        return NULL;
1759    }
1760    if (local == Py_None) {
1761        local = global;
1762    }
1763    else if (!PyDecContext_Check(local)) {
1764        PyErr_SetString(PyExc_TypeError,
1765            "optional argument must be a context");
1766        return NULL;
1767    }
1768
1769    self = PyObject_New(PyDecContextManagerObject,
1770                        &PyDecContextManager_Type);
1771    if (self == NULL) {
1772        return NULL;
1773    }
1774
1775    self->local = context_copy(local, NULL);
1776    if (self->local == NULL) {
1777        self->global = NULL;
1778        Py_DECREF(self);
1779        return NULL;
1780    }
1781    self->global = global;
1782    Py_INCREF(self->global);
1783
1784    int ret = context_setattrs(
1785        self->local, prec, rounding,
1786        Emin, Emax, capitals,
1787        clamp, flags, traps
1788    );
1789
1790    if (ret < 0) {
1791        Py_DECREF(self);
1792        return NULL;
1793    }
1794
1795    return (PyObject *)self;
1796}
1797
1798static void
1799ctxmanager_dealloc(PyDecContextManagerObject *self)
1800{
1801    Py_XDECREF(self->local);
1802    Py_XDECREF(self->global);
1803    PyObject_Free(self);
1804}
1805
1806static PyObject *
1807ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED)
1808{
1809    PyObject *ret;
1810
1811    ret = PyDec_SetCurrentContext(NULL, self->local);
1812    if (ret == NULL) {
1813        return NULL;
1814    }
1815    Py_DECREF(ret);
1816
1817    Py_INCREF(self->local);
1818    return self->local;
1819}
1820
1821static PyObject *
1822ctxmanager_restore_global(PyDecContextManagerObject *self,
1823                          PyObject *args UNUSED)
1824{
1825    PyObject *ret;
1826
1827    ret = PyDec_SetCurrentContext(NULL, self->global);
1828    if (ret == NULL) {
1829        return NULL;
1830    }
1831    Py_DECREF(ret);
1832
1833    Py_RETURN_NONE;
1834}
1835
1836
1837static PyMethodDef ctxmanager_methods[] = {
1838  {"__enter__", (PyCFunction)ctxmanager_set_local, METH_NOARGS, NULL},
1839  {"__exit__", (PyCFunction)ctxmanager_restore_global, METH_VARARGS, NULL},
1840  {NULL, NULL}
1841};
1842
1843static PyTypeObject PyDecContextManager_Type =
1844{
1845    PyVarObject_HEAD_INIT(NULL, 0)
1846    "decimal.ContextManager",               /* tp_name */
1847    sizeof(PyDecContextManagerObject),      /* tp_basicsize */
1848    0,                                      /* tp_itemsize */
1849    (destructor) ctxmanager_dealloc,        /* tp_dealloc */
1850    0,                                      /* tp_vectorcall_offset */
1851    (getattrfunc) 0,                        /* tp_getattr */
1852    (setattrfunc) 0,                        /* tp_setattr */
1853    0,                                      /* tp_as_async */
1854    (reprfunc) 0,                           /* tp_repr */
1855    0,                                      /* tp_as_number */
1856    0,                                      /* tp_as_sequence */
1857    0,                                      /* tp_as_mapping */
1858    0,                                      /* tp_hash */
1859    0,                                      /* tp_call */
1860    0,                                      /* tp_str */
1861    (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */
1862    (setattrofunc) 0,                       /* tp_setattro */
1863    (PyBufferProcs *) 0,                    /* tp_as_buffer */
1864    Py_TPFLAGS_DEFAULT,                     /* tp_flags */
1865    0,                                      /* tp_doc */
1866    0,                                      /* tp_traverse */
1867    0,                                      /* tp_clear */
1868    0,                                      /* tp_richcompare */
1869    0,                                      /* tp_weaklistoffset */
1870    0,                                      /* tp_iter */
1871    0,                                      /* tp_iternext */
1872    ctxmanager_methods,                     /* tp_methods */
1873};
1874
1875
1876/******************************************************************************/
1877/*                           New Decimal Object                               */
1878/******************************************************************************/
1879
1880static PyObject *
1881PyDecType_New(PyTypeObject *type)
1882{
1883    PyDecObject *dec;
1884
1885    if (type == &PyDec_Type) {
1886        dec = PyObject_New(PyDecObject, &PyDec_Type);
1887    }
1888    else {
1889        dec = (PyDecObject *)type->tp_alloc(type, 0);
1890    }
1891    if (dec == NULL) {
1892        return NULL;
1893    }
1894
1895    dec->hash = -1;
1896
1897    MPD(dec)->flags = MPD_STATIC|MPD_STATIC_DATA;
1898    MPD(dec)->exp = 0;
1899    MPD(dec)->digits = 0;
1900    MPD(dec)->len = 0;
1901    MPD(dec)->alloc = _Py_DEC_MINALLOC;
1902    MPD(dec)->data = dec->data;
1903
1904    return (PyObject *)dec;
1905}
1906#define dec_alloc() PyDecType_New(&PyDec_Type)
1907
1908static void
1909dec_dealloc(PyObject *dec)
1910{
1911    mpd_del(MPD(dec));
1912    Py_TYPE(dec)->tp_free(dec);
1913}
1914
1915
1916/******************************************************************************/
1917/*                           Conversions to Decimal                           */
1918/******************************************************************************/
1919
1920Py_LOCAL_INLINE(int)
1921is_space(enum PyUnicode_Kind kind, const void *data, Py_ssize_t pos)
1922{
1923    Py_UCS4 ch = PyUnicode_READ(kind, data, pos);
1924    return Py_UNICODE_ISSPACE(ch);
1925}
1926
1927/* Return the ASCII representation of a numeric Unicode string. The numeric
1928   string may contain ascii characters in the range [1, 127], any Unicode
1929   space and any unicode digit. If strip_ws is true, leading and trailing
1930   whitespace is stripped. If ignore_underscores is true, underscores are
1931   ignored.
1932
1933   Return NULL if malloc fails and an empty string if invalid characters
1934   are found. */
1935static char *
1936numeric_as_ascii(const PyObject *u, int strip_ws, int ignore_underscores)
1937{
1938    enum PyUnicode_Kind kind;
1939    const void *data;
1940    Py_UCS4 ch;
1941    char *res, *cp;
1942    Py_ssize_t j, len;
1943    int d;
1944
1945    if (PyUnicode_READY(u) == -1) {
1946        return NULL;
1947    }
1948
1949    kind = PyUnicode_KIND(u);
1950    data = PyUnicode_DATA(u);
1951    len =  PyUnicode_GET_LENGTH(u);
1952
1953    cp = res = PyMem_Malloc(len+1);
1954    if (res == NULL) {
1955        PyErr_NoMemory();
1956        return NULL;
1957    }
1958
1959    j = 0;
1960    if (strip_ws) {
1961        while (len > 0 && is_space(kind, data, len-1)) {
1962            len--;
1963        }
1964        while (j < len && is_space(kind, data, j)) {
1965            j++;
1966        }
1967    }
1968
1969    for (; j < len; j++) {
1970        ch = PyUnicode_READ(kind, data, j);
1971        if (ignore_underscores && ch == '_') {
1972            continue;
1973        }
1974        if (0 < ch && ch <= 127) {
1975            *cp++ = ch;
1976            continue;
1977        }
1978        if (Py_UNICODE_ISSPACE(ch)) {
1979            *cp++ = ' ';
1980            continue;
1981        }
1982        d = Py_UNICODE_TODECIMAL(ch);
1983        if (d < 0) {
1984            /* empty string triggers ConversionSyntax */
1985            *res = '\0';
1986            return res;
1987        }
1988        *cp++ = '0' + d;
1989    }
1990    *cp = '\0';
1991    return res;
1992}
1993
1994/* Return a new PyDecObject or a subtype from a C string. Use the context
1995   during conversion. */
1996static PyObject *
1997PyDecType_FromCString(PyTypeObject *type, const char *s,
1998                      PyObject *context)
1999{
2000    PyObject *dec;
2001    uint32_t status = 0;
2002
2003    dec = PyDecType_New(type);
2004    if (dec == NULL) {
2005        return NULL;
2006    }
2007
2008    mpd_qset_string(MPD(dec), s, CTX(context), &status);
2009    if (dec_addstatus(context, status)) {
2010        Py_DECREF(dec);
2011        return NULL;
2012    }
2013    return dec;
2014}
2015
2016/* Return a new PyDecObject or a subtype from a C string. Attempt exact
2017   conversion. If the operand cannot be converted exactly, set
2018   InvalidOperation. */
2019static PyObject *
2020PyDecType_FromCStringExact(PyTypeObject *type, const char *s,
2021                           PyObject *context)
2022{
2023    PyObject *dec;
2024    uint32_t status = 0;
2025    mpd_context_t maxctx;
2026
2027    dec = PyDecType_New(type);
2028    if (dec == NULL) {
2029        return NULL;
2030    }
2031
2032    mpd_maxcontext(&maxctx);
2033
2034    mpd_qset_string(MPD(dec), s, &maxctx, &status);
2035    if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
2036        /* we want exact results */
2037        mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
2038    }
2039    status &= MPD_Errors;
2040    if (dec_addstatus(context, status)) {
2041        Py_DECREF(dec);
2042        return NULL;
2043    }
2044
2045    return dec;
2046}
2047
2048/* Return a new PyDecObject or a subtype from a PyUnicodeObject. */
2049static PyObject *
2050PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u,
2051                      PyObject *context)
2052{
2053    PyObject *dec;
2054    char *s;
2055
2056    s = numeric_as_ascii(u, 0, 0);
2057    if (s == NULL) {
2058        return NULL;
2059    }
2060
2061    dec = PyDecType_FromCString(type, s, context);
2062    PyMem_Free(s);
2063    return dec;
2064}
2065
2066/* Return a new PyDecObject or a subtype from a PyUnicodeObject. Attempt exact
2067 * conversion. If the conversion is not exact, fail with InvalidOperation.
2068 * Allow leading and trailing whitespace in the input operand. */
2069static PyObject *
2070PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u,
2071                             PyObject *context)
2072{
2073    PyObject *dec;
2074    char *s;
2075
2076    s = numeric_as_ascii(u, 1, 1);
2077    if (s == NULL) {
2078        return NULL;
2079    }
2080
2081    dec = PyDecType_FromCStringExact(type, s, context);
2082    PyMem_Free(s);
2083    return dec;
2084}
2085
2086/* Set PyDecObject from triple without any error checking. */
2087Py_LOCAL_INLINE(void)
2088_dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp)
2089{
2090
2091#ifdef CONFIG_64
2092    MPD(dec)->data[0] = v;
2093    MPD(dec)->len = 1;
2094#else
2095    uint32_t q, r;
2096    q = v / MPD_RADIX;
2097    r = v - q * MPD_RADIX;
2098    MPD(dec)->data[1] = q;
2099    MPD(dec)->data[0] = r;
2100    MPD(dec)->len = q ? 2 : 1;
2101#endif
2102    mpd_set_flags(MPD(dec), sign);
2103    MPD(dec)->exp = exp;
2104    mpd_setdigits(MPD(dec));
2105}
2106
2107/* Return a new PyDecObject from an mpd_ssize_t. */
2108static PyObject *
2109PyDecType_FromSsize(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2110{
2111    PyObject *dec;
2112    uint32_t status = 0;
2113
2114    dec = PyDecType_New(type);
2115    if (dec == NULL) {
2116        return NULL;
2117    }
2118
2119    mpd_qset_ssize(MPD(dec), v, CTX(context), &status);
2120    if (dec_addstatus(context, status)) {
2121        Py_DECREF(dec);
2122        return NULL;
2123    }
2124    return dec;
2125}
2126
2127/* Return a new PyDecObject from an mpd_ssize_t. Conversion is exact. */
2128static PyObject *
2129PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2130{
2131    PyObject *dec;
2132    uint32_t status = 0;
2133    mpd_context_t maxctx;
2134
2135    dec = PyDecType_New(type);
2136    if (dec == NULL) {
2137        return NULL;
2138    }
2139
2140    mpd_maxcontext(&maxctx);
2141
2142    mpd_qset_ssize(MPD(dec), v, &maxctx, &status);
2143    if (dec_addstatus(context, status)) {
2144        Py_DECREF(dec);
2145        return NULL;
2146    }
2147    return dec;
2148}
2149
2150/* Convert from a PyLongObject. The context is not modified; flags set
2151   during conversion are accumulated in the status parameter. */
2152static PyObject *
2153dec_from_long(PyTypeObject *type, const PyObject *v,
2154              const mpd_context_t *ctx, uint32_t *status)
2155{
2156    PyObject *dec;
2157    PyLongObject *l = (PyLongObject *)v;
2158    Py_ssize_t ob_size;
2159    size_t len;
2160    uint8_t sign;
2161
2162    dec = PyDecType_New(type);
2163    if (dec == NULL) {
2164        return NULL;
2165    }
2166
2167    ob_size = Py_SIZE(l);
2168    if (ob_size == 0) {
2169        _dec_settriple(dec, MPD_POS, 0, 0);
2170        return dec;
2171    }
2172
2173    if (ob_size < 0) {
2174        len = -ob_size;
2175        sign = MPD_NEG;
2176    }
2177    else {
2178        len = ob_size;
2179        sign = MPD_POS;
2180    }
2181
2182    if (len == 1) {
2183        _dec_settriple(dec, sign, *l->ob_digit, 0);
2184        mpd_qfinalize(MPD(dec), ctx, status);
2185        return dec;
2186    }
2187
2188#if PYLONG_BITS_IN_DIGIT == 30
2189    mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2190                    ctx, status);
2191#elif PYLONG_BITS_IN_DIGIT == 15
2192    mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2193                    ctx, status);
2194#else
2195  #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
2196#endif
2197
2198    return dec;
2199}
2200
2201/* Return a new PyDecObject from a PyLongObject. Use the context for
2202   conversion. */
2203static PyObject *
2204PyDecType_FromLong(PyTypeObject *type, const PyObject *v, PyObject *context)
2205{
2206    PyObject *dec;
2207    uint32_t status = 0;
2208
2209    if (!PyLong_Check(v)) {
2210        PyErr_SetString(PyExc_TypeError, "argument must be an integer");
2211        return NULL;
2212    }
2213
2214    dec = dec_from_long(type, v, CTX(context), &status);
2215    if (dec == NULL) {
2216        return NULL;
2217    }
2218
2219    if (dec_addstatus(context, status)) {
2220        Py_DECREF(dec);
2221        return NULL;
2222    }
2223
2224    return dec;
2225}
2226
2227/* Return a new PyDecObject from a PyLongObject. Use a maximum context
2228   for conversion. If the conversion is not exact, set InvalidOperation. */
2229static PyObject *
2230PyDecType_FromLongExact(PyTypeObject *type, const PyObject *v,
2231                        PyObject *context)
2232{
2233    PyObject *dec;
2234    uint32_t status = 0;
2235    mpd_context_t maxctx;
2236
2237    if (!PyLong_Check(v)) {
2238        PyErr_SetString(PyExc_TypeError, "argument must be an integer");
2239        return NULL;
2240    }
2241
2242    mpd_maxcontext(&maxctx);
2243    dec = dec_from_long(type, v, &maxctx, &status);
2244    if (dec == NULL) {
2245        return NULL;
2246    }
2247
2248    if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
2249        /* we want exact results */
2250        mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
2251    }
2252    status &= MPD_Errors;
2253    if (dec_addstatus(context, status)) {
2254        Py_DECREF(dec);
2255        return NULL;
2256    }
2257
2258    return dec;
2259}
2260
2261/* External C-API functions */
2262static binaryfunc _py_long_multiply;
2263static binaryfunc _py_long_floor_divide;
2264static ternaryfunc _py_long_power;
2265static unaryfunc _py_float_abs;
2266static PyCFunction _py_long_bit_length;
2267static PyCFunction _py_float_as_integer_ratio;
2268
2269/* Return a PyDecObject or a subtype from a PyFloatObject.
2270   Conversion is exact. */
2271static PyObject *
2272PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v,
2273                         PyObject *context)
2274{
2275    PyObject *dec, *tmp;
2276    PyObject *n, *d, *n_d;
2277    mpd_ssize_t k;
2278    double x;
2279    int sign;
2280    mpd_t *d1, *d2;
2281    uint32_t status = 0;
2282    mpd_context_t maxctx;
2283
2284
2285    assert(PyType_IsSubtype(type, &PyDec_Type));
2286
2287    if (PyLong_Check(v)) {
2288        return PyDecType_FromLongExact(type, v, context);
2289    }
2290    if (!PyFloat_Check(v)) {
2291        PyErr_SetString(PyExc_TypeError,
2292            "argument must be int or float");
2293        return NULL;
2294    }
2295
2296    x = PyFloat_AsDouble(v);
2297    if (x == -1.0 && PyErr_Occurred()) {
2298        return NULL;
2299    }
2300    sign = (copysign(1.0, x) == 1.0) ? 0 : 1;
2301
2302    if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
2303        dec = PyDecType_New(type);
2304        if (dec == NULL) {
2305            return NULL;
2306        }
2307        if (Py_IS_NAN(x)) {
2308            /* decimal.py calls repr(float(+-nan)),
2309             * which always gives a positive result. */
2310            mpd_setspecial(MPD(dec), MPD_POS, MPD_NAN);
2311        }
2312        else {
2313            mpd_setspecial(MPD(dec), sign, MPD_INF);
2314        }
2315        return dec;
2316    }
2317
2318    /* absolute value of the float */
2319    tmp = _py_float_abs(v);
2320    if (tmp == NULL) {
2321        return NULL;
2322    }
2323
2324    /* float as integer ratio: numerator/denominator */
2325    n_d = _py_float_as_integer_ratio(tmp, NULL);
2326    Py_DECREF(tmp);
2327    if (n_d == NULL) {
2328        return NULL;
2329    }
2330    n = PyTuple_GET_ITEM(n_d, 0);
2331    d = PyTuple_GET_ITEM(n_d, 1);
2332
2333    tmp = _py_long_bit_length(d, NULL);
2334    if (tmp == NULL) {
2335        Py_DECREF(n_d);
2336        return NULL;
2337    }
2338    k = PyLong_AsSsize_t(tmp);
2339    Py_DECREF(tmp);
2340    if (k == -1 && PyErr_Occurred()) {
2341        Py_DECREF(n_d);
2342        return NULL;
2343    }
2344    k--;
2345
2346    dec = PyDecType_FromLongExact(type, n, context);
2347    Py_DECREF(n_d);
2348    if (dec == NULL) {
2349        return NULL;
2350    }
2351
2352    d1 = mpd_qnew();
2353    if (d1 == NULL) {
2354        Py_DECREF(dec);
2355        PyErr_NoMemory();
2356        return NULL;
2357    }
2358    d2 = mpd_qnew();
2359    if (d2 == NULL) {
2360        mpd_del(d1);
2361        Py_DECREF(dec);
2362        PyErr_NoMemory();
2363        return NULL;
2364    }
2365
2366    mpd_maxcontext(&maxctx);
2367    mpd_qset_uint(d1, 5, &maxctx, &status);
2368    mpd_qset_ssize(d2, k, &maxctx, &status);
2369    mpd_qpow(d1, d1, d2, &maxctx, &status);
2370    if (dec_addstatus(context, status)) {
2371        mpd_del(d1);
2372        mpd_del(d2);
2373        Py_DECREF(dec);
2374        return NULL;
2375    }
2376
2377    /* result = n * 5**k */
2378    mpd_qmul(MPD(dec), MPD(dec), d1, &maxctx, &status);
2379    mpd_del(d1);
2380    mpd_del(d2);
2381    if (dec_addstatus(context, status)) {
2382        Py_DECREF(dec);
2383        return NULL;
2384    }
2385    /* result = +- n * 5**k * 10**-k */
2386    mpd_set_sign(MPD(dec), sign);
2387    MPD(dec)->exp = -k;
2388
2389    return dec;
2390}
2391
2392static PyObject *
2393PyDecType_FromFloat(PyTypeObject *type, PyObject *v,
2394                    PyObject *context)
2395{
2396    PyObject *dec;
2397    uint32_t status = 0;
2398
2399    dec = PyDecType_FromFloatExact(type, v, context);
2400    if (dec == NULL) {
2401        return NULL;
2402    }
2403
2404    mpd_qfinalize(MPD(dec), CTX(context), &status);
2405    if (dec_addstatus(context, status)) {
2406        Py_DECREF(dec);
2407        return NULL;
2408    }
2409
2410    return dec;
2411}
2412
2413/* Return a new PyDecObject or a subtype from a Decimal. */
2414static PyObject *
2415PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context)
2416{
2417    PyObject *dec;
2418    uint32_t status = 0;
2419
2420    if (type == &PyDec_Type && PyDec_CheckExact(v)) {
2421        Py_INCREF(v);
2422        return v;
2423    }
2424
2425    dec = PyDecType_New(type);
2426    if (dec == NULL) {
2427        return NULL;
2428    }
2429
2430    mpd_qcopy(MPD(dec), MPD(v), &status);
2431    if (dec_addstatus(context, status)) {
2432        Py_DECREF(dec);
2433        return NULL;
2434    }
2435
2436    return dec;
2437}
2438
2439static PyObject *
2440sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg)
2441{
2442    if (PyTuple_Check(v)) {
2443        Py_INCREF(v);
2444        return v;
2445    }
2446    if (PyList_Check(v)) {
2447        return PyList_AsTuple(v);
2448    }
2449
2450    PyErr_SetString(ex, mesg);
2451    return NULL;
2452}
2453
2454/* Return a new C string representation of a DecimalTuple. */
2455static char *
2456dectuple_as_str(PyObject *dectuple)
2457{
2458    PyObject *digits = NULL, *tmp;
2459    char *decstring = NULL;
2460    char sign_special[6];
2461    char *cp;
2462    long sign, l;
2463    mpd_ssize_t exp = 0;
2464    Py_ssize_t i, mem, tsize;
2465    int is_infinite = 0;
2466    int n;
2467
2468    assert(PyTuple_Check(dectuple));
2469
2470    if (PyTuple_Size(dectuple) != 3) {
2471        PyErr_SetString(PyExc_ValueError,
2472            "argument must be a sequence of length 3");
2473        goto error;
2474    }
2475
2476    /* sign */
2477    tmp = PyTuple_GET_ITEM(dectuple, 0);
2478    if (!PyLong_Check(tmp)) {
2479        PyErr_SetString(PyExc_ValueError,
2480            "sign must be an integer with the value 0 or 1");
2481        goto error;
2482    }
2483    sign = PyLong_AsLong(tmp);
2484    if (sign == -1 && PyErr_Occurred()) {
2485        goto error;
2486    }
2487    if (sign != 0 && sign != 1) {
2488        PyErr_SetString(PyExc_ValueError,
2489            "sign must be an integer with the value 0 or 1");
2490        goto error;
2491    }
2492    sign_special[0] = sign ? '-' : '+';
2493    sign_special[1] = '\0';
2494
2495    /* exponent or encoding for a special number */
2496    tmp = PyTuple_GET_ITEM(dectuple, 2);
2497    if (PyUnicode_Check(tmp)) {
2498        /* special */
2499        if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) {
2500            strcat(sign_special, "Inf");
2501            is_infinite = 1;
2502        }
2503        else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) {
2504            strcat(sign_special, "NaN");
2505        }
2506        else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) {
2507            strcat(sign_special, "sNaN");
2508        }
2509        else {
2510            PyErr_SetString(PyExc_ValueError,
2511                "string argument in the third position "
2512                "must be 'F', 'n' or 'N'");
2513            goto error;
2514        }
2515    }
2516    else {
2517        /* exponent */
2518        if (!PyLong_Check(tmp)) {
2519            PyErr_SetString(PyExc_ValueError,
2520                "exponent must be an integer");
2521            goto error;
2522        }
2523        exp = PyLong_AsSsize_t(tmp);
2524        if (exp == -1 && PyErr_Occurred()) {
2525            goto error;
2526        }
2527    }
2528
2529    /* coefficient */
2530    digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError,
2531                               "coefficient must be a tuple of digits");
2532    if (digits == NULL) {
2533        goto error;
2534    }
2535
2536    tsize = PyTuple_Size(digits);
2537    /* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */
2538    mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2;
2539    cp = decstring = PyMem_Malloc(mem);
2540    if (decstring == NULL) {
2541        PyErr_NoMemory();
2542        goto error;
2543    }
2544
2545    n = snprintf(cp, mem, "%s", sign_special);
2546    if (n < 0 || n >= mem) {
2547        PyErr_SetString(PyExc_RuntimeError,
2548            "internal error in dec_sequence_as_str");
2549        goto error;
2550    }
2551    cp += n;
2552
2553    if (tsize == 0 && sign_special[1] == '\0') {
2554        /* empty tuple: zero coefficient, except for special numbers */
2555        *cp++ = '0';
2556    }
2557    for (i = 0; i < tsize; i++) {
2558        tmp = PyTuple_GET_ITEM(digits, i);
2559        if (!PyLong_Check(tmp)) {
2560            PyErr_SetString(PyExc_ValueError,
2561                "coefficient must be a tuple of digits");
2562            goto error;
2563        }
2564        l = PyLong_AsLong(tmp);
2565        if (l == -1 && PyErr_Occurred()) {
2566            goto error;
2567        }
2568        if (l < 0 || l > 9) {
2569            PyErr_SetString(PyExc_ValueError,
2570                "coefficient must be a tuple of digits");
2571            goto error;
2572        }
2573        if (is_infinite) {
2574            /* accept but ignore any well-formed coefficient for compatibility
2575               with decimal.py */
2576            continue;
2577        }
2578        *cp++ = (char)l + '0';
2579    }
2580    *cp = '\0';
2581
2582    if (sign_special[1] == '\0') {
2583        /* not a special number */
2584        *cp++ = 'E';
2585        n = snprintf(cp, MPD_EXPDIGITS+2, "%" PRI_mpd_ssize_t, exp);
2586        if (n < 0 || n >= MPD_EXPDIGITS+2) {
2587            PyErr_SetString(PyExc_RuntimeError,
2588                "internal error in dec_sequence_as_str");
2589            goto error;
2590        }
2591    }
2592
2593    Py_XDECREF(digits);
2594    return decstring;
2595
2596
2597error:
2598    Py_XDECREF(digits);
2599    if (decstring) PyMem_Free(decstring);
2600    return NULL;
2601}
2602
2603/* Currently accepts tuples and lists. */
2604static PyObject *
2605PyDecType_FromSequence(PyTypeObject *type, PyObject *v,
2606                       PyObject *context)
2607{
2608    PyObject *dectuple;
2609    PyObject *dec;
2610    char *s;
2611
2612    dectuple = sequence_as_tuple(v, PyExc_TypeError,
2613                                 "argument must be a tuple or list");
2614    if (dectuple == NULL) {
2615        return NULL;
2616    }
2617
2618    s = dectuple_as_str(dectuple);
2619    Py_DECREF(dectuple);
2620    if (s == NULL) {
2621        return NULL;
2622    }
2623
2624    dec = PyDecType_FromCString(type, s, context);
2625
2626    PyMem_Free(s);
2627    return dec;
2628}
2629
2630/* Currently accepts tuples and lists. */
2631static PyObject *
2632PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
2633                            PyObject *context)
2634{
2635    PyObject *dectuple;
2636    PyObject *dec;
2637    char *s;
2638
2639    dectuple = sequence_as_tuple(v, PyExc_TypeError,
2640                   "argument must be a tuple or list");
2641    if (dectuple == NULL) {
2642        return NULL;
2643    }
2644
2645    s = dectuple_as_str(dectuple);
2646    Py_DECREF(dectuple);
2647    if (s == NULL) {
2648        return NULL;
2649    }
2650
2651    dec = PyDecType_FromCStringExact(type, s, context);
2652
2653    PyMem_Free(s);
2654    return dec;
2655}
2656
2657#define PyDec_FromCString(str, context) \
2658        PyDecType_FromCString(&PyDec_Type, str, context)
2659#define PyDec_FromCStringExact(str, context) \
2660        PyDecType_FromCStringExact(&PyDec_Type, str, context)
2661
2662#define PyDec_FromUnicode(unicode, context) \
2663        PyDecType_FromUnicode(&PyDec_Type, unicode, context)
2664#define PyDec_FromUnicodeExact(unicode, context) \
2665        PyDecType_FromUnicodeExact(&PyDec_Type, unicode, context)
2666#define PyDec_FromUnicodeExactWS(unicode, context) \
2667        PyDecType_FromUnicodeExactWS(&PyDec_Type, unicode, context)
2668
2669#define PyDec_FromSsize(v, context) \
2670        PyDecType_FromSsize(&PyDec_Type, v, context)
2671#define PyDec_FromSsizeExact(v, context) \
2672        PyDecType_FromSsizeExact(&PyDec_Type, v, context)
2673
2674#define PyDec_FromLong(pylong, context) \
2675        PyDecType_FromLong(&PyDec_Type, pylong, context)
2676#define PyDec_FromLongExact(pylong, context) \
2677        PyDecType_FromLongExact(&PyDec_Type, pylong, context)
2678
2679#define PyDec_FromFloat(pyfloat, context) \
2680        PyDecType_FromFloat(&PyDec_Type, pyfloat, context)
2681#define PyDec_FromFloatExact(pyfloat, context) \
2682        PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context)
2683
2684#define PyDec_FromSequence(sequence, context) \
2685        PyDecType_FromSequence(&PyDec_Type, sequence, context)
2686#define PyDec_FromSequenceExact(sequence, context) \
2687        PyDecType_FromSequenceExact(&PyDec_Type, sequence, context)
2688
2689/* class method */
2690static PyObject *
2691dec_from_float(PyObject *type, PyObject *pyfloat)
2692{
2693    PyObject *context;
2694    PyObject *result;
2695
2696    CURRENT_CONTEXT(context);
2697    result = PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context);
2698    if (type != (PyObject *)&PyDec_Type && result != NULL) {
2699        Py_SETREF(result, PyObject_CallFunctionObjArgs(type, result, NULL));
2700    }
2701
2702    return result;
2703}
2704
2705/* create_decimal_from_float */
2706static PyObject *
2707ctx_from_float(PyObject *context, PyObject *v)
2708{
2709    return PyDec_FromFloat(v, context);
2710}
2711
2712/* Apply the context to the input operand. Return a new PyDecObject. */
2713static PyObject *
2714dec_apply(PyObject *v, PyObject *context)
2715{
2716    PyObject *result;
2717    uint32_t status = 0;
2718
2719    result = dec_alloc();
2720    if (result == NULL) {
2721        return NULL;
2722    }
2723
2724    mpd_qcopy(MPD(result), MPD(v), &status);
2725    if (dec_addstatus(context, status)) {
2726        Py_DECREF(result);
2727        return NULL;
2728    }
2729
2730    mpd_qfinalize(MPD(result), CTX(context), &status);
2731    if (dec_addstatus(context, status)) {
2732        Py_DECREF(result);
2733        return NULL;
2734    }
2735
2736    return result;
2737}
2738
2739/* 'v' can have any type accepted by the Decimal constructor. Attempt
2740   an exact conversion. If the result does not meet the restrictions
2741   for an mpd_t, fail with InvalidOperation. */
2742static PyObject *
2743PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context)
2744{
2745    if (v == NULL) {
2746        return PyDecType_FromSsizeExact(type, 0, context);
2747    }
2748    else if (PyDec_Check(v)) {
2749        return PyDecType_FromDecimalExact(type, v, context);
2750    }
2751    else if (PyUnicode_Check(v)) {
2752        return PyDecType_FromUnicodeExactWS(type, v, context);
2753    }
2754    else if (PyLong_Check(v)) {
2755        return PyDecType_FromLongExact(type, v, context);
2756    }
2757    else if (PyTuple_Check(v) || PyList_Check(v)) {
2758        return PyDecType_FromSequenceExact(type, v, context);
2759    }
2760    else if (PyFloat_Check(v)) {
2761        if (dec_addstatus(context, MPD_Float_operation)) {
2762            return NULL;
2763        }
2764        return PyDecType_FromFloatExact(type, v, context);
2765    }
2766    else {
2767        PyErr_Format(PyExc_TypeError,
2768            "conversion from %s to Decimal is not supported",
2769            Py_TYPE(v)->tp_name);
2770        return NULL;
2771    }
2772}
2773
2774/* The context is used during conversion. This function is the
2775   equivalent of context.create_decimal(). */
2776static PyObject *
2777PyDec_FromObject(PyObject *v, PyObject *context)
2778{
2779    if (v == NULL) {
2780        return PyDec_FromSsize(0, context);
2781    }
2782    else if (PyDec_Check(v)) {
2783        mpd_context_t *ctx = CTX(context);
2784        if (mpd_isnan(MPD(v)) &&
2785            MPD(v)->digits > ctx->prec - ctx->clamp) {
2786            /* Special case: too many NaN payload digits */
2787            PyObject *result;
2788            if (dec_addstatus(context, MPD_Conversion_syntax)) {
2789                return NULL;
2790            }
2791            result = dec_alloc();
2792            if (result == NULL) {
2793                return NULL;
2794            }
2795            mpd_setspecial(MPD(result), MPD_POS, MPD_NAN);
2796            return result;
2797        }
2798        return dec_apply(v, context);
2799    }
2800    else if (PyUnicode_Check(v)) {
2801        return PyDec_FromUnicode(v, context);
2802    }
2803    else if (PyLong_Check(v)) {
2804        return PyDec_FromLong(v, context);
2805    }
2806    else if (PyTuple_Check(v) || PyList_Check(v)) {
2807        return PyDec_FromSequence(v, context);
2808    }
2809    else if (PyFloat_Check(v)) {
2810        if (dec_addstatus(context, MPD_Float_operation)) {
2811            return NULL;
2812        }
2813        return PyDec_FromFloat(v, context);
2814    }
2815    else {
2816        PyErr_Format(PyExc_TypeError,
2817            "conversion from %s to Decimal is not supported",
2818            Py_TYPE(v)->tp_name);
2819        return NULL;
2820    }
2821}
2822
2823static PyObject *
2824dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2825{
2826    static char *kwlist[] = {"value", "context", NULL};
2827    PyObject *v = NULL;
2828    PyObject *context = Py_None;
2829
2830    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
2831                                     &v, &context)) {
2832        return NULL;
2833    }
2834    CONTEXT_CHECK_VA(context);
2835
2836    return PyDecType_FromObjectExact(type, v, context);
2837}
2838
2839static PyObject *
2840ctx_create_decimal(PyObject *context, PyObject *args)
2841{
2842    PyObject *v = NULL;
2843
2844    if (!PyArg_ParseTuple(args, "|O", &v)) {
2845        return NULL;
2846    }
2847
2848    return PyDec_FromObject(v, context);
2849}
2850
2851
2852/******************************************************************************/
2853/*                        Implicit conversions to Decimal                     */
2854/******************************************************************************/
2855
2856/* Try to convert PyObject v to a new PyDecObject conv. If the conversion
2857   fails, set conv to NULL (exception is set). If the conversion is not
2858   implemented, set conv to Py_NotImplemented. */
2859#define NOT_IMPL 0
2860#define TYPE_ERR 1
2861Py_LOCAL_INLINE(int)
2862convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context)
2863{
2864
2865    if (PyDec_Check(v)) {
2866        *conv = v;
2867        Py_INCREF(v);
2868        return 1;
2869    }
2870    if (PyLong_Check(v)) {
2871        *conv = PyDec_FromLongExact(v, context);
2872        if (*conv == NULL) {
2873            return 0;
2874        }
2875        return 1;
2876    }
2877
2878    if (type_err) {
2879        PyErr_Format(PyExc_TypeError,
2880            "conversion from %s to Decimal is not supported",
2881            Py_TYPE(v)->tp_name);
2882    }
2883    else {
2884        Py_INCREF(Py_NotImplemented);
2885        *conv = Py_NotImplemented;
2886    }
2887    return 0;
2888}
2889
2890/* Return NotImplemented for unsupported types. */
2891#define CONVERT_OP(a, v, context) \
2892    if (!convert_op(NOT_IMPL, a, v, context)) { \
2893        return *(a);                            \
2894    }
2895
2896#define CONVERT_BINOP(a, b, v, w, context) \
2897    if (!convert_op(NOT_IMPL, a, v, context)) { \
2898        return *(a);                            \
2899    }                                           \
2900    if (!convert_op(NOT_IMPL, b, w, context)) { \
2901        Py_DECREF(*(a));                        \
2902        return *(b);                            \
2903    }
2904
2905#define CONVERT_TERNOP(a, b, c, v, w, x, context) \
2906    if (!convert_op(NOT_IMPL, a, v, context)) {   \
2907        return *(a);                              \
2908    }                                             \
2909    if (!convert_op(NOT_IMPL, b, w, context)) {   \
2910        Py_DECREF(*(a));                          \
2911        return *(b);                              \
2912    }                                             \
2913    if (!convert_op(NOT_IMPL, c, x, context)) {   \
2914        Py_DECREF(*(a));                          \
2915        Py_DECREF(*(b));                          \
2916        return *(c);                              \
2917    }
2918
2919/* Raise TypeError for unsupported types. */
2920#define CONVERT_OP_RAISE(a, v, context) \
2921    if (!convert_op(TYPE_ERR, a, v, context)) { \
2922        return NULL;                            \
2923    }
2924
2925#define CONVERT_BINOP_RAISE(a, b, v, w, context) \
2926    if (!convert_op(TYPE_ERR, a, v, context)) {  \
2927        return NULL;                             \
2928    }                                            \
2929    if (!convert_op(TYPE_ERR, b, w, context)) {  \
2930        Py_DECREF(*(a));                         \
2931        return NULL;                             \
2932    }
2933
2934#define CONVERT_TERNOP_RAISE(a, b, c, v, w, x, context) \
2935    if (!convert_op(TYPE_ERR, a, v, context)) {         \
2936        return NULL;                                    \
2937    }                                                   \
2938    if (!convert_op(TYPE_ERR, b, w, context)) {         \
2939        Py_DECREF(*(a));                                \
2940        return NULL;                                    \
2941    }                                                   \
2942    if (!convert_op(TYPE_ERR, c, x, context)) {         \
2943        Py_DECREF(*(a));                                \
2944        Py_DECREF(*(b));                                \
2945        return NULL;                                    \
2946    }
2947
2948
2949/******************************************************************************/
2950/*              Implicit conversions to Decimal for comparison                */
2951/******************************************************************************/
2952
2953/* Convert rationals for comparison */
2954static PyObject *Rational = NULL;
2955static PyObject *
2956multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context)
2957{
2958    PyObject *result;
2959    PyObject *tmp = NULL;
2960    PyObject *denom = NULL;
2961    uint32_t status = 0;
2962    mpd_context_t maxctx;
2963    mpd_ssize_t exp;
2964    mpd_t *vv;
2965
2966    /* v is not special, r is a rational */
2967    tmp = PyObject_GetAttrString(r, "denominator");
2968    if (tmp == NULL) {
2969        return NULL;
2970    }
2971    denom = PyDec_FromLongExact(tmp, context);
2972    Py_DECREF(tmp);
2973    if (denom == NULL) {
2974        return NULL;
2975    }
2976
2977    vv = mpd_qncopy(MPD(v));
2978    if (vv == NULL) {
2979        Py_DECREF(denom);
2980        PyErr_NoMemory();
2981        return NULL;
2982    }
2983    result = dec_alloc();
2984    if (result == NULL) {
2985        Py_DECREF(denom);
2986        mpd_del(vv);
2987        return NULL;
2988    }
2989
2990    mpd_maxcontext(&maxctx);
2991    /* Prevent Overflow in the following multiplication. The result of
2992       the multiplication is only used in mpd_qcmp, which can handle
2993       values that are technically out of bounds, like (for 32-bit)
2994       99999999999999999999...99999999e+425000000. */
2995    exp = vv->exp;
2996    vv->exp = 0;
2997    mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status);
2998    MPD(result)->exp = exp;
2999
3000    Py_DECREF(denom);
3001    mpd_del(vv);
3002    /* If any status has been accumulated during the multiplication,
3003       the result is invalid. This is very unlikely, since even the
3004       32-bit version supports 425000000 digits. */
3005    if (status) {
3006        PyErr_SetString(PyExc_ValueError,
3007            "exact conversion for comparison failed");
3008        Py_DECREF(result);
3009        return NULL;
3010    }
3011
3012    return result;
3013}
3014
3015static PyObject *
3016numerator_as_decimal(PyObject *r, PyObject *context)
3017{
3018    PyObject *tmp, *num;
3019
3020    tmp = PyObject_GetAttrString(r, "numerator");
3021    if (tmp == NULL) {
3022        return NULL;
3023    }
3024
3025    num = PyDec_FromLongExact(tmp, context);
3026    Py_DECREF(tmp);
3027    return num;
3028}
3029
3030/* Convert v and w for comparison. v is a Decimal. If w is a Rational, both
3031   v and w have to be transformed. Return 1 for success, with new references
3032   to the converted objects in vcmp and wcmp. Return 0 for failure. In that
3033   case wcmp is either NULL or Py_NotImplemented (new reference) and vcmp
3034   is undefined. */
3035static int
3036convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w,
3037               int op, PyObject *context)
3038{
3039    mpd_context_t *ctx = CTX(context);
3040
3041    *vcmp = v;
3042
3043    if (PyDec_Check(w)) {
3044        Py_INCREF(w);
3045        *wcmp = w;
3046    }
3047    else if (PyLong_Check(w)) {
3048        *wcmp = PyDec_FromLongExact(w, context);
3049    }
3050    else if (PyFloat_Check(w)) {
3051        if (op != Py_EQ && op != Py_NE &&
3052            dec_addstatus(context, MPD_Float_operation)) {
3053            *wcmp = NULL;
3054        }
3055        else {
3056            ctx->status |= MPD_Float_operation;
3057            *wcmp = PyDec_FromFloatExact(w, context);
3058        }
3059    }
3060    else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) {
3061        Py_complex c = PyComplex_AsCComplex(w);
3062        if (c.real == -1.0 && PyErr_Occurred()) {
3063            *wcmp = NULL;
3064        }
3065        else if (c.imag == 0.0) {
3066            PyObject *tmp = PyFloat_FromDouble(c.real);
3067            if (tmp == NULL) {
3068                *wcmp = NULL;
3069            }
3070            else {
3071                ctx->status |= MPD_Float_operation;
3072                *wcmp = PyDec_FromFloatExact(tmp, context);
3073                Py_DECREF(tmp);
3074            }
3075        }
3076        else {
3077            Py_INCREF(Py_NotImplemented);
3078            *wcmp = Py_NotImplemented;
3079        }
3080    }
3081    else {
3082        int is_rational = PyObject_IsInstance(w, Rational);
3083        if (is_rational < 0) {
3084            *wcmp = NULL;
3085        }
3086        else if (is_rational > 0) {
3087            *wcmp = numerator_as_decimal(w, context);
3088            if (*wcmp && !mpd_isspecial(MPD(v))) {
3089                *vcmp = multiply_by_denominator(v, w, context);
3090                if (*vcmp == NULL) {
3091                    Py_CLEAR(*wcmp);
3092                }
3093            }
3094        }
3095        else {
3096            Py_INCREF(Py_NotImplemented);
3097            *wcmp = Py_NotImplemented;
3098        }
3099    }
3100
3101    if (*wcmp == NULL || *wcmp == Py_NotImplemented) {
3102        return 0;
3103    }
3104    if (*vcmp == v) {
3105        Py_INCREF(v);
3106    }
3107    return 1;
3108}
3109
3110#define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \
3111    if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) {  \
3112        return *(wcmp);                                \
3113    }                                                  \
3114
3115
3116/******************************************************************************/
3117/*                          Conversions from decimal                          */
3118/******************************************************************************/
3119
3120static PyObject *
3121unicode_fromascii(const char *s, Py_ssize_t size)
3122{
3123    PyObject *res;
3124
3125    res = PyUnicode_New(size, 127);
3126    if (res == NULL) {
3127        return NULL;
3128    }
3129
3130    memcpy(PyUnicode_1BYTE_DATA(res), s, size);
3131    return res;
3132}
3133
3134/* PyDecObject as a string. The default module context is only used for
3135   the value of 'capitals'. */
3136static PyObject *
3137dec_str(PyObject *dec)
3138{
3139    PyObject *res, *context;
3140    mpd_ssize_t size;
3141    char *cp;
3142
3143    CURRENT_CONTEXT(context);
3144    size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context));
3145    if (size < 0) {
3146        PyErr_NoMemory();
3147        return NULL;
3148    }
3149
3150    res = unicode_fromascii(cp, size);
3151    mpd_free(cp);
3152    return res;
3153}
3154
3155/* Representation of a PyDecObject. */
3156static PyObject *
3157dec_repr(PyObject *dec)
3158{
3159    PyObject *res, *context;
3160    char *cp;
3161
3162    CURRENT_CONTEXT(context);
3163    cp = mpd_to_sci(MPD(dec), CtxCaps(context));
3164    if (cp == NULL) {
3165        PyErr_NoMemory();
3166        return NULL;
3167    }
3168
3169    res = PyUnicode_FromFormat("Decimal('%s')", cp);
3170    mpd_free(cp);
3171    return res;
3172}
3173
3174/* Return a duplicate of src, copy embedded null characters. */
3175static char *
3176dec_strdup(const char *src, Py_ssize_t size)
3177{
3178    char *dest = PyMem_Malloc(size+1);
3179    if (dest == NULL) {
3180        PyErr_NoMemory();
3181        return NULL;
3182    }
3183
3184    memcpy(dest, src, size);
3185    dest[size] = '\0';
3186    return dest;
3187}
3188
3189static void
3190dec_replace_fillchar(char *dest)
3191{
3192     while (*dest != '\0') {
3193         if (*dest == '\xff') *dest = '\0';
3194         dest++;
3195     }
3196}
3197
3198/* Convert decimal_point or thousands_sep, which may be multibyte or in
3199   the range [128, 255], to a UTF8 string. */
3200static PyObject *
3201dotsep_as_utf8(const char *s)
3202{
3203    PyObject *utf8;
3204    PyObject *tmp;
3205    wchar_t buf[2];
3206    size_t n;
3207
3208    n = mbstowcs(buf, s, 2);
3209    if (n != 1) { /* Issue #7442 */
3210        PyErr_SetString(PyExc_ValueError,
3211            "invalid decimal point or unsupported "
3212            "combination of LC_CTYPE and LC_NUMERIC");
3213        return NULL;
3214    }
3215    tmp = PyUnicode_FromWideChar(buf, n);
3216    if (tmp == NULL) {
3217        return NULL;
3218    }
3219    utf8 = PyUnicode_AsUTF8String(tmp);
3220    Py_DECREF(tmp);
3221    return utf8;
3222}
3223
3224/* copy of libmpdec _mpd_round() */
3225static void
3226_mpd_round(mpd_t *result, const mpd_t *a, mpd_ssize_t prec,
3227           const mpd_context_t *ctx, uint32_t *status)
3228{
3229    mpd_ssize_t exp = a->exp + a->digits - prec;
3230
3231    if (prec <= 0) {
3232        mpd_seterror(result, MPD_Invalid_operation, status);
3233        return;
3234    }
3235    if (mpd_isspecial(a) || mpd_iszero(a)) {
3236        mpd_qcopy(result, a, status);
3237        return;
3238    }
3239
3240    mpd_qrescale_fmt(result, a, exp, ctx, status);
3241    if (result->digits > prec) {
3242        mpd_qrescale_fmt(result, result, exp+1, ctx, status);
3243    }
3244}
3245
3246/* Locate negative zero "z" option within a UTF-8 format spec string.
3247 * Returns pointer to "z", else NULL.
3248 * The portion of the spec we're working with is [[fill]align][sign][z] */
3249static const char *
3250format_spec_z_search(char const *fmt, Py_ssize_t size) {
3251    char const *pos = fmt;
3252    char const *fmt_end = fmt + size;
3253    /* skip over [[fill]align] (fill may be multi-byte character) */
3254    pos += 1;
3255    while (pos < fmt_end && *pos & 0x80) {
3256        pos += 1;
3257    }
3258    if (pos < fmt_end && strchr("<>=^", *pos) != NULL) {
3259        pos += 1;
3260    } else {
3261        /* fill not present-- skip over [align] */
3262        pos = fmt;
3263        if (pos < fmt_end && strchr("<>=^", *pos) != NULL) {
3264            pos += 1;
3265        }
3266    }
3267    /* skip over [sign] */
3268    if (pos < fmt_end && strchr("+- ", *pos) != NULL) {
3269        pos += 1;
3270    }
3271    return pos < fmt_end && *pos == 'z' ? pos : NULL;
3272}
3273
3274static int
3275dict_get_item_string(PyObject *dict, const char *key, PyObject **valueobj, const char **valuestr)
3276{
3277    *valueobj = NULL;
3278    PyObject *keyobj = PyUnicode_FromString(key);
3279    if (keyobj == NULL) {
3280        return -1;
3281    }
3282    PyObject *value = PyDict_GetItemWithError(dict, keyobj);
3283    Py_DECREF(keyobj);
3284    if (value == NULL) {
3285        if (PyErr_Occurred()) {
3286            return -1;
3287        }
3288        return 0;
3289    }
3290    value = PyUnicode_AsUTF8String(value);
3291    if (value == NULL) {
3292        return -1;
3293    }
3294    *valueobj = value;
3295    *valuestr = PyBytes_AS_STRING(value);
3296    return 0;
3297}
3298
3299/* Formatted representation of a PyDecObject. */
3300static PyObject *
3301dec_format(PyObject *dec, PyObject *args)
3302{
3303    PyObject *result = NULL;
3304    PyObject *override = NULL;
3305    PyObject *dot = NULL;
3306    PyObject *sep = NULL;
3307    PyObject *grouping = NULL;
3308    PyObject *fmtarg;
3309    PyObject *context;
3310    mpd_spec_t spec;
3311    char const *fmt;
3312    char *fmt_copy = NULL;
3313    char *decstring = NULL;
3314    uint32_t status = 0;
3315    int replace_fillchar = 0;
3316    int no_neg_0 = 0;
3317    Py_ssize_t size;
3318    mpd_t *mpd = MPD(dec);
3319    mpd_uint_t dt[MPD_MINALLOC_MAX];
3320    mpd_t tmp = {MPD_STATIC|MPD_STATIC_DATA,0,0,0,MPD_MINALLOC_MAX,dt};
3321
3322
3323    CURRENT_CONTEXT(context);
3324    if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) {
3325        return NULL;
3326    }
3327
3328    if (PyUnicode_Check(fmtarg)) {
3329        fmt = PyUnicode_AsUTF8AndSize(fmtarg, &size);
3330        if (fmt == NULL) {
3331            return NULL;
3332        }
3333        /* NOTE: If https://github.com/python/cpython/pull/29438 lands, the
3334         *   format string manipulation below can be eliminated by enhancing
3335         *   the forked mpd_parse_fmt_str(). */
3336        if (size > 0 && fmt[0] == '\0') {
3337            /* NUL fill character: must be replaced with a valid UTF-8 char
3338               before calling mpd_parse_fmt_str(). */
3339            replace_fillchar = 1;
3340            fmt = fmt_copy = dec_strdup(fmt, size);
3341            if (fmt_copy == NULL) {
3342                return NULL;
3343            }
3344            fmt_copy[0] = '_';
3345        }
3346        /* Strip 'z' option, which isn't understood by mpd_parse_fmt_str().
3347         * NOTE: fmt is always null terminated by PyUnicode_AsUTF8AndSize() */
3348        char const *z_position = format_spec_z_search(fmt, size);
3349        if (z_position != NULL) {
3350            no_neg_0 = 1;
3351            size_t z_index = z_position - fmt;
3352            if (fmt_copy == NULL) {
3353                fmt = fmt_copy = dec_strdup(fmt, size);
3354                if (fmt_copy == NULL) {
3355                    return NULL;
3356                }
3357            }
3358            /* Shift characters (including null terminator) left,
3359               overwriting the 'z' option. */
3360            memmove(fmt_copy + z_index, fmt_copy + z_index + 1, size - z_index);
3361            size -= 1;
3362        }
3363    }
3364    else {
3365        PyErr_SetString(PyExc_TypeError,
3366            "format arg must be str");
3367        return NULL;
3368    }
3369
3370    if (!mpd_parse_fmt_str(&spec, fmt, CtxCaps(context))) {
3371        PyErr_SetString(PyExc_ValueError,
3372            "invalid format string");
3373        goto finish;
3374    }
3375    if (replace_fillchar) {
3376        /* In order to avoid clobbering parts of UTF-8 thousands separators or
3377           decimal points when the substitution is reversed later, the actual
3378           placeholder must be an invalid UTF-8 byte. */
3379        spec.fill[0] = '\xff';
3380        spec.fill[1] = '\0';
3381    }
3382
3383    if (override) {
3384        /* Values for decimal_point, thousands_sep and grouping can
3385           be explicitly specified in the override dict. These values
3386           take precedence over the values obtained from localeconv()
3387           in mpd_parse_fmt_str(). The feature is not documented and
3388           is only used in test_decimal. */
3389        if (!PyDict_Check(override)) {
3390            PyErr_SetString(PyExc_TypeError,
3391                "optional argument must be a dict");
3392            goto finish;
3393        }
3394        if (dict_get_item_string(override, "decimal_point", &dot, &spec.dot) ||
3395            dict_get_item_string(override, "thousands_sep", &sep, &spec.sep) ||
3396            dict_get_item_string(override, "grouping", &grouping, &spec.grouping))
3397        {
3398            goto finish;
3399        }
3400        if (mpd_validate_lconv(&spec) < 0) {
3401            PyErr_SetString(PyExc_ValueError,
3402                "invalid override dict");
3403            goto finish;
3404        }
3405    }
3406    else {
3407        size_t n = strlen(spec.dot);
3408        if (n > 1 || (n == 1 && !isascii((unsigned char)spec.dot[0]))) {
3409            /* fix locale dependent non-ascii characters */
3410            dot = dotsep_as_utf8(spec.dot);
3411            if (dot == NULL) {
3412                goto finish;
3413            }
3414            spec.dot = PyBytes_AS_STRING(dot);
3415        }
3416        n = strlen(spec.sep);
3417        if (n > 1 || (n == 1 && !isascii((unsigned char)spec.sep[0]))) {
3418            /* fix locale dependent non-ascii characters */
3419            sep = dotsep_as_utf8(spec.sep);
3420            if (sep == NULL) {
3421                goto finish;
3422            }
3423            spec.sep = PyBytes_AS_STRING(sep);
3424        }
3425    }
3426
3427    if (no_neg_0 && mpd_isnegative(mpd) && !mpd_isspecial(mpd)) {
3428        /* Round into a temporary (carefully mirroring the rounding
3429           of mpd_qformat_spec()), and check if the result is negative zero.
3430           If so, clear the sign and format the resulting positive zero. */
3431        mpd_ssize_t prec;
3432        mpd_qcopy(&tmp, mpd, &status);
3433        if (spec.prec >= 0) {
3434            switch (spec.type) {
3435              case 'f':
3436                  mpd_qrescale(&tmp, &tmp, -spec.prec, CTX(context), &status);
3437                  break;
3438              case '%':
3439                  tmp.exp += 2;
3440                  mpd_qrescale(&tmp, &tmp, -spec.prec, CTX(context), &status);
3441                  break;
3442              case 'g':
3443                  prec = (spec.prec == 0) ? 1 : spec.prec;
3444                  if (tmp.digits > prec) {
3445                      _mpd_round(&tmp, &tmp, prec, CTX(context), &status);
3446                  }
3447                  break;
3448              case 'e':
3449                  if (!mpd_iszero(&tmp)) {
3450                      _mpd_round(&tmp, &tmp, spec.prec+1, CTX(context), &status);
3451                  }
3452                  break;
3453            }
3454        }
3455        if (status & MPD_Errors) {
3456            PyErr_SetString(PyExc_ValueError, "unexpected error when rounding");
3457            goto finish;
3458        }
3459        if (mpd_iszero(&tmp)) {
3460            mpd_set_positive(&tmp);
3461            mpd = &tmp;
3462        }
3463    }
3464
3465    decstring = mpd_qformat_spec(mpd, &spec, CTX(context), &status);
3466    if (decstring == NULL) {
3467        if (status & MPD_Malloc_error) {
3468            PyErr_NoMemory();
3469        }
3470        else {
3471            PyErr_SetString(PyExc_ValueError,
3472                "format specification exceeds internal limits of _decimal");
3473        }
3474        goto finish;
3475    }
3476    size = strlen(decstring);
3477    if (replace_fillchar) {
3478        dec_replace_fillchar(decstring);
3479    }
3480
3481    result = PyUnicode_DecodeUTF8(decstring, size, NULL);
3482
3483
3484finish:
3485    Py_XDECREF(grouping);
3486    Py_XDECREF(sep);
3487    Py_XDECREF(dot);
3488    if (fmt_copy) PyMem_Free(fmt_copy);
3489    if (decstring) mpd_free(decstring);
3490    return result;
3491}
3492
3493/* Return a PyLongObject from a PyDecObject, using the specified rounding
3494 * mode. The context precision is not observed. */
3495static PyObject *
3496dec_as_long(PyObject *dec, PyObject *context, int round)
3497{
3498    PyLongObject *pylong;
3499    digit *ob_digit;
3500    size_t n;
3501    Py_ssize_t i;
3502    mpd_t *x;
3503    mpd_context_t workctx;
3504    uint32_t status = 0;
3505
3506    if (mpd_isspecial(MPD(dec))) {
3507        if (mpd_isnan(MPD(dec))) {
3508            PyErr_SetString(PyExc_ValueError,
3509                "cannot convert NaN to integer");
3510        }
3511        else {
3512            PyErr_SetString(PyExc_OverflowError,
3513                "cannot convert Infinity to integer");
3514        }
3515        return NULL;
3516    }
3517
3518    x = mpd_qnew();
3519    if (x == NULL) {
3520        PyErr_NoMemory();
3521        return NULL;
3522    }
3523    workctx = *CTX(context);
3524    workctx.round = round;
3525    mpd_qround_to_int(x, MPD(dec), &workctx, &status);
3526    if (dec_addstatus(context, status)) {
3527        mpd_del(x);
3528        return NULL;
3529    }
3530
3531    status = 0;
3532    ob_digit = NULL;
3533#if PYLONG_BITS_IN_DIGIT == 30
3534    n = mpd_qexport_u32(&ob_digit, 0, PyLong_BASE, x, &status);
3535#elif PYLONG_BITS_IN_DIGIT == 15
3536    n = mpd_qexport_u16(&ob_digit, 0, PyLong_BASE, x, &status);
3537#else
3538    #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
3539#endif
3540
3541    if (n == SIZE_MAX) {
3542        PyErr_NoMemory();
3543        mpd_del(x);
3544        return NULL;
3545    }
3546
3547    if (n == 1) {
3548        sdigit val = mpd_arith_sign(x) * ob_digit[0];
3549        mpd_free(ob_digit);
3550        mpd_del(x);
3551        return PyLong_FromLong(val);
3552    }
3553
3554    assert(n > 0);
3555    pylong = _PyLong_New(n);
3556    if (pylong == NULL) {
3557        mpd_free(ob_digit);
3558        mpd_del(x);
3559        return NULL;
3560    }
3561
3562    memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit));
3563    mpd_free(ob_digit);
3564
3565    i = n;
3566    while ((i > 0) && (pylong->ob_digit[i-1] == 0)) {
3567        i--;
3568    }
3569
3570    Py_SET_SIZE(pylong, i);
3571    if (mpd_isnegative(x) && !mpd_iszero(x)) {
3572        Py_SET_SIZE(pylong, -i);
3573    }
3574
3575    mpd_del(x);
3576    return (PyObject *) pylong;
3577}
3578
3579/* Convert a Decimal to its exact integer ratio representation. */
3580static PyObject *
3581dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED)
3582{
3583    PyObject *numerator = NULL;
3584    PyObject *denominator = NULL;
3585    PyObject *exponent = NULL;
3586    PyObject *result = NULL;
3587    PyObject *tmp;
3588    mpd_ssize_t exp;
3589    PyObject *context;
3590    uint32_t status = 0;
3591
3592    if (mpd_isspecial(MPD(self))) {
3593        if (mpd_isnan(MPD(self))) {
3594            PyErr_SetString(PyExc_ValueError,
3595                "cannot convert NaN to integer ratio");
3596        }
3597        else {
3598            PyErr_SetString(PyExc_OverflowError,
3599                "cannot convert Infinity to integer ratio");
3600        }
3601        return NULL;
3602    }
3603
3604    CURRENT_CONTEXT(context);
3605
3606    tmp = dec_alloc();
3607    if (tmp == NULL) {
3608        return NULL;
3609    }
3610
3611    if (!mpd_qcopy(MPD(tmp), MPD(self), &status)) {
3612        Py_DECREF(tmp);
3613        PyErr_NoMemory();
3614        return NULL;
3615    }
3616
3617    exp = mpd_iszero(MPD(tmp)) ? 0 : MPD(tmp)->exp;
3618    MPD(tmp)->exp = 0;
3619
3620    /* context and rounding are unused here: the conversion is exact */
3621    numerator = dec_as_long(tmp, context, MPD_ROUND_FLOOR);
3622    Py_DECREF(tmp);
3623    if (numerator == NULL) {
3624        goto error;
3625    }
3626
3627    exponent = PyLong_FromSsize_t(exp < 0 ? -exp : exp);
3628    if (exponent == NULL) {
3629        goto error;
3630    }
3631
3632    tmp = PyLong_FromLong(10);
3633    if (tmp == NULL) {
3634        goto error;
3635    }
3636
3637    Py_SETREF(exponent, _py_long_power(tmp, exponent, Py_None));
3638    Py_DECREF(tmp);
3639    if (exponent == NULL) {
3640        goto error;
3641    }
3642
3643    if (exp >= 0) {
3644        Py_SETREF(numerator, _py_long_multiply(numerator, exponent));
3645        if (numerator == NULL) {
3646            goto error;
3647        }
3648        denominator = PyLong_FromLong(1);
3649        if (denominator == NULL) {
3650            goto error;
3651        }
3652    }
3653    else {
3654        denominator = exponent;
3655        exponent = NULL;
3656        tmp = _PyLong_GCD(numerator, denominator);
3657        if (tmp == NULL) {
3658            goto error;
3659        }
3660        Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp));
3661        Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp));
3662        Py_DECREF(tmp);
3663        if (numerator == NULL || denominator == NULL) {
3664            goto error;
3665        }
3666    }
3667
3668    result = PyTuple_Pack(2, numerator, denominator);
3669
3670
3671error:
3672    Py_XDECREF(exponent);
3673    Py_XDECREF(denominator);
3674    Py_XDECREF(numerator);
3675    return result;
3676}
3677
3678static PyObject *
3679PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds)
3680{
3681    static char *kwlist[] = {"rounding", "context", NULL};
3682    PyObject *result;
3683    PyObject *rounding = Py_None;
3684    PyObject *context = Py_None;
3685    uint32_t status = 0;
3686    mpd_context_t workctx;
3687
3688    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
3689                                     &rounding, &context)) {
3690        return NULL;
3691    }
3692    CONTEXT_CHECK_VA(context);
3693
3694    workctx = *CTX(context);
3695    if (rounding != Py_None) {
3696        int round = getround(rounding);
3697        if (round < 0) {
3698            return NULL;
3699        }
3700        if (!mpd_qsetround(&workctx, round)) {
3701            INTERNAL_ERROR_PTR("PyDec_ToIntegralValue"); /* GCOV_NOT_REACHED */
3702        }
3703    }
3704
3705    result = dec_alloc();
3706    if (result == NULL) {
3707        return NULL;
3708    }
3709
3710    mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status);
3711    if (dec_addstatus(context, status)) {
3712        Py_DECREF(result);
3713        return NULL;
3714    }
3715
3716    return result;
3717}
3718
3719static PyObject *
3720PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds)
3721{
3722    static char *kwlist[] = {"rounding", "context", NULL};
3723    PyObject *result;
3724    PyObject *rounding = Py_None;
3725    PyObject *context = Py_None;
3726    uint32_t status = 0;
3727    mpd_context_t workctx;
3728
3729    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
3730                                     &rounding, &context)) {
3731        return NULL;
3732    }
3733    CONTEXT_CHECK_VA(context);
3734
3735    workctx = *CTX(context);
3736    if (rounding != Py_None) {
3737        int round = getround(rounding);
3738        if (round < 0) {
3739            return NULL;
3740        }
3741        if (!mpd_qsetround(&workctx, round)) {
3742            INTERNAL_ERROR_PTR("PyDec_ToIntegralExact"); /* GCOV_NOT_REACHED */
3743        }
3744    }
3745
3746    result = dec_alloc();
3747    if (result == NULL) {
3748        return NULL;
3749    }
3750
3751    mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status);
3752    if (dec_addstatus(context, status)) {
3753        Py_DECREF(result);
3754        return NULL;
3755    }
3756
3757    return result;
3758}
3759
3760static PyObject *
3761PyDec_AsFloat(PyObject *dec)
3762{
3763    PyObject *f, *s;
3764
3765    if (mpd_isnan(MPD(dec))) {
3766        if (mpd_issnan(MPD(dec))) {
3767            PyErr_SetString(PyExc_ValueError,
3768                "cannot convert signaling NaN to float");
3769            return NULL;
3770        }
3771        if (mpd_isnegative(MPD(dec))) {
3772            s = PyUnicode_FromString("-nan");
3773        }
3774        else {
3775            s = PyUnicode_FromString("nan");
3776        }
3777    }
3778    else {
3779        s = dec_str(dec);
3780    }
3781
3782    if (s == NULL) {
3783        return NULL;
3784    }
3785
3786    f = PyFloat_FromString(s);
3787    Py_DECREF(s);
3788
3789    return f;
3790}
3791
3792static PyObject *
3793PyDec_Round(PyObject *dec, PyObject *args)
3794{
3795    PyObject *result;
3796    PyObject *x = NULL;
3797    uint32_t status = 0;
3798    PyObject *context;
3799
3800
3801    CURRENT_CONTEXT(context);
3802    if (!PyArg_ParseTuple(args, "|O", &x)) {
3803        return NULL;
3804    }
3805
3806    if (x) {
3807        mpd_uint_t dq[1] = {1};
3808        mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq};
3809        mpd_ssize_t y;
3810
3811        if (!PyLong_Check(x)) {
3812            PyErr_SetString(PyExc_TypeError,
3813                "optional arg must be an integer");
3814            return NULL;
3815        }
3816
3817        y = PyLong_AsSsize_t(x);
3818        if (y == -1 && PyErr_Occurred()) {
3819            return NULL;
3820        }
3821        result = dec_alloc();
3822        if (result == NULL) {
3823            return NULL;
3824        }
3825
3826        q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y;
3827        mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status);
3828        if (dec_addstatus(context, status)) {
3829            Py_DECREF(result);
3830            return NULL;
3831        }
3832
3833        return result;
3834    }
3835    else {
3836        return dec_as_long(dec, context, MPD_ROUND_HALF_EVEN);
3837    }
3838}
3839
3840static PyTypeObject *DecimalTuple = NULL;
3841/* Return the DecimalTuple representation of a PyDecObject. */
3842static PyObject *
3843PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED)
3844{
3845    PyObject *result = NULL;
3846    PyObject *sign = NULL;
3847    PyObject *coeff = NULL;
3848    PyObject *expt = NULL;
3849    PyObject *tmp = NULL;
3850    mpd_t *x = NULL;
3851    char *intstring = NULL;
3852    Py_ssize_t intlen, i;
3853
3854
3855    x = mpd_qncopy(MPD(dec));
3856    if (x == NULL) {
3857        PyErr_NoMemory();
3858        goto out;
3859    }
3860
3861    sign = PyLong_FromUnsignedLong(mpd_sign(MPD(dec)));
3862    if (sign == NULL) {
3863        goto out;
3864    }
3865
3866    if (mpd_isinfinite(x)) {
3867        expt = PyUnicode_FromString("F");
3868        if (expt == NULL) {
3869            goto out;
3870        }
3871        /* decimal.py has non-compliant infinity payloads. */
3872        coeff = Py_BuildValue("(i)", 0);
3873        if (coeff == NULL) {
3874            goto out;
3875        }
3876    }
3877    else {
3878        if (mpd_isnan(x)) {
3879            expt = PyUnicode_FromString(mpd_isqnan(x)?"n":"N");
3880        }
3881        else {
3882            expt = PyLong_FromSsize_t(MPD(dec)->exp);
3883        }
3884        if (expt == NULL) {
3885            goto out;
3886        }
3887
3888        /* coefficient is defined */
3889        if (x->len > 0) {
3890
3891            /* make an integer */
3892            x->exp = 0;
3893            /* clear NaN and sign */
3894            mpd_clear_flags(x);
3895            intstring = mpd_to_sci(x, 1);
3896            if (intstring == NULL) {
3897                PyErr_NoMemory();
3898                goto out;
3899            }
3900
3901            intlen = strlen(intstring);
3902            coeff = PyTuple_New(intlen);
3903            if (coeff == NULL) {
3904                goto out;
3905            }
3906
3907            for (i = 0; i < intlen; i++) {
3908                tmp = PyLong_FromLong(intstring[i]-'0');
3909                if (tmp == NULL) {
3910                    goto out;
3911                }
3912                PyTuple_SET_ITEM(coeff, i, tmp);
3913            }
3914        }
3915        else {
3916            coeff = PyTuple_New(0);
3917            if (coeff == NULL) {
3918                goto out;
3919            }
3920        }
3921    }
3922
3923    result = PyObject_CallFunctionObjArgs((PyObject *)DecimalTuple,
3924                                          sign, coeff, expt, NULL);
3925
3926out:
3927    if (x) mpd_del(x);
3928    if (intstring) mpd_free(intstring);
3929    Py_XDECREF(sign);
3930    Py_XDECREF(coeff);
3931    Py_XDECREF(expt);
3932    return result;
3933}
3934
3935
3936/******************************************************************************/
3937/*         Macros for converting mpdecimal functions to Decimal methods       */
3938/******************************************************************************/
3939
3940/* Unary number method that uses the default module context. */
3941#define Dec_UnaryNumberMethod(MPDFUNC) \
3942static PyObject *                                           \
3943nm_##MPDFUNC(PyObject *self)                                \
3944{                                                           \
3945    PyObject *result;                                       \
3946    PyObject *context;                                      \
3947    uint32_t status = 0;                                    \
3948                                                            \
3949    CURRENT_CONTEXT(context);                               \
3950    if ((result = dec_alloc()) == NULL) {                   \
3951        return NULL;                                        \
3952    }                                                       \
3953                                                            \
3954    MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \
3955    if (dec_addstatus(context, status)) {                   \
3956        Py_DECREF(result);                                  \
3957        return NULL;                                        \
3958    }                                                       \
3959                                                            \
3960    return result;                                          \
3961}
3962
3963/* Binary number method that uses default module context. */
3964#define Dec_BinaryNumberMethod(MPDFUNC) \
3965static PyObject *                                                \
3966nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
3967{                                                                \
3968    PyObject *a, *b;                                             \
3969    PyObject *result;                                            \
3970    PyObject *context;                                           \
3971    uint32_t status = 0;                                         \
3972                                                                 \
3973    CURRENT_CONTEXT(context) ;                                   \
3974    CONVERT_BINOP(&a, &b, self, other, context);                 \
3975                                                                 \
3976    if ((result = dec_alloc()) == NULL) {                        \
3977        Py_DECREF(a);                                            \
3978        Py_DECREF(b);                                            \
3979        return NULL;                                             \
3980    }                                                            \
3981                                                                 \
3982    MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3983    Py_DECREF(a);                                                \
3984    Py_DECREF(b);                                                \
3985    if (dec_addstatus(context, status)) {                        \
3986        Py_DECREF(result);                                       \
3987        return NULL;                                             \
3988    }                                                            \
3989                                                                 \
3990    return result;                                               \
3991}
3992
3993/* Boolean function without a context arg. */
3994#define Dec_BoolFunc(MPDFUNC) \
3995static PyObject *                                           \
3996dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED)       \
3997{                                                           \
3998    return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \
3999}
4000
4001/* Boolean function with an optional context arg. */
4002#define Dec_BoolFuncVA(MPDFUNC) \
4003static PyObject *                                                         \
4004dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)             \
4005{                                                                         \
4006    static char *kwlist[] = {"context", NULL};                            \
4007    PyObject *context = Py_None;                                          \
4008                                                                          \
4009    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,            \
4010                                     &context)) {                         \
4011        return NULL;                                                      \
4012    }                                                                     \
4013    CONTEXT_CHECK_VA(context);                                            \
4014                                                                          \
4015    return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \
4016}
4017
4018/* Unary function with an optional context arg. */
4019#define Dec_UnaryFuncVA(MPDFUNC) \
4020static PyObject *                                              \
4021dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)  \
4022{                                                              \
4023    static char *kwlist[] = {"context", NULL};                 \
4024    PyObject *result;                                          \
4025    PyObject *context = Py_None;                               \
4026    uint32_t status = 0;                                       \
4027                                                               \
4028    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
4029                                     &context)) {              \
4030        return NULL;                                           \
4031    }                                                          \
4032    CONTEXT_CHECK_VA(context);                                 \
4033                                                               \
4034    if ((result = dec_alloc()) == NULL) {                      \
4035        return NULL;                                           \
4036    }                                                          \
4037                                                               \
4038    MPDFUNC(MPD(result), MPD(self), CTX(context), &status);    \
4039    if (dec_addstatus(context, status)) {                      \
4040        Py_DECREF(result);                                     \
4041        return NULL;                                           \
4042    }                                                          \
4043                                                               \
4044    return result;                                             \
4045}
4046
4047/* Binary function with an optional context arg. */
4048#define Dec_BinaryFuncVA(MPDFUNC) \
4049static PyObject *                                                \
4050dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)    \
4051{                                                                \
4052    static char *kwlist[] = {"other", "context", NULL};          \
4053    PyObject *other;                                             \
4054    PyObject *a, *b;                                             \
4055    PyObject *result;                                            \
4056    PyObject *context = Py_None;                                 \
4057    uint32_t status = 0;                                         \
4058                                                                 \
4059    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,  \
4060                                     &other, &context)) {        \
4061        return NULL;                                             \
4062    }                                                            \
4063    CONTEXT_CHECK_VA(context);                                   \
4064    CONVERT_BINOP_RAISE(&a, &b, self, other, context);           \
4065                                                                 \
4066    if ((result = dec_alloc()) == NULL) {                        \
4067        Py_DECREF(a);                                            \
4068        Py_DECREF(b);                                            \
4069        return NULL;                                             \
4070    }                                                            \
4071                                                                 \
4072    MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
4073    Py_DECREF(a);                                                \
4074    Py_DECREF(b);                                                \
4075    if (dec_addstatus(context, status)) {                        \
4076        Py_DECREF(result);                                       \
4077        return NULL;                                             \
4078    }                                                            \
4079                                                                 \
4080    return result;                                               \
4081}
4082
4083/* Binary function with an optional context arg. Actual MPDFUNC does
4084   NOT take a context. The context is used to record InvalidOperation
4085   if the second operand cannot be converted exactly. */
4086#define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \
4087static PyObject *                                               \
4088dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)   \
4089{                                                               \
4090    static char *kwlist[] = {"other", "context", NULL};         \
4091    PyObject *context = Py_None;                                \
4092    PyObject *other;                                            \
4093    PyObject *a, *b;                                            \
4094    PyObject *result;                                           \
4095                                                                \
4096    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
4097                                     &other, &context)) {       \
4098        return NULL;                                            \
4099    }                                                           \
4100    CONTEXT_CHECK_VA(context);                                  \
4101    CONVERT_BINOP_RAISE(&a, &b, self, other, context);          \
4102                                                                \
4103    if ((result = dec_alloc()) == NULL) {                       \
4104        Py_DECREF(a);                                           \
4105        Py_DECREF(b);                                           \
4106        return NULL;                                            \
4107    }                                                           \
4108                                                                \
4109    MPDFUNC(MPD(result), MPD(a), MPD(b));                       \
4110    Py_DECREF(a);                                               \
4111    Py_DECREF(b);                                               \
4112                                                                \
4113    return result;                                              \
4114}
4115
4116/* Ternary function with an optional context arg. */
4117#define Dec_TernaryFuncVA(MPDFUNC) \
4118static PyObject *                                                        \
4119dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)            \
4120{                                                                        \
4121    static char *kwlist[] = {"other", "third", "context", NULL};         \
4122    PyObject *other, *third;                                             \
4123    PyObject *a, *b, *c;                                                 \
4124    PyObject *result;                                                    \
4125    PyObject *context = Py_None;                                         \
4126    uint32_t status = 0;                                                 \
4127                                                                         \
4128    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,         \
4129                                     &other, &third, &context)) {        \
4130        return NULL;                                                     \
4131    }                                                                    \
4132    CONTEXT_CHECK_VA(context);                                           \
4133    CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context);       \
4134                                                                         \
4135    if ((result = dec_alloc()) == NULL) {                                \
4136        Py_DECREF(a);                                                    \
4137        Py_DECREF(b);                                                    \
4138        Py_DECREF(c);                                                    \
4139        return NULL;                                                     \
4140    }                                                                    \
4141                                                                         \
4142    MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \
4143    Py_DECREF(a);                                                        \
4144    Py_DECREF(b);                                                        \
4145    Py_DECREF(c);                                                        \
4146    if (dec_addstatus(context, status)) {                                \
4147        Py_DECREF(result);                                               \
4148        return NULL;                                                     \
4149    }                                                                    \
4150                                                                         \
4151    return result;                                                       \
4152}
4153
4154
4155/**********************************************/
4156/*              Number methods                */
4157/**********************************************/
4158
4159Dec_UnaryNumberMethod(mpd_qminus)
4160Dec_UnaryNumberMethod(mpd_qplus)
4161Dec_UnaryNumberMethod(mpd_qabs)
4162
4163Dec_BinaryNumberMethod(mpd_qadd)
4164Dec_BinaryNumberMethod(mpd_qsub)
4165Dec_BinaryNumberMethod(mpd_qmul)
4166Dec_BinaryNumberMethod(mpd_qdiv)
4167Dec_BinaryNumberMethod(mpd_qrem)
4168Dec_BinaryNumberMethod(mpd_qdivint)
4169
4170static PyObject *
4171nm_dec_as_long(PyObject *dec)
4172{
4173    PyObject *context;
4174
4175    CURRENT_CONTEXT(context);
4176    return dec_as_long(dec, context, MPD_ROUND_DOWN);
4177}
4178
4179static int
4180nm_nonzero(PyObject *v)
4181{
4182    return !mpd_iszero(MPD(v));
4183}
4184
4185static PyObject *
4186nm_mpd_qdivmod(PyObject *v, PyObject *w)
4187{
4188    PyObject *a, *b;
4189    PyObject *q, *r;
4190    PyObject *context;
4191    uint32_t status = 0;
4192    PyObject *ret;
4193
4194    CURRENT_CONTEXT(context);
4195    CONVERT_BINOP(&a, &b, v, w, context);
4196
4197    q = dec_alloc();
4198    if (q == NULL) {
4199        Py_DECREF(a);
4200        Py_DECREF(b);
4201        return NULL;
4202    }
4203    r = dec_alloc();
4204    if (r == NULL) {
4205        Py_DECREF(a);
4206        Py_DECREF(b);
4207        Py_DECREF(q);
4208        return NULL;
4209    }
4210
4211    mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status);
4212    Py_DECREF(a);
4213    Py_DECREF(b);
4214    if (dec_addstatus(context, status)) {
4215        Py_DECREF(r);
4216        Py_DECREF(q);
4217        return NULL;
4218    }
4219
4220    ret = Py_BuildValue("(OO)", q, r);
4221    Py_DECREF(r);
4222    Py_DECREF(q);
4223    return ret;
4224}
4225
4226static PyObject *
4227nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod)
4228{
4229    PyObject *a, *b, *c = NULL;
4230    PyObject *result;
4231    PyObject *context;
4232    uint32_t status = 0;
4233
4234    CURRENT_CONTEXT(context);
4235    CONVERT_BINOP(&a, &b, base, exp, context);
4236
4237    if (mod != Py_None) {
4238        if (!convert_op(NOT_IMPL, &c, mod, context)) {
4239            Py_DECREF(a);
4240            Py_DECREF(b);
4241            return c;
4242        }
4243    }
4244
4245    result = dec_alloc();
4246    if (result == NULL) {
4247        Py_DECREF(a);
4248        Py_DECREF(b);
4249        Py_XDECREF(c);
4250        return NULL;
4251    }
4252
4253    if (c == NULL) {
4254        mpd_qpow(MPD(result), MPD(a), MPD(b),
4255                 CTX(context), &status);
4256    }
4257    else {
4258        mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c),
4259                    CTX(context), &status);
4260        Py_DECREF(c);
4261    }
4262    Py_DECREF(a);
4263    Py_DECREF(b);
4264    if (dec_addstatus(context, status)) {
4265        Py_DECREF(result);
4266        return NULL;
4267    }
4268
4269    return result;
4270}
4271
4272
4273/******************************************************************************/
4274/*                             Decimal Methods                                */
4275/******************************************************************************/
4276
4277/* Unary arithmetic functions, optional context arg */
4278Dec_UnaryFuncVA(mpd_qexp)
4279Dec_UnaryFuncVA(mpd_qln)
4280Dec_UnaryFuncVA(mpd_qlog10)
4281Dec_UnaryFuncVA(mpd_qnext_minus)
4282Dec_UnaryFuncVA(mpd_qnext_plus)
4283Dec_UnaryFuncVA(mpd_qreduce)
4284Dec_UnaryFuncVA(mpd_qsqrt)
4285
4286/* Binary arithmetic functions, optional context arg */
4287Dec_BinaryFuncVA(mpd_qcompare)
4288Dec_BinaryFuncVA(mpd_qcompare_signal)
4289Dec_BinaryFuncVA(mpd_qmax)
4290Dec_BinaryFuncVA(mpd_qmax_mag)
4291Dec_BinaryFuncVA(mpd_qmin)
4292Dec_BinaryFuncVA(mpd_qmin_mag)
4293Dec_BinaryFuncVA(mpd_qnext_toward)
4294Dec_BinaryFuncVA(mpd_qrem_near)
4295
4296/* Ternary arithmetic functions, optional context arg */
4297Dec_TernaryFuncVA(mpd_qfma)
4298
4299/* Boolean functions, no context arg */
4300Dec_BoolFunc(mpd_iscanonical)
4301Dec_BoolFunc(mpd_isfinite)
4302Dec_BoolFunc(mpd_isinfinite)
4303Dec_BoolFunc(mpd_isnan)
4304Dec_BoolFunc(mpd_isqnan)
4305Dec_BoolFunc(mpd_issnan)
4306Dec_BoolFunc(mpd_issigned)
4307Dec_BoolFunc(mpd_iszero)
4308
4309/* Boolean functions, optional context arg */
4310Dec_BoolFuncVA(mpd_isnormal)
4311Dec_BoolFuncVA(mpd_issubnormal)
4312
4313/* Unary functions, no context arg */
4314static PyObject *
4315dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED)
4316{
4317    mpd_ssize_t retval;
4318
4319    if (mpd_isspecial(MPD(self))) {
4320        retval = 0;
4321    }
4322    else {
4323        retval = mpd_adjexp(MPD(self));
4324    }
4325
4326    return PyLong_FromSsize_t(retval);
4327}
4328
4329static PyObject *
4330dec_canonical(PyObject *self, PyObject *dummy UNUSED)
4331{
4332    Py_INCREF(self);
4333    return self;
4334}
4335
4336static PyObject *
4337dec_conjugate(PyObject *self, PyObject *dummy UNUSED)
4338{
4339    Py_INCREF(self);
4340    return self;
4341}
4342
4343static PyObject *
4344dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED)
4345{
4346    PyObject *result;
4347
4348    result = dec_alloc();
4349    if (result == NULL) {
4350        return NULL;
4351    }
4352
4353    _dec_settriple(result, MPD_POS, 10, 0);
4354    return result;
4355}
4356
4357static PyObject *
4358dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED)
4359{
4360    PyObject *result;
4361    uint32_t status = 0;
4362
4363    if ((result = dec_alloc()) == NULL) {
4364        return NULL;
4365    }
4366
4367    mpd_qcopy_abs(MPD(result), MPD(self), &status);
4368    if (status & MPD_Malloc_error) {
4369        Py_DECREF(result);
4370        PyErr_NoMemory();
4371        return NULL;
4372    }
4373
4374    return result;
4375}
4376
4377static PyObject *
4378dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED)
4379{
4380    PyObject *result;
4381    uint32_t status = 0;
4382
4383    if ((result = dec_alloc()) == NULL) {
4384        return NULL;
4385    }
4386
4387    mpd_qcopy_negate(MPD(result), MPD(self), &status);
4388    if (status & MPD_Malloc_error) {
4389        Py_DECREF(result);
4390        PyErr_NoMemory();
4391        return NULL;
4392    }
4393
4394    return result;
4395}
4396
4397/* Unary functions, optional context arg */
4398Dec_UnaryFuncVA(mpd_qinvert)
4399Dec_UnaryFuncVA(mpd_qlogb)
4400
4401static PyObject *
4402dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds)
4403{
4404    static char *kwlist[] = {"context", NULL};
4405    PyObject *context = Py_None;
4406    const char *cp;
4407
4408    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
4409                                     &context)) {
4410        return NULL;
4411    }
4412    CONTEXT_CHECK_VA(context);
4413
4414    cp = mpd_class(MPD(self), CTX(context));
4415    return PyUnicode_FromString(cp);
4416}
4417
4418static PyObject *
4419dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds)
4420{
4421    static char *kwlist[] = {"context", NULL};
4422    PyObject *result;
4423    PyObject *context = Py_None;
4424    mpd_ssize_t size;
4425    char *s;
4426
4427    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
4428                                     &context)) {
4429        return NULL;
4430    }
4431    CONTEXT_CHECK_VA(context);
4432
4433    size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context));
4434    if (size < 0) {
4435        PyErr_NoMemory();
4436        return NULL;
4437    }
4438
4439    result = unicode_fromascii(s, size);
4440    mpd_free(s);
4441
4442    return result;
4443}
4444
4445/* Binary functions, optional context arg for conversion errors */
4446Dec_BinaryFuncVA_NO_CTX(mpd_compare_total)
4447Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag)
4448
4449static PyObject *
4450dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds)
4451{
4452    static char *kwlist[] = {"other", "context", NULL};
4453    PyObject *other;
4454    PyObject *a, *b;
4455    PyObject *result;
4456    PyObject *context = Py_None;
4457    uint32_t status = 0;
4458
4459    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
4460                                     &other, &context)) {
4461        return NULL;
4462    }
4463    CONTEXT_CHECK_VA(context);
4464    CONVERT_BINOP_RAISE(&a, &b, self, other, context);
4465
4466    result = dec_alloc();
4467    if (result == NULL) {
4468        Py_DECREF(a);
4469        Py_DECREF(b);
4470        return NULL;
4471    }
4472
4473    mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
4474    Py_DECREF(a);
4475    Py_DECREF(b);
4476    if (dec_addstatus(context, status)) {
4477        Py_DECREF(result);
4478        return NULL;
4479    }
4480
4481    return result;
4482}
4483
4484static PyObject *
4485dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds)
4486{
4487    static char *kwlist[] = {"other", "context", NULL};
4488    PyObject *other;
4489    PyObject *a, *b;
4490    PyObject *result;
4491    PyObject *context = Py_None;
4492
4493    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
4494                                     &other, &context)) {
4495        return NULL;
4496    }
4497    CONTEXT_CHECK_VA(context);
4498    CONVERT_BINOP_RAISE(&a, &b, self, other, context);
4499
4500    result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false();
4501    Py_DECREF(a);
4502    Py_DECREF(b);
4503
4504    return result;
4505}
4506
4507/* Binary functions, optional context arg */
4508Dec_BinaryFuncVA(mpd_qand)
4509Dec_BinaryFuncVA(mpd_qor)
4510Dec_BinaryFuncVA(mpd_qxor)
4511
4512Dec_BinaryFuncVA(mpd_qrotate)
4513Dec_BinaryFuncVA(mpd_qscaleb)
4514Dec_BinaryFuncVA(mpd_qshift)
4515
4516static PyObject *
4517dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds)
4518{
4519    static char *kwlist[] = {"exp", "rounding", "context", NULL};
4520    PyObject *rounding = Py_None;
4521    PyObject *context = Py_None;
4522    PyObject *w, *a, *b;
4523    PyObject *result;
4524    uint32_t status = 0;
4525    mpd_context_t workctx;
4526
4527    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist,
4528                                     &w, &rounding, &context)) {
4529        return NULL;
4530    }
4531    CONTEXT_CHECK_VA(context);
4532
4533    workctx = *CTX(context);
4534    if (rounding != Py_None) {
4535        int round = getround(rounding);
4536        if (round < 0) {
4537            return NULL;
4538        }
4539        if (!mpd_qsetround(&workctx, round)) {
4540            INTERNAL_ERROR_PTR("dec_mpd_qquantize"); /* GCOV_NOT_REACHED */
4541        }
4542    }
4543
4544    CONVERT_BINOP_RAISE(&a, &b, v, w, context);
4545
4546    result = dec_alloc();
4547    if (result == NULL) {
4548        Py_DECREF(a);
4549        Py_DECREF(b);
4550        return NULL;
4551    }
4552
4553    mpd_qquantize(MPD(result), MPD(a), MPD(b), &workctx, &status);
4554    Py_DECREF(a);
4555    Py_DECREF(b);
4556    if (dec_addstatus(context, status)) {
4557        Py_DECREF(result);
4558        return NULL;
4559    }
4560
4561    return result;
4562}
4563
4564/* Special methods */
4565static PyObject *
4566dec_richcompare(PyObject *v, PyObject *w, int op)
4567{
4568    PyObject *a;
4569    PyObject *b;
4570    PyObject *context;
4571    uint32_t status = 0;
4572    int a_issnan, b_issnan;
4573    int r;
4574
4575    assert(PyDec_Check(v));
4576
4577    CURRENT_CONTEXT(context);
4578    CONVERT_BINOP_CMP(&a, &b, v, w, op, context);
4579
4580    a_issnan = mpd_issnan(MPD(a));
4581    b_issnan = mpd_issnan(MPD(b));
4582
4583    r = mpd_qcmp(MPD(a), MPD(b), &status);
4584    Py_DECREF(a);
4585    Py_DECREF(b);
4586    if (r == INT_MAX) {
4587        /* sNaNs or op={le,ge,lt,gt} always signal. */
4588        if (a_issnan || b_issnan || (op != Py_EQ && op != Py_NE)) {
4589            if (dec_addstatus(context, status)) {
4590                return NULL;
4591            }
4592        }
4593        /* qNaN comparison with op={eq,ne} or comparison
4594         * with InvalidOperation disabled. */
4595        return (op == Py_NE) ? incr_true() : incr_false();
4596    }
4597
4598    switch (op) {
4599    case Py_EQ:
4600        r = (r == 0);
4601        break;
4602    case Py_NE:
4603        r = (r != 0);
4604        break;
4605    case Py_LE:
4606        r = (r <= 0);
4607        break;
4608    case Py_GE:
4609        r = (r >= 0);
4610        break;
4611    case Py_LT:
4612        r = (r == -1);
4613        break;
4614    case Py_GT:
4615        r = (r == 1);
4616        break;
4617    }
4618
4619    return PyBool_FromLong(r);
4620}
4621
4622/* __ceil__ */
4623static PyObject *
4624dec_ceil(PyObject *self, PyObject *dummy UNUSED)
4625{
4626    PyObject *context;
4627
4628    CURRENT_CONTEXT(context);
4629    return dec_as_long(self, context, MPD_ROUND_CEILING);
4630}
4631
4632/* __complex__ */
4633static PyObject *
4634dec_complex(PyObject *self, PyObject *dummy UNUSED)
4635{
4636    PyObject *f;
4637    double x;
4638
4639    f = PyDec_AsFloat(self);
4640    if (f == NULL) {
4641        return NULL;
4642    }
4643
4644    x = PyFloat_AsDouble(f);
4645    Py_DECREF(f);
4646    if (x == -1.0 && PyErr_Occurred()) {
4647        return NULL;
4648    }
4649
4650    return PyComplex_FromDoubles(x, 0);
4651}
4652
4653/* __copy__ and __deepcopy__ */
4654static PyObject *
4655dec_copy(PyObject *self, PyObject *dummy UNUSED)
4656{
4657    Py_INCREF(self);
4658    return self;
4659}
4660
4661/* __floor__ */
4662static PyObject *
4663dec_floor(PyObject *self, PyObject *dummy UNUSED)
4664{
4665    PyObject *context;
4666
4667    CURRENT_CONTEXT(context);
4668    return dec_as_long(self, context, MPD_ROUND_FLOOR);
4669}
4670
4671/* Always uses the module context */
4672static Py_hash_t
4673_dec_hash(PyDecObject *v)
4674{
4675#if defined(CONFIG_64) && _PyHASH_BITS == 61
4676    /* 2**61 - 1 */
4677    mpd_uint_t p_data[1] = {2305843009213693951ULL};
4678    mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
4679    /* Inverse of 10 modulo p */
4680    mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL};
4681    mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4682                     0, 19, 1, 1, inv10_p_data};
4683#elif defined(CONFIG_32) && _PyHASH_BITS == 31
4684    /* 2**31 - 1 */
4685    mpd_uint_t p_data[2] = {147483647UL, 2};
4686    mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data};
4687    /* Inverse of 10 modulo p */
4688    mpd_uint_t inv10_p_data[2] = {503238553UL, 1};
4689    mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4690                     0, 10, 2, 2, inv10_p_data};
4691#else
4692    #error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS"
4693#endif
4694    const Py_hash_t py_hash_inf = 314159;
4695    mpd_uint_t ten_data[1] = {10};
4696    mpd_t ten = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4697                 0, 2, 1, 1, ten_data};
4698    Py_hash_t result;
4699    mpd_t *exp_hash = NULL;
4700    mpd_t *tmp = NULL;
4701    mpd_ssize_t exp;
4702    uint32_t status = 0;
4703    mpd_context_t maxctx;
4704
4705
4706    if (mpd_isspecial(MPD(v))) {
4707        if (mpd_issnan(MPD(v))) {
4708            PyErr_SetString(PyExc_TypeError,
4709                "Cannot hash a signaling NaN value");
4710            return -1;
4711        }
4712        else if (mpd_isnan(MPD(v))) {
4713            return _Py_HashPointer(v);
4714        }
4715        else {
4716            return py_hash_inf * mpd_arith_sign(MPD(v));
4717        }
4718    }
4719
4720    mpd_maxcontext(&maxctx);
4721    exp_hash = mpd_qnew();
4722    if (exp_hash == NULL) {
4723        goto malloc_error;
4724    }
4725    tmp = mpd_qnew();
4726    if (tmp == NULL) {
4727        goto malloc_error;
4728    }
4729
4730    /*
4731     * exp(v): exponent of v
4732     * int(v): coefficient of v
4733     */
4734    exp = MPD(v)->exp;
4735    if (exp >= 0) {
4736        /* 10**exp(v) % p */
4737        mpd_qsset_ssize(tmp, exp, &maxctx, &status);
4738        mpd_qpowmod(exp_hash, &ten, tmp, &p, &maxctx, &status);
4739    }
4740    else {
4741        /* inv10_p**(-exp(v)) % p */
4742        mpd_qsset_ssize(tmp, -exp, &maxctx, &status);
4743        mpd_qpowmod(exp_hash, &inv10_p, tmp, &p, &maxctx, &status);
4744    }
4745
4746    /* hash = (int(v) * exp_hash) % p */
4747    if (!mpd_qcopy(tmp, MPD(v), &status)) {
4748        goto malloc_error;
4749    }
4750    tmp->exp = 0;
4751    mpd_set_positive(tmp);
4752
4753    maxctx.prec = MPD_MAX_PREC + 21;
4754    maxctx.emax = MPD_MAX_EMAX + 21;
4755    maxctx.emin = MPD_MIN_EMIN - 21;
4756
4757    mpd_qmul(tmp, tmp, exp_hash, &maxctx, &status);
4758    mpd_qrem(tmp, tmp, &p, &maxctx, &status);
4759
4760    result = mpd_qget_ssize(tmp, &status);
4761    result = mpd_ispositive(MPD(v)) ? result : -result;
4762    result = (result == -1) ? -2 : result;
4763
4764    if (status != 0) {
4765        if (status & MPD_Malloc_error) {
4766            goto malloc_error;
4767        }
4768        else {
4769            PyErr_SetString(PyExc_RuntimeError, /* GCOV_NOT_REACHED */
4770                "dec_hash: internal error: please report"); /* GCOV_NOT_REACHED */
4771        }
4772        result = -1; /* GCOV_NOT_REACHED */
4773    }
4774
4775
4776finish:
4777    if (exp_hash) mpd_del(exp_hash);
4778    if (tmp) mpd_del(tmp);
4779    return result;
4780
4781malloc_error:
4782    PyErr_NoMemory();
4783    result = -1;
4784    goto finish;
4785}
4786
4787static Py_hash_t
4788dec_hash(PyDecObject *self)
4789{
4790    if (self->hash == -1) {
4791        self->hash = _dec_hash(self);
4792    }
4793
4794    return self->hash;
4795}
4796
4797/* __reduce__ */
4798static PyObject *
4799dec_reduce(PyObject *self, PyObject *dummy UNUSED)
4800{
4801    PyObject *result, *str;
4802
4803    str = dec_str(self);
4804    if (str == NULL) {
4805        return NULL;
4806    }
4807
4808    result = Py_BuildValue("O(O)", Py_TYPE(self), str);
4809    Py_DECREF(str);
4810
4811    return result;
4812}
4813
4814/* __sizeof__ */
4815static PyObject *
4816dec_sizeof(PyObject *v, PyObject *dummy UNUSED)
4817{
4818    Py_ssize_t res;
4819
4820    res = _PyObject_SIZE(Py_TYPE(v));
4821    if (mpd_isdynamic_data(MPD(v))) {
4822        res += MPD(v)->alloc * sizeof(mpd_uint_t);
4823    }
4824    return PyLong_FromSsize_t(res);
4825}
4826
4827/* __trunc__ */
4828static PyObject *
4829dec_trunc(PyObject *self, PyObject *dummy UNUSED)
4830{
4831    PyObject *context;
4832
4833    CURRENT_CONTEXT(context);
4834    return dec_as_long(self, context, MPD_ROUND_DOWN);
4835}
4836
4837/* real and imag */
4838static PyObject *
4839dec_real(PyObject *self, void *closure UNUSED)
4840{
4841    Py_INCREF(self);
4842    return self;
4843}
4844
4845static PyObject *
4846dec_imag(PyObject *self UNUSED, void *closure UNUSED)
4847{
4848    PyObject *result;
4849
4850    result = dec_alloc();
4851    if (result == NULL) {
4852        return NULL;
4853    }
4854
4855    _dec_settriple(result, MPD_POS, 0, 0);
4856    return result;
4857}
4858
4859
4860static PyGetSetDef dec_getsets [] =
4861{
4862  { "real", (getter)dec_real, NULL, NULL, NULL},
4863  { "imag", (getter)dec_imag, NULL, NULL, NULL},
4864  {NULL}
4865};
4866
4867static PyNumberMethods dec_number_methods =
4868{
4869    (binaryfunc) nm_mpd_qadd,
4870    (binaryfunc) nm_mpd_qsub,
4871    (binaryfunc) nm_mpd_qmul,
4872    (binaryfunc) nm_mpd_qrem,
4873    (binaryfunc) nm_mpd_qdivmod,
4874    (ternaryfunc) nm_mpd_qpow,
4875    (unaryfunc) nm_mpd_qminus,
4876    (unaryfunc) nm_mpd_qplus,
4877    (unaryfunc) nm_mpd_qabs,
4878    (inquiry) nm_nonzero,
4879    (unaryfunc) 0,   /* no bit-complement */
4880    (binaryfunc) 0,  /* no shiftl */
4881    (binaryfunc) 0,  /* no shiftr */
4882    (binaryfunc) 0,  /* no bit-and */
4883    (binaryfunc) 0,  /* no bit-xor */
4884    (binaryfunc) 0,  /* no bit-ior */
4885    (unaryfunc) nm_dec_as_long,
4886    0,               /* nb_reserved */
4887    (unaryfunc) PyDec_AsFloat,
4888    0,               /* binaryfunc nb_inplace_add; */
4889    0,               /* binaryfunc nb_inplace_subtract; */
4890    0,               /* binaryfunc nb_inplace_multiply; */
4891    0,               /* binaryfunc nb_inplace_remainder; */
4892    0,               /* ternaryfunc nb_inplace_power; */
4893    0,               /* binaryfunc nb_inplace_lshift; */
4894    0,               /* binaryfunc nb_inplace_rshift; */
4895    0,               /* binaryfunc nb_inplace_and; */
4896    0,               /* binaryfunc nb_inplace_xor; */
4897    0,               /* binaryfunc nb_inplace_or; */
4898    (binaryfunc) nm_mpd_qdivint,  /* binaryfunc nb_floor_divide; */
4899    (binaryfunc) nm_mpd_qdiv,     /* binaryfunc nb_true_divide; */
4900    0,               /* binaryfunc nb_inplace_floor_divide; */
4901    0,               /* binaryfunc nb_inplace_true_divide; */
4902};
4903
4904static PyMethodDef dec_methods [] =
4905{
4906  /* Unary arithmetic functions, optional context arg */
4907  { "exp", _PyCFunction_CAST(dec_mpd_qexp), METH_VARARGS|METH_KEYWORDS, doc_exp },
4908  { "ln", _PyCFunction_CAST(dec_mpd_qln), METH_VARARGS|METH_KEYWORDS, doc_ln },
4909  { "log10", _PyCFunction_CAST(dec_mpd_qlog10), METH_VARARGS|METH_KEYWORDS, doc_log10 },
4910  { "next_minus", _PyCFunction_CAST(dec_mpd_qnext_minus), METH_VARARGS|METH_KEYWORDS, doc_next_minus },
4911  { "next_plus", _PyCFunction_CAST(dec_mpd_qnext_plus), METH_VARARGS|METH_KEYWORDS, doc_next_plus },
4912  { "normalize", _PyCFunction_CAST(dec_mpd_qreduce), METH_VARARGS|METH_KEYWORDS, doc_normalize },
4913  { "to_integral", _PyCFunction_CAST(PyDec_ToIntegralValue), METH_VARARGS|METH_KEYWORDS, doc_to_integral },
4914  { "to_integral_exact", _PyCFunction_CAST(PyDec_ToIntegralExact), METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact },
4915  { "to_integral_value", _PyCFunction_CAST(PyDec_ToIntegralValue), METH_VARARGS|METH_KEYWORDS, doc_to_integral_value },
4916  { "sqrt", _PyCFunction_CAST(dec_mpd_qsqrt), METH_VARARGS|METH_KEYWORDS, doc_sqrt },
4917
4918  /* Binary arithmetic functions, optional context arg */
4919  { "compare", _PyCFunction_CAST(dec_mpd_qcompare), METH_VARARGS|METH_KEYWORDS, doc_compare },
4920  { "compare_signal", _PyCFunction_CAST(dec_mpd_qcompare_signal), METH_VARARGS|METH_KEYWORDS, doc_compare_signal },
4921  { "max", _PyCFunction_CAST(dec_mpd_qmax), METH_VARARGS|METH_KEYWORDS, doc_max },
4922  { "max_mag", _PyCFunction_CAST(dec_mpd_qmax_mag), METH_VARARGS|METH_KEYWORDS, doc_max_mag },
4923  { "min", _PyCFunction_CAST(dec_mpd_qmin), METH_VARARGS|METH_KEYWORDS, doc_min },
4924  { "min_mag", _PyCFunction_CAST(dec_mpd_qmin_mag), METH_VARARGS|METH_KEYWORDS, doc_min_mag },
4925  { "next_toward", _PyCFunction_CAST(dec_mpd_qnext_toward), METH_VARARGS|METH_KEYWORDS, doc_next_toward },
4926  { "quantize", _PyCFunction_CAST(dec_mpd_qquantize), METH_VARARGS|METH_KEYWORDS, doc_quantize },
4927  { "remainder_near", _PyCFunction_CAST(dec_mpd_qrem_near), METH_VARARGS|METH_KEYWORDS, doc_remainder_near },
4928
4929  /* Ternary arithmetic functions, optional context arg */
4930  { "fma", _PyCFunction_CAST(dec_mpd_qfma), METH_VARARGS|METH_KEYWORDS, doc_fma },
4931
4932  /* Boolean functions, no context arg */
4933  { "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical },
4934  { "is_finite", dec_mpd_isfinite, METH_NOARGS, doc_is_finite },
4935  { "is_infinite", dec_mpd_isinfinite, METH_NOARGS, doc_is_infinite },
4936  { "is_nan", dec_mpd_isnan, METH_NOARGS, doc_is_nan },
4937  { "is_qnan", dec_mpd_isqnan, METH_NOARGS, doc_is_qnan },
4938  { "is_snan", dec_mpd_issnan, METH_NOARGS, doc_is_snan },
4939  { "is_signed", dec_mpd_issigned, METH_NOARGS, doc_is_signed },
4940  { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero },
4941
4942  /* Boolean functions, optional context arg */
4943  { "is_normal", _PyCFunction_CAST(dec_mpd_isnormal), METH_VARARGS|METH_KEYWORDS, doc_is_normal },
4944  { "is_subnormal", _PyCFunction_CAST(dec_mpd_issubnormal), METH_VARARGS|METH_KEYWORDS, doc_is_subnormal },
4945
4946  /* Unary functions, no context arg */
4947  { "adjusted", dec_mpd_adjexp, METH_NOARGS, doc_adjusted },
4948  { "canonical", dec_canonical, METH_NOARGS, doc_canonical },
4949  { "conjugate", dec_conjugate, METH_NOARGS, doc_conjugate },
4950  { "radix", dec_mpd_radix, METH_NOARGS, doc_radix },
4951
4952  /* Unary functions, optional context arg for conversion errors */
4953  { "copy_abs", dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs },
4954  { "copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate },
4955
4956  /* Unary functions, optional context arg */
4957  { "logb", _PyCFunction_CAST(dec_mpd_qlogb), METH_VARARGS|METH_KEYWORDS, doc_logb },
4958  { "logical_invert", _PyCFunction_CAST(dec_mpd_qinvert), METH_VARARGS|METH_KEYWORDS, doc_logical_invert },
4959  { "number_class", _PyCFunction_CAST(dec_mpd_class), METH_VARARGS|METH_KEYWORDS, doc_number_class },
4960  { "to_eng_string", _PyCFunction_CAST(dec_mpd_to_eng), METH_VARARGS|METH_KEYWORDS, doc_to_eng_string },
4961
4962  /* Binary functions, optional context arg for conversion errors */
4963  { "compare_total", _PyCFunction_CAST(dec_mpd_compare_total), METH_VARARGS|METH_KEYWORDS, doc_compare_total },
4964  { "compare_total_mag", _PyCFunction_CAST(dec_mpd_compare_total_mag), METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag },
4965  { "copy_sign", _PyCFunction_CAST(dec_mpd_qcopy_sign), METH_VARARGS|METH_KEYWORDS, doc_copy_sign },
4966  { "same_quantum", _PyCFunction_CAST(dec_mpd_same_quantum), METH_VARARGS|METH_KEYWORDS, doc_same_quantum },
4967
4968  /* Binary functions, optional context arg */
4969  { "logical_and", _PyCFunction_CAST(dec_mpd_qand), METH_VARARGS|METH_KEYWORDS, doc_logical_and },
4970  { "logical_or", _PyCFunction_CAST(dec_mpd_qor), METH_VARARGS|METH_KEYWORDS, doc_logical_or },
4971  { "logical_xor", _PyCFunction_CAST(dec_mpd_qxor), METH_VARARGS|METH_KEYWORDS, doc_logical_xor },
4972  { "rotate", _PyCFunction_CAST(dec_mpd_qrotate), METH_VARARGS|METH_KEYWORDS, doc_rotate },
4973  { "scaleb", _PyCFunction_CAST(dec_mpd_qscaleb), METH_VARARGS|METH_KEYWORDS, doc_scaleb },
4974  { "shift", _PyCFunction_CAST(dec_mpd_qshift), METH_VARARGS|METH_KEYWORDS, doc_shift },
4975
4976  /* Miscellaneous */
4977  { "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float },
4978  { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple },
4979  { "as_integer_ratio", dec_as_integer_ratio, METH_NOARGS, doc_as_integer_ratio },
4980
4981  /* Special methods */
4982  { "__copy__", dec_copy, METH_NOARGS, NULL },
4983  { "__deepcopy__", dec_copy, METH_O, NULL },
4984  { "__format__", dec_format, METH_VARARGS, NULL },
4985  { "__reduce__", dec_reduce, METH_NOARGS, NULL },
4986  { "__round__", PyDec_Round, METH_VARARGS, NULL },
4987  { "__ceil__", dec_ceil, METH_NOARGS, NULL },
4988  { "__floor__", dec_floor, METH_NOARGS, NULL },
4989  { "__trunc__", dec_trunc, METH_NOARGS, NULL },
4990  { "__complex__", dec_complex, METH_NOARGS, NULL },
4991  { "__sizeof__", dec_sizeof, METH_NOARGS, NULL },
4992
4993  { NULL, NULL, 1 }
4994};
4995
4996static PyTypeObject PyDec_Type =
4997{
4998    PyVarObject_HEAD_INIT(NULL, 0)
4999    "decimal.Decimal",                      /* tp_name */
5000    sizeof(PyDecObject),                    /* tp_basicsize */
5001    0,                                      /* tp_itemsize */
5002    (destructor) dec_dealloc,               /* tp_dealloc */
5003    0,                                      /* tp_vectorcall_offset */
5004    (getattrfunc) 0,                        /* tp_getattr */
5005    (setattrfunc) 0,                        /* tp_setattr */
5006    0,                                      /* tp_as_async */
5007    (reprfunc) dec_repr,                    /* tp_repr */
5008    &dec_number_methods,                    /* tp_as_number */
5009    0,                                      /* tp_as_sequence */
5010    0,                                      /* tp_as_mapping */
5011    (hashfunc) dec_hash,                    /* tp_hash */
5012    0,                                      /* tp_call */
5013    (reprfunc) dec_str,                     /* tp_str */
5014    (getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */
5015    (setattrofunc) 0,                       /* tp_setattro */
5016    (PyBufferProcs *) 0,                    /* tp_as_buffer */
5017    (Py_TPFLAGS_DEFAULT|
5018     Py_TPFLAGS_BASETYPE),                  /* tp_flags */
5019    doc_decimal,                            /* tp_doc */
5020    0,                                      /* tp_traverse */
5021    0,                                      /* tp_clear */
5022    dec_richcompare,                        /* tp_richcompare */
5023    0,                                      /* tp_weaklistoffset */
5024    0,                                      /* tp_iter */
5025    0,                                      /* tp_iternext */
5026    dec_methods,                            /* tp_methods */
5027    0,                                      /* tp_members */
5028    dec_getsets,                            /* tp_getset */
5029    0,                                      /* tp_base */
5030    0,                                      /* tp_dict */
5031    0,                                      /* tp_descr_get */
5032    0,                                      /* tp_descr_set */
5033    0,                                      /* tp_dictoffset */
5034    0,                                      /* tp_init */
5035    0,                                      /* tp_alloc */
5036    dec_new,                                /* tp_new */
5037    PyObject_Del,                           /* tp_free */
5038};
5039
5040
5041/******************************************************************************/
5042/*                         Context Object, Part 2                             */
5043/******************************************************************************/
5044
5045
5046/************************************************************************/
5047/*     Macros for converting mpdecimal functions to Context methods     */
5048/************************************************************************/
5049
5050/* Boolean context method. */
5051#define DecCtx_BoolFunc(MPDFUNC) \
5052static PyObject *                                                     \
5053ctx_##MPDFUNC(PyObject *context, PyObject *v)                         \
5054{                                                                     \
5055    PyObject *ret;                                                    \
5056    PyObject *a;                                                      \
5057                                                                      \
5058    CONVERT_OP_RAISE(&a, v, context);                                 \
5059                                                                      \
5060    ret = MPDFUNC(MPD(a), CTX(context)) ? incr_true() : incr_false(); \
5061    Py_DECREF(a);                                                     \
5062    return ret;                                                       \
5063}
5064
5065/* Boolean context method. MPDFUNC does NOT use a context. */
5066#define DecCtx_BoolFunc_NO_CTX(MPDFUNC) \
5067static PyObject *                                       \
5068ctx_##MPDFUNC(PyObject *context, PyObject *v)           \
5069{                                                       \
5070    PyObject *ret;                                      \
5071    PyObject *a;                                        \
5072                                                        \
5073    CONVERT_OP_RAISE(&a, v, context);                   \
5074                                                        \
5075    ret = MPDFUNC(MPD(a)) ? incr_true() : incr_false(); \
5076    Py_DECREF(a);                                       \
5077    return ret;                                         \
5078}
5079
5080/* Unary context method. */
5081#define DecCtx_UnaryFunc(MPDFUNC) \
5082static PyObject *                                        \
5083ctx_##MPDFUNC(PyObject *context, PyObject *v)            \
5084{                                                        \
5085    PyObject *result, *a;                                \
5086    uint32_t status = 0;                                 \
5087                                                         \
5088    CONVERT_OP_RAISE(&a, v, context);                    \
5089                                                         \
5090    if ((result = dec_alloc()) == NULL) {                \
5091        Py_DECREF(a);                                    \
5092        return NULL;                                     \
5093    }                                                    \
5094                                                         \
5095    MPDFUNC(MPD(result), MPD(a), CTX(context), &status); \
5096    Py_DECREF(a);                                        \
5097    if (dec_addstatus(context, status)) {                \
5098        Py_DECREF(result);                               \
5099        return NULL;                                     \
5100    }                                                    \
5101                                                         \
5102    return result;                                       \
5103}
5104
5105/* Binary context method. */
5106#define DecCtx_BinaryFunc(MPDFUNC) \
5107static PyObject *                                                \
5108ctx_##MPDFUNC(PyObject *context, PyObject *args)                 \
5109{                                                                \
5110    PyObject *v, *w;                                             \
5111    PyObject *a, *b;                                             \
5112    PyObject *result;                                            \
5113    uint32_t status = 0;                                         \
5114                                                                 \
5115    if (!PyArg_ParseTuple(args, "OO", &v, &w)) {                 \
5116        return NULL;                                             \
5117    }                                                            \
5118                                                                 \
5119    CONVERT_BINOP_RAISE(&a, &b, v, w, context);                  \
5120                                                                 \
5121    if ((result = dec_alloc()) == NULL) {                        \
5122        Py_DECREF(a);                                            \
5123        Py_DECREF(b);                                            \
5124        return NULL;                                             \
5125    }                                                            \
5126                                                                 \
5127    MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
5128    Py_DECREF(a);                                                \
5129    Py_DECREF(b);                                                \
5130    if (dec_addstatus(context, status)) {                        \
5131        Py_DECREF(result);                                       \
5132        return NULL;                                             \
5133    }                                                            \
5134                                                                 \
5135    return result;                                               \
5136}
5137
5138/*
5139 * Binary context method. The context is only used for conversion.
5140 * The actual MPDFUNC does NOT take a context arg.
5141 */
5142#define DecCtx_BinaryFunc_NO_CTX(MPDFUNC) \
5143static PyObject *                                \
5144ctx_##MPDFUNC(PyObject *context, PyObject *args) \
5145{                                                \
5146    PyObject *v, *w;                             \
5147    PyObject *a, *b;                             \
5148    PyObject *result;                            \
5149                                                 \
5150    if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \
5151        return NULL;                             \
5152    }                                            \
5153                                                 \
5154    CONVERT_BINOP_RAISE(&a, &b, v, w, context);  \
5155                                                 \
5156    if ((result = dec_alloc()) == NULL) {        \
5157        Py_DECREF(a);                            \
5158        Py_DECREF(b);                            \
5159        return NULL;                             \
5160    }                                            \
5161                                                 \
5162    MPDFUNC(MPD(result), MPD(a), MPD(b));        \
5163    Py_DECREF(a);                                \
5164    Py_DECREF(b);                                \
5165                                                 \
5166    return result;                               \
5167}
5168
5169/* Ternary context method. */
5170#define DecCtx_TernaryFunc(MPDFUNC) \
5171static PyObject *                                                        \
5172ctx_##MPDFUNC(PyObject *context, PyObject *args)                         \
5173{                                                                        \
5174    PyObject *v, *w, *x;                                                 \
5175    PyObject *a, *b, *c;                                                 \
5176    PyObject *result;                                                    \
5177    uint32_t status = 0;                                                 \
5178                                                                         \
5179    if (!PyArg_ParseTuple(args, "OOO", &v, &w, &x)) {                    \
5180        return NULL;                                                     \
5181    }                                                                    \
5182                                                                         \
5183    CONVERT_TERNOP_RAISE(&a, &b, &c, v, w, x, context);                  \
5184                                                                         \
5185    if ((result = dec_alloc()) == NULL) {                                \
5186        Py_DECREF(a);                                                    \
5187        Py_DECREF(b);                                                    \
5188        Py_DECREF(c);                                                    \
5189        return NULL;                                                     \
5190    }                                                                    \
5191                                                                         \
5192    MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \
5193    Py_DECREF(a);                                                        \
5194    Py_DECREF(b);                                                        \
5195    Py_DECREF(c);                                                        \
5196    if (dec_addstatus(context, status)) {                                \
5197        Py_DECREF(result);                                               \
5198        return NULL;                                                     \
5199    }                                                                    \
5200                                                                         \
5201    return result;                                                       \
5202}
5203
5204
5205/* Unary arithmetic functions */
5206DecCtx_UnaryFunc(mpd_qabs)
5207DecCtx_UnaryFunc(mpd_qexp)
5208DecCtx_UnaryFunc(mpd_qln)
5209DecCtx_UnaryFunc(mpd_qlog10)
5210DecCtx_UnaryFunc(mpd_qminus)
5211DecCtx_UnaryFunc(mpd_qnext_minus)
5212DecCtx_UnaryFunc(mpd_qnext_plus)
5213DecCtx_UnaryFunc(mpd_qplus)
5214DecCtx_UnaryFunc(mpd_qreduce)
5215DecCtx_UnaryFunc(mpd_qround_to_int)
5216DecCtx_UnaryFunc(mpd_qround_to_intx)
5217DecCtx_UnaryFunc(mpd_qsqrt)
5218
5219/* Binary arithmetic functions */
5220DecCtx_BinaryFunc(mpd_qadd)
5221DecCtx_BinaryFunc(mpd_qcompare)
5222DecCtx_BinaryFunc(mpd_qcompare_signal)
5223DecCtx_BinaryFunc(mpd_qdiv)
5224DecCtx_BinaryFunc(mpd_qdivint)
5225DecCtx_BinaryFunc(mpd_qmax)
5226DecCtx_BinaryFunc(mpd_qmax_mag)
5227DecCtx_BinaryFunc(mpd_qmin)
5228DecCtx_BinaryFunc(mpd_qmin_mag)
5229DecCtx_BinaryFunc(mpd_qmul)
5230DecCtx_BinaryFunc(mpd_qnext_toward)
5231DecCtx_BinaryFunc(mpd_qquantize)
5232DecCtx_BinaryFunc(mpd_qrem)
5233DecCtx_BinaryFunc(mpd_qrem_near)
5234DecCtx_BinaryFunc(mpd_qsub)
5235
5236static PyObject *
5237ctx_mpd_qdivmod(PyObject *context, PyObject *args)
5238{
5239    PyObject *v, *w;
5240    PyObject *a, *b;
5241    PyObject *q, *r;
5242    uint32_t status = 0;
5243    PyObject *ret;
5244
5245    if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5246        return NULL;
5247    }
5248
5249    CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5250
5251    q = dec_alloc();
5252    if (q == NULL) {
5253        Py_DECREF(a);
5254        Py_DECREF(b);
5255        return NULL;
5256    }
5257    r = dec_alloc();
5258    if (r == NULL) {
5259        Py_DECREF(a);
5260        Py_DECREF(b);
5261        Py_DECREF(q);
5262        return NULL;
5263    }
5264
5265    mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status);
5266    Py_DECREF(a);
5267    Py_DECREF(b);
5268    if (dec_addstatus(context, status)) {
5269        Py_DECREF(r);
5270        Py_DECREF(q);
5271        return NULL;
5272    }
5273
5274    ret = Py_BuildValue("(OO)", q, r);
5275    Py_DECREF(r);
5276    Py_DECREF(q);
5277    return ret;
5278}
5279
5280/* Binary or ternary arithmetic functions */
5281static PyObject *
5282ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
5283{
5284    static char *kwlist[] = {"a", "b", "modulo", NULL};
5285    PyObject *base, *exp, *mod = Py_None;
5286    PyObject *a, *b, *c = NULL;
5287    PyObject *result;
5288    uint32_t status = 0;
5289
5290    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,
5291                                     &base, &exp, &mod)) {
5292        return NULL;
5293    }
5294
5295    CONVERT_BINOP_RAISE(&a, &b, base, exp, context);
5296
5297    if (mod != Py_None) {
5298        if (!convert_op(TYPE_ERR, &c, mod, context)) {
5299            Py_DECREF(a);
5300            Py_DECREF(b);
5301            return c;
5302        }
5303    }
5304
5305    result = dec_alloc();
5306    if (result == NULL) {
5307        Py_DECREF(a);
5308        Py_DECREF(b);
5309        Py_XDECREF(c);
5310        return NULL;
5311    }
5312
5313    if (c == NULL) {
5314        mpd_qpow(MPD(result), MPD(a), MPD(b),
5315                 CTX(context), &status);
5316    }
5317    else {
5318        mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c),
5319                    CTX(context), &status);
5320        Py_DECREF(c);
5321    }
5322    Py_DECREF(a);
5323    Py_DECREF(b);
5324    if (dec_addstatus(context, status)) {
5325        Py_DECREF(result);
5326        return NULL;
5327    }
5328
5329    return result;
5330}
5331
5332/* Ternary arithmetic functions */
5333DecCtx_TernaryFunc(mpd_qfma)
5334
5335/* No argument */
5336static PyObject *
5337ctx_mpd_radix(PyObject *context, PyObject *dummy)
5338{
5339    return dec_mpd_radix(context, dummy);
5340}
5341
5342/* Boolean functions: single decimal argument */
5343DecCtx_BoolFunc(mpd_isnormal)
5344DecCtx_BoolFunc(mpd_issubnormal)
5345DecCtx_BoolFunc_NO_CTX(mpd_isfinite)
5346DecCtx_BoolFunc_NO_CTX(mpd_isinfinite)
5347DecCtx_BoolFunc_NO_CTX(mpd_isnan)
5348DecCtx_BoolFunc_NO_CTX(mpd_isqnan)
5349DecCtx_BoolFunc_NO_CTX(mpd_issigned)
5350DecCtx_BoolFunc_NO_CTX(mpd_issnan)
5351DecCtx_BoolFunc_NO_CTX(mpd_iszero)
5352
5353static PyObject *
5354ctx_iscanonical(PyObject *context UNUSED, PyObject *v)
5355{
5356    if (!PyDec_Check(v)) {
5357        PyErr_SetString(PyExc_TypeError,
5358            "argument must be a Decimal");
5359        return NULL;
5360    }
5361
5362    return mpd_iscanonical(MPD(v)) ? incr_true() : incr_false();
5363}
5364
5365/* Functions with a single decimal argument */
5366static PyObject *
5367PyDecContext_Apply(PyObject *context, PyObject *v)
5368{
5369    PyObject *result, *a;
5370
5371    CONVERT_OP_RAISE(&a, v, context);
5372
5373    result = dec_apply(a, context);
5374    Py_DECREF(a);
5375    return result;
5376}
5377
5378static PyObject *
5379ctx_canonical(PyObject *context UNUSED, PyObject *v)
5380{
5381    if (!PyDec_Check(v)) {
5382        PyErr_SetString(PyExc_TypeError,
5383            "argument must be a Decimal");
5384        return NULL;
5385    }
5386
5387    Py_INCREF(v);
5388    return v;
5389}
5390
5391static PyObject *
5392ctx_mpd_qcopy_abs(PyObject *context, PyObject *v)
5393{
5394    PyObject *result, *a;
5395    uint32_t status = 0;
5396
5397    CONVERT_OP_RAISE(&a, v, context);
5398
5399    result = dec_alloc();
5400    if (result == NULL) {
5401        Py_DECREF(a);
5402        return NULL;
5403    }
5404
5405    mpd_qcopy_abs(MPD(result), MPD(a), &status);
5406    Py_DECREF(a);
5407    if (dec_addstatus(context, status)) {
5408        Py_DECREF(result);
5409        return NULL;
5410    }
5411
5412    return result;
5413}
5414
5415static PyObject *
5416ctx_copy_decimal(PyObject *context, PyObject *v)
5417{
5418    PyObject *result;
5419
5420    CONVERT_OP_RAISE(&result, v, context);
5421    return result;
5422}
5423
5424static PyObject *
5425ctx_mpd_qcopy_negate(PyObject *context, PyObject *v)
5426{
5427    PyObject *result, *a;
5428    uint32_t status = 0;
5429
5430    CONVERT_OP_RAISE(&a, v, context);
5431
5432    result = dec_alloc();
5433    if (result == NULL) {
5434        Py_DECREF(a);
5435        return NULL;
5436    }
5437
5438    mpd_qcopy_negate(MPD(result), MPD(a), &status);
5439    Py_DECREF(a);
5440    if (dec_addstatus(context, status)) {
5441        Py_DECREF(result);
5442        return NULL;
5443    }
5444
5445    return result;
5446}
5447
5448DecCtx_UnaryFunc(mpd_qlogb)
5449DecCtx_UnaryFunc(mpd_qinvert)
5450
5451static PyObject *
5452ctx_mpd_class(PyObject *context, PyObject *v)
5453{
5454    PyObject *a;
5455    const char *cp;
5456
5457    CONVERT_OP_RAISE(&a, v, context);
5458
5459    cp = mpd_class(MPD(a), CTX(context));
5460    Py_DECREF(a);
5461
5462    return PyUnicode_FromString(cp);
5463}
5464
5465static PyObject *
5466ctx_mpd_to_sci(PyObject *context, PyObject *v)
5467{
5468    PyObject *result;
5469    PyObject *a;
5470    mpd_ssize_t size;
5471    char *s;
5472
5473    CONVERT_OP_RAISE(&a, v, context);
5474
5475    size = mpd_to_sci_size(&s, MPD(a), CtxCaps(context));
5476    Py_DECREF(a);
5477    if (size < 0) {
5478        PyErr_NoMemory();
5479        return NULL;
5480    }
5481
5482    result = unicode_fromascii(s, size);
5483    mpd_free(s);
5484
5485    return result;
5486}
5487
5488static PyObject *
5489ctx_mpd_to_eng(PyObject *context, PyObject *v)
5490{
5491    PyObject *result;
5492    PyObject *a;
5493    mpd_ssize_t size;
5494    char *s;
5495
5496    CONVERT_OP_RAISE(&a, v, context);
5497
5498    size = mpd_to_eng_size(&s, MPD(a), CtxCaps(context));
5499    Py_DECREF(a);
5500    if (size < 0) {
5501        PyErr_NoMemory();
5502        return NULL;
5503    }
5504
5505    result = unicode_fromascii(s, size);
5506    mpd_free(s);
5507
5508    return result;
5509}
5510
5511/* Functions with two decimal arguments */
5512DecCtx_BinaryFunc_NO_CTX(mpd_compare_total)
5513DecCtx_BinaryFunc_NO_CTX(mpd_compare_total_mag)
5514
5515static PyObject *
5516ctx_mpd_qcopy_sign(PyObject *context, PyObject *args)
5517{
5518    PyObject *v, *w;
5519    PyObject *a, *b;
5520    PyObject *result;
5521    uint32_t status = 0;
5522
5523    if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5524        return NULL;
5525    }
5526
5527    CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5528
5529    result = dec_alloc();
5530    if (result == NULL) {
5531        Py_DECREF(a);
5532        Py_DECREF(b);
5533        return NULL;
5534    }
5535
5536    mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
5537    Py_DECREF(a);
5538    Py_DECREF(b);
5539    if (dec_addstatus(context, status)) {
5540        Py_DECREF(result);
5541        return NULL;
5542    }
5543
5544    return result;
5545}
5546
5547DecCtx_BinaryFunc(mpd_qand)
5548DecCtx_BinaryFunc(mpd_qor)
5549DecCtx_BinaryFunc(mpd_qxor)
5550
5551DecCtx_BinaryFunc(mpd_qrotate)
5552DecCtx_BinaryFunc(mpd_qscaleb)
5553DecCtx_BinaryFunc(mpd_qshift)
5554
5555static PyObject *
5556ctx_mpd_same_quantum(PyObject *context, PyObject *args)
5557{
5558    PyObject *v, *w;
5559    PyObject *a, *b;
5560    PyObject *result;
5561
5562    if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5563        return NULL;
5564    }
5565
5566    CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5567
5568    result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false();
5569    Py_DECREF(a);
5570    Py_DECREF(b);
5571
5572    return result;
5573}
5574
5575
5576static PyMethodDef context_methods [] =
5577{
5578  /* Unary arithmetic functions */
5579  { "abs", ctx_mpd_qabs, METH_O, doc_ctx_abs },
5580  { "exp", ctx_mpd_qexp, METH_O, doc_ctx_exp },
5581  { "ln", ctx_mpd_qln, METH_O, doc_ctx_ln },
5582  { "log10", ctx_mpd_qlog10, METH_O, doc_ctx_log10 },
5583  { "minus", ctx_mpd_qminus, METH_O, doc_ctx_minus },
5584  { "next_minus", ctx_mpd_qnext_minus, METH_O, doc_ctx_next_minus },
5585  { "next_plus", ctx_mpd_qnext_plus, METH_O, doc_ctx_next_plus },
5586  { "normalize", ctx_mpd_qreduce, METH_O, doc_ctx_normalize },
5587  { "plus", ctx_mpd_qplus, METH_O, doc_ctx_plus },
5588  { "to_integral", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral },
5589  { "to_integral_exact", ctx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact },
5590  { "to_integral_value", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value },
5591  { "sqrt", ctx_mpd_qsqrt, METH_O, doc_ctx_sqrt },
5592
5593  /* Binary arithmetic functions */
5594  { "add", ctx_mpd_qadd, METH_VARARGS, doc_ctx_add },
5595  { "compare", ctx_mpd_qcompare, METH_VARARGS, doc_ctx_compare },
5596  { "compare_signal", ctx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal },
5597  { "divide", ctx_mpd_qdiv, METH_VARARGS, doc_ctx_divide },
5598  { "divide_int", ctx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int },
5599  { "divmod", ctx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod },
5600  { "max", ctx_mpd_qmax, METH_VARARGS, doc_ctx_max },
5601  { "max_mag", ctx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag },
5602  { "min", ctx_mpd_qmin, METH_VARARGS, doc_ctx_min },
5603  { "min_mag", ctx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag },
5604  { "multiply", ctx_mpd_qmul, METH_VARARGS, doc_ctx_multiply },
5605  { "next_toward", ctx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward },
5606  { "quantize", ctx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize },
5607  { "remainder", ctx_mpd_qrem, METH_VARARGS, doc_ctx_remainder },
5608  { "remainder_near", ctx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near },
5609  { "subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract },
5610
5611  /* Binary or ternary arithmetic functions */
5612  { "power", _PyCFunction_CAST(ctx_mpd_qpow), METH_VARARGS|METH_KEYWORDS, doc_ctx_power },
5613
5614  /* Ternary arithmetic functions */
5615  { "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma },
5616
5617  /* No argument */
5618  { "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny },
5619  { "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop },
5620  { "radix", ctx_mpd_radix, METH_NOARGS, doc_ctx_radix },
5621
5622  /* Boolean functions */
5623  { "is_canonical", ctx_iscanonical, METH_O, doc_ctx_is_canonical },
5624  { "is_finite", ctx_mpd_isfinite, METH_O, doc_ctx_is_finite },
5625  { "is_infinite", ctx_mpd_isinfinite, METH_O, doc_ctx_is_infinite },
5626  { "is_nan", ctx_mpd_isnan, METH_O, doc_ctx_is_nan },
5627  { "is_normal", ctx_mpd_isnormal, METH_O, doc_ctx_is_normal },
5628  { "is_qnan", ctx_mpd_isqnan, METH_O, doc_ctx_is_qnan },
5629  { "is_signed", ctx_mpd_issigned, METH_O, doc_ctx_is_signed },
5630  { "is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan },
5631  { "is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal },
5632  { "is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero },
5633
5634  /* Functions with a single decimal argument */
5635  { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */
5636#ifdef EXTRA_FUNCTIONALITY
5637  { "apply", PyDecContext_Apply, METH_O, doc_ctx_apply },
5638#endif
5639  { "canonical", ctx_canonical, METH_O, doc_ctx_canonical },
5640  { "copy_abs", ctx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs },
5641  { "copy_decimal", ctx_copy_decimal, METH_O, doc_ctx_copy_decimal },
5642  { "copy_negate", ctx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate },
5643  { "logb", ctx_mpd_qlogb, METH_O, doc_ctx_logb },
5644  { "logical_invert", ctx_mpd_qinvert, METH_O, doc_ctx_logical_invert },
5645  { "number_class", ctx_mpd_class, METH_O, doc_ctx_number_class },
5646  { "to_sci_string", ctx_mpd_to_sci, METH_O, doc_ctx_to_sci_string },
5647  { "to_eng_string", ctx_mpd_to_eng, METH_O, doc_ctx_to_eng_string },
5648
5649  /* Functions with two decimal arguments */
5650  { "compare_total", ctx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total },
5651  { "compare_total_mag", ctx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag },
5652  { "copy_sign", ctx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign },
5653  { "logical_and", ctx_mpd_qand, METH_VARARGS, doc_ctx_logical_and },
5654  { "logical_or", ctx_mpd_qor, METH_VARARGS, doc_ctx_logical_or },
5655  { "logical_xor", ctx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor },
5656  { "rotate", ctx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate },
5657  { "same_quantum", ctx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum },
5658  { "scaleb", ctx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb },
5659  { "shift", ctx_mpd_qshift, METH_VARARGS, doc_ctx_shift },
5660
5661  /* Set context values */
5662  { "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags },
5663  { "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps },
5664
5665#ifdef CONFIG_32
5666  /* Unsafe set functions with relaxed range checks */
5667  { "_unsafe_setprec", context_unsafe_setprec, METH_O, NULL },
5668  { "_unsafe_setemin", context_unsafe_setemin, METH_O, NULL },
5669  { "_unsafe_setemax", context_unsafe_setemax, METH_O, NULL },
5670#endif
5671
5672  /* Miscellaneous */
5673  { "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL },
5674  { "__reduce__", context_reduce, METH_NOARGS, NULL },
5675  { "copy", (PyCFunction)context_copy, METH_NOARGS, doc_ctx_copy },
5676  { "create_decimal", ctx_create_decimal, METH_VARARGS, doc_ctx_create_decimal },
5677  { "create_decimal_from_float", ctx_from_float, METH_O, doc_ctx_create_decimal_from_float },
5678
5679  { NULL, NULL, 1 }
5680};
5681
5682static PyTypeObject PyDecContext_Type =
5683{
5684    PyVarObject_HEAD_INIT(NULL, 0)
5685    "decimal.Context",                         /* tp_name */
5686    sizeof(PyDecContextObject),                /* tp_basicsize */
5687    0,                                         /* tp_itemsize */
5688    (destructor) context_dealloc,              /* tp_dealloc */
5689    0,                                         /* tp_vectorcall_offset */
5690    (getattrfunc) 0,                           /* tp_getattr */
5691    (setattrfunc) 0,                           /* tp_setattr */
5692    0,                                         /* tp_as_async */
5693    (reprfunc) context_repr,                   /* tp_repr */
5694    0,                                         /* tp_as_number */
5695    0,                                         /* tp_as_sequence */
5696    0,                                         /* tp_as_mapping */
5697    (hashfunc) 0,                              /* tp_hash */
5698    0,                                         /* tp_call */
5699    0,                                         /* tp_str */
5700    (getattrofunc) context_getattr,            /* tp_getattro */
5701    (setattrofunc) context_setattr,            /* tp_setattro */
5702    (PyBufferProcs *) 0,                       /* tp_as_buffer */
5703    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,    /* tp_flags */
5704    doc_context,                               /* tp_doc */
5705    0,                                         /* tp_traverse */
5706    0,                                         /* tp_clear */
5707    0,                                         /* tp_richcompare */
5708    0,                                         /* tp_weaklistoffset */
5709    0,                                         /* tp_iter */
5710    0,                                         /* tp_iternext */
5711    context_methods,                           /* tp_methods */
5712    0,                                         /* tp_members */
5713    context_getsets,                           /* tp_getset */
5714    0,                                         /* tp_base */
5715    0,                                         /* tp_dict */
5716    0,                                         /* tp_descr_get */
5717    0,                                         /* tp_descr_set */
5718    0,                                         /* tp_dictoffset */
5719    context_init,                              /* tp_init */
5720    0,                                         /* tp_alloc */
5721    context_new,                               /* tp_new */
5722    PyObject_Del,                              /* tp_free */
5723};
5724
5725
5726static PyMethodDef _decimal_methods [] =
5727{
5728  { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext},
5729  { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext},
5730  { "localcontext", _PyCFunction_CAST(ctxmanager_new), METH_VARARGS|METH_KEYWORDS, doc_localcontext},
5731#ifdef EXTRA_FUNCTIONALITY
5732  { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context},
5733#endif
5734  { NULL, NULL, 1, NULL }
5735};
5736
5737static struct PyModuleDef _decimal_module = {
5738    PyModuleDef_HEAD_INIT,
5739    "decimal",
5740    doc__decimal,
5741    -1,
5742    _decimal_methods,
5743    NULL,
5744    NULL,
5745    NULL,
5746    NULL
5747};
5748
5749struct ssize_constmap { const char *name; mpd_ssize_t val; };
5750static struct ssize_constmap ssize_constants [] = {
5751    {"MAX_PREC", MPD_MAX_PREC},
5752    {"MAX_EMAX", MPD_MAX_EMAX},
5753    {"MIN_EMIN",  MPD_MIN_EMIN},
5754    {"MIN_ETINY", MPD_MIN_ETINY},
5755    {NULL}
5756};
5757
5758struct int_constmap { const char *name; int val; };
5759static struct int_constmap int_constants [] = {
5760    /* int constants */
5761#ifdef EXTRA_FUNCTIONALITY
5762    {"DECIMAL32", MPD_DECIMAL32},
5763    {"DECIMAL64", MPD_DECIMAL64},
5764    {"DECIMAL128", MPD_DECIMAL128},
5765    {"IEEE_CONTEXT_MAX_BITS", MPD_IEEE_CONTEXT_MAX_BITS},
5766    /* int condition flags */
5767    {"DecClamped", MPD_Clamped},
5768    {"DecConversionSyntax", MPD_Conversion_syntax},
5769    {"DecDivisionByZero", MPD_Division_by_zero},
5770    {"DecDivisionImpossible", MPD_Division_impossible},
5771    {"DecDivisionUndefined", MPD_Division_undefined},
5772    {"DecFpuError", MPD_Fpu_error},
5773    {"DecInexact", MPD_Inexact},
5774    {"DecInvalidContext", MPD_Invalid_context},
5775    {"DecInvalidOperation", MPD_Invalid_operation},
5776    {"DecIEEEInvalidOperation", MPD_IEEE_Invalid_operation},
5777    {"DecMallocError", MPD_Malloc_error},
5778    {"DecFloatOperation", MPD_Float_operation},
5779    {"DecOverflow", MPD_Overflow},
5780    {"DecRounded", MPD_Rounded},
5781    {"DecSubnormal", MPD_Subnormal},
5782    {"DecUnderflow", MPD_Underflow},
5783    {"DecErrors", MPD_Errors},
5784    {"DecTraps", MPD_Traps},
5785#endif
5786    {NULL}
5787};
5788
5789
5790#define CHECK_INT(expr) \
5791    do { if ((expr) < 0) goto error; } while (0)
5792#define ASSIGN_PTR(result, expr) \
5793    do { result = (expr); if (result == NULL) goto error; } while (0)
5794#define CHECK_PTR(expr) \
5795    do { if ((expr) == NULL) goto error; } while (0)
5796
5797
5798static PyCFunction
5799cfunc_noargs(PyTypeObject *t, const char *name)
5800{
5801    struct PyMethodDef *m;
5802
5803    if (t->tp_methods == NULL) {
5804        goto error;
5805    }
5806
5807    for (m = t->tp_methods; m->ml_name != NULL; m++) {
5808        if (strcmp(name, m->ml_name) == 0) {
5809            if (!(m->ml_flags & METH_NOARGS)) {
5810                goto error;
5811            }
5812            return m->ml_meth;
5813        }
5814    }
5815
5816error:
5817    PyErr_Format(PyExc_RuntimeError,
5818        "internal error: could not find method %s", name);
5819    return NULL;
5820}
5821
5822
5823PyMODINIT_FUNC
5824PyInit__decimal(void)
5825{
5826    PyObject *m = NULL;
5827    PyObject *numbers = NULL;
5828    PyObject *Number = NULL;
5829    PyObject *collections = NULL;
5830    PyObject *collections_abc = NULL;
5831    PyObject *MutableMapping = NULL;
5832    PyObject *obj = NULL;
5833    DecCondMap *cm;
5834    struct ssize_constmap *ssize_cm;
5835    struct int_constmap *int_cm;
5836    int i;
5837
5838
5839    /* Init libmpdec */
5840    mpd_traphandler = dec_traphandler;
5841    mpd_mallocfunc = PyMem_Malloc;
5842    mpd_reallocfunc = PyMem_Realloc;
5843    mpd_callocfunc = mpd_callocfunc_em;
5844    mpd_free = PyMem_Free;
5845    mpd_setminalloc(_Py_DEC_MINALLOC);
5846
5847
5848    /* Init external C-API functions */
5849    _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply;
5850    _py_long_floor_divide = PyLong_Type.tp_as_number->nb_floor_divide;
5851    _py_long_power = PyLong_Type.tp_as_number->nb_power;
5852    _py_float_abs = PyFloat_Type.tp_as_number->nb_absolute;
5853    ASSIGN_PTR(_py_float_as_integer_ratio, cfunc_noargs(&PyFloat_Type,
5854                                                        "as_integer_ratio"));
5855    ASSIGN_PTR(_py_long_bit_length, cfunc_noargs(&PyLong_Type, "bit_length"));
5856
5857
5858    /* Init types */
5859    PyDec_Type.tp_base = &PyBaseObject_Type;
5860    PyDecContext_Type.tp_base = &PyBaseObject_Type;
5861    PyDecContextManager_Type.tp_base = &PyBaseObject_Type;
5862    PyDecSignalDictMixin_Type.tp_base = &PyBaseObject_Type;
5863
5864    CHECK_INT(PyType_Ready(&PyDec_Type));
5865    CHECK_INT(PyType_Ready(&PyDecContext_Type));
5866    CHECK_INT(PyType_Ready(&PyDecSignalDictMixin_Type));
5867    CHECK_INT(PyType_Ready(&PyDecContextManager_Type));
5868
5869    ASSIGN_PTR(obj, PyUnicode_FromString("decimal"));
5870    CHECK_INT(PyDict_SetItemString(PyDec_Type.tp_dict, "__module__", obj));
5871    CHECK_INT(PyDict_SetItemString(PyDecContext_Type.tp_dict,
5872                                   "__module__", obj));
5873    Py_CLEAR(obj);
5874
5875
5876    /* Numeric abstract base classes */
5877    ASSIGN_PTR(numbers, PyImport_ImportModule("numbers"));
5878    ASSIGN_PTR(Number, PyObject_GetAttrString(numbers, "Number"));
5879    /* Register Decimal with the Number abstract base class */
5880    ASSIGN_PTR(obj, PyObject_CallMethod(Number, "register", "(O)",
5881                                        (PyObject *)&PyDec_Type));
5882    Py_CLEAR(obj);
5883    /* Rational is a global variable used for fraction comparisons. */
5884    ASSIGN_PTR(Rational, PyObject_GetAttrString(numbers, "Rational"));
5885    /* Done with numbers, Number */
5886    Py_CLEAR(numbers);
5887    Py_CLEAR(Number);
5888
5889    /* DecimalTuple */
5890    ASSIGN_PTR(collections, PyImport_ImportModule("collections"));
5891    ASSIGN_PTR(DecimalTuple, (PyTypeObject *)PyObject_CallMethod(collections,
5892                                 "namedtuple", "(ss)", "DecimalTuple",
5893                                 "sign digits exponent"));
5894
5895    ASSIGN_PTR(obj, PyUnicode_FromString("decimal"));
5896    CHECK_INT(PyDict_SetItemString(DecimalTuple->tp_dict, "__module__", obj));
5897    Py_CLEAR(obj);
5898
5899    /* MutableMapping */
5900    ASSIGN_PTR(collections_abc, PyImport_ImportModule("collections.abc"));
5901    ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections_abc,
5902                                                      "MutableMapping"));
5903    /* Create SignalDict type */
5904    ASSIGN_PTR(PyDecSignalDict_Type,
5905                   (PyTypeObject *)PyObject_CallFunction(
5906                   (PyObject *)&PyType_Type, "s(OO){}",
5907                   "SignalDict", &PyDecSignalDictMixin_Type,
5908                   MutableMapping));
5909
5910    /* Done with collections, MutableMapping */
5911    Py_CLEAR(collections);
5912    Py_CLEAR(collections_abc);
5913    Py_CLEAR(MutableMapping);
5914
5915
5916    /* Create the module */
5917    ASSIGN_PTR(m, PyModule_Create(&_decimal_module));
5918
5919
5920    /* Add types to the module */
5921    Py_INCREF(&PyDec_Type);
5922    CHECK_INT(PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type));
5923    Py_INCREF(&PyDecContext_Type);
5924    CHECK_INT(PyModule_AddObject(m, "Context",
5925                                 (PyObject *)&PyDecContext_Type));
5926    Py_INCREF(DecimalTuple);
5927    CHECK_INT(PyModule_AddObject(m, "DecimalTuple", (PyObject *)DecimalTuple));
5928
5929
5930    /* Create top level exception */
5931    ASSIGN_PTR(DecimalException, PyErr_NewException(
5932                                     "decimal.DecimalException",
5933                                     PyExc_ArithmeticError, NULL));
5934    Py_INCREF(DecimalException);
5935    CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException));
5936
5937    /* Create signal tuple */
5938    ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN));
5939
5940    /* Add exceptions that correspond to IEEE signals */
5941    for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) {
5942        PyObject *base;
5943
5944        cm = signal_map + i;
5945
5946        switch (cm->flag) {
5947        case MPD_Float_operation:
5948            base = PyTuple_Pack(2, DecimalException, PyExc_TypeError);
5949            break;
5950        case MPD_Division_by_zero:
5951            base = PyTuple_Pack(2, DecimalException, PyExc_ZeroDivisionError);
5952            break;
5953        case MPD_Overflow:
5954            base = PyTuple_Pack(2, signal_map[INEXACT].ex,
5955                                   signal_map[ROUNDED].ex);
5956            break;
5957        case MPD_Underflow:
5958            base = PyTuple_Pack(3, signal_map[INEXACT].ex,
5959                                   signal_map[ROUNDED].ex,
5960                                   signal_map[SUBNORMAL].ex);
5961            break;
5962        default:
5963            base = PyTuple_Pack(1, DecimalException);
5964            break;
5965        }
5966
5967        if (base == NULL) {
5968            goto error; /* GCOV_NOT_REACHED */
5969        }
5970
5971        ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL));
5972        Py_DECREF(base);
5973
5974        /* add to module */
5975        Py_INCREF(cm->ex);
5976        CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex));
5977
5978        /* add to signal tuple */
5979        Py_INCREF(cm->ex);
5980        PyTuple_SET_ITEM(SignalTuple, i, cm->ex);
5981    }
5982
5983    /*
5984     * Unfortunately, InvalidOperation is a signal that comprises
5985     * several conditions, including InvalidOperation! Naming the
5986     * signal IEEEInvalidOperation would prevent the confusion.
5987     */
5988    cond_map[0].ex = signal_map[0].ex;
5989
5990    /* Add remaining exceptions, inherit from InvalidOperation */
5991    for (cm = cond_map+1; cm->name != NULL; cm++) {
5992        PyObject *base;
5993        if (cm->flag == MPD_Division_undefined) {
5994            base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError);
5995        }
5996        else {
5997            base = PyTuple_Pack(1, signal_map[0].ex);
5998        }
5999        if (base == NULL) {
6000            goto error; /* GCOV_NOT_REACHED */
6001        }
6002
6003        ASSIGN_PTR(cm->ex, PyErr_NewException(cm->fqname, base, NULL));
6004        Py_DECREF(base);
6005
6006        Py_INCREF(cm->ex);
6007        CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex));
6008    }
6009
6010
6011    /* Init default context template first */
6012    ASSIGN_PTR(default_context_template,
6013               PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
6014    Py_INCREF(default_context_template);
6015    CHECK_INT(PyModule_AddObject(m, "DefaultContext",
6016                                 default_context_template));
6017
6018#ifndef WITH_DECIMAL_CONTEXTVAR
6019    ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__"));
6020    Py_INCREF(Py_False);
6021    CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_False));
6022#else
6023    ASSIGN_PTR(current_context_var, PyContextVar_New("decimal_context", NULL));
6024    Py_INCREF(Py_True);
6025    CHECK_INT(PyModule_AddObject(m, "HAVE_CONTEXTVAR", Py_True));
6026#endif
6027    Py_INCREF(Py_True);
6028    CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True));
6029
6030    /* Init basic context template */
6031    ASSIGN_PTR(basic_context_template,
6032               PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
6033    init_basic_context(basic_context_template);
6034    Py_INCREF(basic_context_template);
6035    CHECK_INT(PyModule_AddObject(m, "BasicContext",
6036                                 basic_context_template));
6037
6038    /* Init extended context template */
6039    ASSIGN_PTR(extended_context_template,
6040               PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
6041    init_extended_context(extended_context_template);
6042    Py_INCREF(extended_context_template);
6043    CHECK_INT(PyModule_AddObject(m, "ExtendedContext",
6044                                 extended_context_template));
6045
6046
6047    /* Init mpd_ssize_t constants */
6048    for (ssize_cm = ssize_constants; ssize_cm->name != NULL; ssize_cm++) {
6049        ASSIGN_PTR(obj, PyLong_FromSsize_t(ssize_cm->val));
6050        CHECK_INT(PyModule_AddObject(m, ssize_cm->name, obj));
6051        obj = NULL;
6052    }
6053
6054    /* Init int constants */
6055    for (int_cm = int_constants; int_cm->name != NULL; int_cm++) {
6056        CHECK_INT(PyModule_AddIntConstant(m, int_cm->name,
6057                                          int_cm->val));
6058    }
6059
6060    /* Init string constants */
6061    for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
6062        ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i]));
6063        Py_INCREF(round_map[i]);
6064        CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], round_map[i]));
6065    }
6066
6067    /* Add specification version number */
6068    CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70"));
6069    CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
6070
6071
6072    return m;
6073
6074
6075error:
6076    Py_CLEAR(obj); /* GCOV_NOT_REACHED */
6077    Py_CLEAR(numbers); /* GCOV_NOT_REACHED */
6078    Py_CLEAR(Number); /* GCOV_NOT_REACHED */
6079    Py_CLEAR(Rational); /* GCOV_NOT_REACHED */
6080    Py_CLEAR(collections); /* GCOV_NOT_REACHED */
6081    Py_CLEAR(collections_abc); /* GCOV_NOT_REACHED */
6082    Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */
6083    Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */
6084    Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */
6085    Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */
6086#ifndef WITH_DECIMAL_CONTEXTVAR
6087    Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */
6088#else
6089    Py_CLEAR(current_context_var); /* GCOV_NOT_REACHED */
6090#endif
6091    Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */
6092    Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */
6093    Py_CLEAR(m); /* GCOV_NOT_REACHED */
6094
6095    return NULL; /* GCOV_NOT_REACHED */
6096}
6097