2
* Copyright (c) 2008-2012 Stefan Krah. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
8
* 1. Redistributions of source code must retain the above copyright
9
* notice, this list of conditions and the following disclaimer.
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.
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
30
#include "longintrepr.h"
32
#include "structmember.h"
33
#include "complexobject.h"
34
#include "mpdecimal.h"
38
#include "docstrings.h"
43
* Type sizes with assertions in mpdecimal.h and pyport.h:
44
* sizeof(size_t) == sizeof(Py_ssize_t)
45
* sizeof(size_t) == sizeof(mpd_uint_t) == sizeof(mpd_ssize_t)
49
#undef Py_LOCAL_INLINE
50
#define Py_LOCAL_INLINE Py_LOCAL
53
#define MPD_Float_operation MPD_Not_implemented
55
#define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x
58
/* _Py_DEC_MINALLOC >= MPD_MINALLOC */
59
#define _Py_DEC_MINALLOC 4
65
mpd_uint_t data[_Py_DEC_MINALLOC];
71
} PyDecSignalDictObject;
79
#ifndef WITHOUT_THREADS
80
PyThreadState *tstate;
88
} PyDecContextManagerObject;
93
static PyTypeObject PyDec_Type;
94
static PyTypeObject *PyDecSignalDict_Type;
95
static PyTypeObject PyDecContext_Type;
96
static PyTypeObject PyDecContextManager_Type;
97
#define PyDec_CheckExact(v) (Py_TYPE(v) == &PyDec_Type)
98
#define PyDec_Check(v) PyObject_TypeCheck(v, &PyDec_Type)
99
#define PyDecSignalDict_Check(v) (Py_TYPE(v) == PyDecSignalDict_Type)
100
#define PyDecContext_Check(v) PyObject_TypeCheck(v, &PyDecContext_Type)
101
#define MPD(v) (&((PyDecObject *)v)->dec)
102
#define SdFlagAddr(v) (((PyDecSignalDictObject *)v)->flags)
103
#define SdFlags(v) (*((PyDecSignalDictObject *)v)->flags)
104
#define CTX(v) (&((PyDecContextObject *)v)->ctx)
105
#define CtxCaps(v) (((PyDecContextObject *)v)->capitals)
108
Py_LOCAL_INLINE(PyObject *)
115
Py_LOCAL_INLINE(PyObject *)
123
#ifdef WITHOUT_THREADS
124
/* Default module context */
125
static PyObject *module_context = NULL;
127
/* Key for thread state dictionary */
128
static PyObject *tls_context_key = NULL;
129
/* Invariant: NULL or the most recently accessed thread local context */
130
static PyDecContextObject *cached_context = NULL;
133
/* Template for creating new thread contexts, calling Context() without
134
* arguments and initializing the module_context on first access. */
135
static PyObject *default_context_template = NULL;
136
/* Basic and extended context templates */
137
static PyObject *basic_context_template = NULL;
138
static PyObject *extended_context_template = NULL;
141
/* Error codes for functions that return signals or conditions */
142
#define DEC_INVALID_SIGNALS (MPD_Max_status+1U)
143
#define DEC_ERR_OCCURRED (DEC_INVALID_SIGNALS<<1)
144
#define DEC_ERRORS (DEC_INVALID_SIGNALS|DEC_ERR_OCCURRED)
147
const char *name; /* condition or signal name */
148
const char *fqname; /* fully qualified name */
149
uint32_t flag; /* libmpdec flag */
150
PyObject *ex; /* corresponding exception */
153
/* Top level Exception; inherits from ArithmeticError */
154
static PyObject *DecimalException = NULL;
156
/* Exceptions that correspond to IEEE signals */
160
#define SIGNAL_MAP_LEN 9
161
static DecCondMap signal_map[] = {
162
{"InvalidOperation", "decimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL},
163
{"FloatOperation", "decimal.FloatOperation", MPD_Float_operation, NULL},
164
{"DivisionByZero", "decimal.DivisionByZero", MPD_Division_by_zero, NULL},
165
{"Overflow", "decimal.Overflow", MPD_Overflow, NULL},
166
{"Underflow", "decimal.Underflow", MPD_Underflow, NULL},
167
{"Subnormal", "decimal.Subnormal", MPD_Subnormal, NULL},
168
{"Inexact", "decimal.Inexact", MPD_Inexact, NULL},
169
{"Rounded", "decimal.Rounded", MPD_Rounded, NULL},
170
{"Clamped", "decimal.Clamped", MPD_Clamped, NULL},
174
/* Exceptions that inherit from InvalidOperation */
175
static DecCondMap cond_map[] = {
176
{"InvalidOperation", "decimal.InvalidOperation", MPD_Invalid_operation, NULL},
177
{"ConversionSyntax", "decimal.ConversionSyntax", MPD_Conversion_syntax, NULL},
178
{"DivisionImpossible", "decimal.DivisionImpossible", MPD_Division_impossible, NULL},
179
{"DivisionUndefined", "decimal.DivisionUndefined", MPD_Division_undefined, NULL},
180
{"InvalidContext", "decimal.InvalidContext", MPD_Invalid_context, NULL},
181
#ifdef EXTRA_FUNCTIONALITY
182
{"MallocError", "decimal.MallocError", MPD_Malloc_error, NULL},
187
static const char *dec_signal_string[MPD_NUM_FLAGS] = {
205
#ifdef EXTRA_FUNCTIONALITY
206
#define _PY_DEC_ROUND_GUARD MPD_ROUND_GUARD
208
#define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1)
210
static PyObject *round_map[_PY_DEC_ROUND_GUARD];
212
static const char *invalid_rounding_err =
213
"valid values for rounding are:\n\
214
[ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\
215
ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\
218
static const char *invalid_signals_err =
219
"valid values for signals are:\n\
220
[InvalidOperation, FloatOperation, DivisionByZero,\n\
221
Overflow, Underflow, Subnormal, Inexact, Rounded,\n\
224
#ifdef EXTRA_FUNCTIONALITY
225
static const char *invalid_flags_err =
226
"valid values for _flags or _traps are:\n\
228
[DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\
229
DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\
231
conditions which trigger DecIEEEInvalidOperation:\n\
232
[DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\
233
DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]";
237
value_error_int(const char *mesg)
239
PyErr_SetString(PyExc_ValueError, mesg);
245
value_error_ptr(const char *mesg)
247
PyErr_SetString(PyExc_ValueError, mesg);
253
type_error_int(const char *mesg)
255
PyErr_SetString(PyExc_TypeError, mesg);
260
runtime_error_int(const char *mesg)
262
PyErr_SetString(PyExc_RuntimeError, mesg);
265
#define INTERNAL_ERROR_INT(funcname) \
266
return runtime_error_int("internal error in " funcname)
269
runtime_error_ptr(const char *mesg)
271
PyErr_SetString(PyExc_RuntimeError, mesg);
274
#define INTERNAL_ERROR_PTR(funcname) \
275
return runtime_error_ptr("internal error in " funcname)
278
dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */
279
{ /* GCOV_NOT_REACHED */
280
return; /* GCOV_NOT_REACHED */
284
flags_as_exception(uint32_t flags)
288
for (cm = signal_map; cm->name != NULL; cm++) {
289
if (flags&cm->flag) {
294
INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */
297
Py_LOCAL_INLINE(uint32_t)
298
exception_as_flag(PyObject *ex)
302
for (cm = signal_map; cm->name != NULL; cm++) {
308
PyErr_SetString(PyExc_KeyError, invalid_signals_err);
309
return DEC_INVALID_SIGNALS;
313
flags_as_list(uint32_t flags)
318
list = PyList_New(0);
323
for (cm = cond_map; cm->name != NULL; cm++) {
324
if (flags&cm->flag) {
325
if (PyList_Append(list, cm->ex) < 0) {
330
for (cm = signal_map+1; cm->name != NULL; cm++) {
331
if (flags&cm->flag) {
332
if (PyList_Append(list, cm->ex) < 0) {
346
signals_as_list(uint32_t flags)
351
list = PyList_New(0);
356
for (cm = signal_map; cm->name != NULL; cm++) {
357
if (flags&cm->flag) {
358
if (PyList_Append(list, cm->ex) < 0) {
369
list_as_flags(PyObject *list)
375
assert(PyList_Check(list));
377
n = PyList_Size(list);
379
for (j = 0; j < n; j++) {
380
item = PyList_GetItem(list, j);
381
x = exception_as_flag(item);
382
if (x & DEC_ERRORS) {
392
flags_as_dict(uint32_t flags)
402
for (cm = signal_map; cm->name != NULL; cm++) {
403
PyObject *b = flags&cm->flag ? Py_True : Py_False;
404
if (PyDict_SetItem(dict, cm->ex, b) < 0) {
414
dict_as_flags(PyObject *val)
421
if (!PyDict_Check(val)) {
422
PyErr_SetString(PyExc_TypeError,
423
"argument must be a signal dict");
424
return DEC_INVALID_SIGNALS;
427
if (PyDict_Size(val) != SIGNAL_MAP_LEN) {
428
PyErr_SetString(PyExc_KeyError,
429
"invalid signal dict");
430
return DEC_INVALID_SIGNALS;
433
for (cm = signal_map; cm->name != NULL; cm++) {
434
b = PyDict_GetItemWithError(val, cm->ex);
436
if (PyErr_Occurred()) {
437
return DEC_ERR_OCCURRED;
439
PyErr_SetString(PyExc_KeyError,
440
"invalid signal dict");
441
return DEC_INVALID_SIGNALS;
444
x = PyObject_IsTrue(b);
446
return DEC_ERR_OCCURRED;
456
#ifdef EXTRA_FUNCTIONALITY
458
long_as_flags(PyObject *v)
462
x = PyLong_AsLong(v);
463
if (x == -1 && PyErr_Occurred()) {
464
return DEC_ERR_OCCURRED;
466
if (x < 0 || x > (long)MPD_Max_status) {
467
PyErr_SetString(PyExc_TypeError, invalid_flags_err);
468
return DEC_INVALID_SIGNALS;
476
dec_addstatus(PyObject *context, uint32_t status)
478
mpd_context_t *ctx = CTX(context);
480
ctx->status |= status;
481
if (status & (ctx->traps|MPD_Malloc_error)) {
482
PyObject *ex, *siglist;
484
if (status & MPD_Malloc_error) {
489
ex = flags_as_exception(ctx->traps&status);
491
return 1; /* GCOV_NOT_REACHED */
493
siglist = flags_as_list(ctx->traps&status);
494
if (siglist == NULL) {
498
PyErr_SetObject(ex, siglist);
506
getround(PyObject *v)
510
if (PyUnicode_Check(v)) {
511
for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
512
if (v == round_map[i]) {
516
for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
517
if (PyUnicode_Compare(v, round_map[i]) == 0) {
523
return type_error_int(invalid_rounding_err);
527
/******************************************************************************/
528
/* SignalDict Object */
529
/******************************************************************************/
531
/* The SignalDict is a MutableMapping that provides access to the
532
mpd_context_t flags, which reside in the context object. When a
533
new context is created, context.traps and context.flags are
534
initialized to new SignalDicts. Once a SignalDict is tied to
535
a context, it cannot be deleted. */
538
signaldict_init(PyObject *self, PyObject *args UNUSED, PyObject *kwds UNUSED)
540
SdFlagAddr(self) = NULL;
545
signaldict_len(PyObject *self UNUSED)
547
return SIGNAL_MAP_LEN;
550
static PyObject *SignalTuple;
552
signaldict_iter(PyObject *self UNUSED)
554
return PyTuple_Type.tp_iter(SignalTuple);
558
signaldict_getitem(PyObject *self, PyObject *key)
562
flag = exception_as_flag(key);
563
if (flag & DEC_ERRORS) {
567
return SdFlags(self)&flag ? incr_true() : incr_false();
571
signaldict_setitem(PyObject *self, PyObject *key, PyObject *value)
577
return value_error_int("signal keys cannot be deleted");
580
flag = exception_as_flag(key);
581
if (flag & DEC_ERRORS) {
585
x = PyObject_IsTrue(value);
591
SdFlags(self) |= flag;
594
SdFlags(self) &= ~flag;
601
signaldict_repr(PyObject *self)
604
const char *n[SIGNAL_MAP_LEN]; /* name */
605
const char *b[SIGNAL_MAP_LEN]; /* bool */
608
assert(SIGNAL_MAP_LEN == 9);
610
for (cm=signal_map, i=0; cm->name != NULL; cm++, i++) {
612
b[i] = SdFlags(self)&cm->flag ? "True" : "False";
614
return PyUnicode_FromFormat(
615
"{<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
616
"<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s, "
617
"<class '%s'>:%s, <class '%s'>:%s, <class '%s'>:%s}",
618
n[0], b[0], n[1], b[1], n[2], b[2],
619
n[3], b[3], n[4], b[4], n[5], b[5],
620
n[6], b[6], n[7], b[7], n[8], b[8]);
624
signaldict_richcompare(PyObject *v, PyObject *w, int op)
626
PyObject *res = Py_NotImplemented;
628
assert(PyDecSignalDict_Check(v));
630
if (op == Py_EQ || op == Py_NE) {
631
if (PyDecSignalDict_Check(w)) {
632
res = (SdFlags(v)==SdFlags(w)) ^ (op==Py_NE) ? Py_True : Py_False;
634
else if (PyDict_Check(w)) {
635
uint32_t flags = dict_as_flags(w);
636
if (flags & DEC_ERRORS) {
637
if (flags & DEC_INVALID_SIGNALS) {
638
/* non-comparable: Py_NotImplemented */
646
res = (SdFlags(v)==flags) ^ (op==Py_NE) ? Py_True : Py_False;
656
signaldict_copy(PyObject *self, PyObject *args UNUSED)
658
return flags_as_dict(SdFlags(self));
662
static PyMappingMethods signaldict_as_mapping = {
663
(lenfunc)signaldict_len, /* mp_length */
664
(binaryfunc)signaldict_getitem, /* mp_subscript */
665
(objobjargproc)signaldict_setitem /* mp_ass_subscript */
668
static PyMethodDef signaldict_methods[] = {
669
{ "copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL},
674
static PyTypeObject PyDecSignalDictMixin_Type =
676
PyVarObject_HEAD_INIT(0, 0)
677
"decimal.SignalDictMixin", /* tp_name */
678
sizeof(PyDecSignalDictObject), /* tp_basicsize */
682
(getattrfunc) 0, /* tp_getattr */
683
(setattrfunc) 0, /* tp_setattr */
685
(reprfunc) signaldict_repr, /* tp_repr */
686
0, /* tp_as_number */
687
0, /* tp_as_sequence */
688
&signaldict_as_mapping, /* tp_as_mapping */
689
PyObject_HashNotImplemented, /* tp_hash */
691
(reprfunc) 0, /* tp_str */
692
PyObject_GenericGetAttr, /* tp_getattro */
693
(setattrofunc) 0, /* tp_setattro */
694
(PyBufferProcs *) 0, /* tp_as_buffer */
695
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|
696
Py_TPFLAGS_HAVE_GC, /* tp_flags */
700
signaldict_richcompare, /* tp_richcompare */
701
0, /* tp_weaklistoffset */
702
(getiterfunc)signaldict_iter, /* tp_iter */
704
signaldict_methods, /* tp_methods */
709
0, /* tp_descr_get */
710
0, /* tp_descr_set */
711
0, /* tp_dictoffset */
712
(initproc)signaldict_init, /* tp_init */
714
PyType_GenericNew, /* tp_new */
718
/******************************************************************************/
719
/* Context Object, Part 1 */
720
/******************************************************************************/
722
#define Dec_CONTEXT_GET_SSIZE(mem) \
724
context_get##mem(PyObject *self, void *closure UNUSED) \
726
return PyLong_FromSsize_t(mpd_get##mem(CTX(self))); \
729
#define Dec_CONTEXT_GET_ULONG(mem) \
731
context_get##mem(PyObject *self, void *closure UNUSED) \
733
return PyLong_FromUnsignedLong(mpd_get##mem(CTX(self))); \
736
Dec_CONTEXT_GET_SSIZE(prec)
737
Dec_CONTEXT_GET_SSIZE(emax)
738
Dec_CONTEXT_GET_SSIZE(emin)
739
Dec_CONTEXT_GET_SSIZE(clamp)
741
#ifdef EXTRA_FUNCTIONALITY
742
Dec_CONTEXT_GET_ULONG(traps)
743
Dec_CONTEXT_GET_ULONG(status)
747
context_getround(PyObject *self, void *closure UNUSED)
749
int i = mpd_getround(CTX(self));
751
Py_INCREF(round_map[i]);
756
context_getcapitals(PyObject *self, void *closure UNUSED)
758
return PyLong_FromLong(CtxCaps(self));
761
#ifdef EXTRA_FUNCTIONALITY
763
context_getallcr(PyObject *self, void *closure UNUSED)
765
return PyLong_FromLong(mpd_getcr(CTX(self)));
770
context_getetiny(PyObject *self, PyObject *dummy UNUSED)
772
return PyLong_FromSsize_t(mpd_etiny(CTX(self)));
776
context_getetop(PyObject *self, PyObject *dummy UNUSED)
778
return PyLong_FromSsize_t(mpd_etop(CTX(self)));
782
context_setprec(PyObject *self, PyObject *value, void *closure UNUSED)
787
x = PyLong_AsSsize_t(value);
788
if (x == -1 && PyErr_Occurred()) {
793
if (!mpd_qsetprec(ctx, x)) {
794
return value_error_int(
795
"valid range for prec is [1, MAX_PREC]");
802
context_setemin(PyObject *self, PyObject *value, void *closure UNUSED)
807
x = PyLong_AsSsize_t(value);
808
if (x == -1 && PyErr_Occurred()) {
813
if (!mpd_qsetemin(ctx, x)) {
814
return value_error_int(
815
"valid range for Emin is [MIN_EMIN, 0]");
822
context_setemax(PyObject *self, PyObject *value, void *closure UNUSED)
827
x = PyLong_AsSsize_t(value);
828
if (x == -1 && PyErr_Occurred()) {
833
if (!mpd_qsetemax(ctx, x)) {
834
return value_error_int(
835
"valid range for Emax is [0, MAX_EMAX]");
843
context_unsafe_setprec(PyObject *self, PyObject *value)
845
mpd_context_t *ctx = CTX(self);
848
x = PyLong_AsSsize_t(value);
849
if (x == -1 && PyErr_Occurred()) {
853
if (x < 1 || x > 1070000000L) {
854
return value_error_ptr(
855
"valid range for unsafe prec is [1, 1070000000]");
863
context_unsafe_setemin(PyObject *self, PyObject *value)
865
mpd_context_t *ctx = CTX(self);
868
x = PyLong_AsSsize_t(value);
869
if (x == -1 && PyErr_Occurred()) {
873
if (x < -1070000000L || x > 0) {
874
return value_error_ptr(
875
"valid range for unsafe emin is [-1070000000, 0]");
883
context_unsafe_setemax(PyObject *self, PyObject *value)
885
mpd_context_t *ctx = CTX(self);
888
x = PyLong_AsSsize_t(value);
889
if (x == -1 && PyErr_Occurred()) {
893
if (x < 0 || x > 1070000000L) {
894
return value_error_ptr(
895
"valid range for unsafe emax is [0, 1070000000]");
904
context_setround(PyObject *self, PyObject *value, void *closure UNUSED)
915
if (!mpd_qsetround(ctx, x)) {
916
INTERNAL_ERROR_INT("context_setround"); /* GCOV_NOT_REACHED */
923
context_setcapitals(PyObject *self, PyObject *value, void *closure UNUSED)
927
x = PyLong_AsSsize_t(value);
928
if (x == -1 && PyErr_Occurred()) {
932
if (x != 0 && x != 1) {
933
return value_error_int(
934
"valid values for capitals are 0 or 1");
936
CtxCaps(self) = (int)x;
941
#ifdef EXTRA_FUNCTIONALITY
943
context_settraps(PyObject *self, PyObject *value, void *closure UNUSED)
948
flags = long_as_flags(value);
949
if (flags & DEC_ERRORS) {
954
if (!mpd_qsettraps(ctx, flags)) {
955
INTERNAL_ERROR_INT("context_settraps");
963
context_settraps_list(PyObject *self, PyObject *value)
968
flags = list_as_flags(value);
969
if (flags & DEC_ERRORS) {
974
if (!mpd_qsettraps(ctx, flags)) {
975
INTERNAL_ERROR_INT("context_settraps_list");
982
context_settraps_dict(PyObject *self, PyObject *value)
987
if (PyDecSignalDict_Check(value)) {
988
flags = SdFlags(value);
991
flags = dict_as_flags(value);
992
if (flags & DEC_ERRORS) {
998
if (!mpd_qsettraps(ctx, flags)) {
999
INTERNAL_ERROR_INT("context_settraps_dict");
1005
#ifdef EXTRA_FUNCTIONALITY
1007
context_setstatus(PyObject *self, PyObject *value, void *closure UNUSED)
1012
flags = long_as_flags(value);
1013
if (flags & DEC_ERRORS) {
1018
if (!mpd_qsetstatus(ctx, flags)) {
1019
INTERNAL_ERROR_INT("context_setstatus");
1027
context_setstatus_list(PyObject *self, PyObject *value)
1032
flags = list_as_flags(value);
1033
if (flags & DEC_ERRORS) {
1038
if (!mpd_qsetstatus(ctx, flags)) {
1039
INTERNAL_ERROR_INT("context_setstatus_list");
1046
context_setstatus_dict(PyObject *self, PyObject *value)
1051
if (PyDecSignalDict_Check(value)) {
1052
flags = SdFlags(value);
1055
flags = dict_as_flags(value);
1056
if (flags & DEC_ERRORS) {
1062
if (!mpd_qsetstatus(ctx, flags)) {
1063
INTERNAL_ERROR_INT("context_setstatus_dict");
1070
context_setclamp(PyObject *self, PyObject *value, void *closure UNUSED)
1075
x = PyLong_AsSsize_t(value);
1076
if (x == -1 && PyErr_Occurred()) {
1079
BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1082
if (!mpd_qsetclamp(ctx, (int)x)) {
1083
return value_error_int("valid values for clamp are 0 or 1");
1089
#ifdef EXTRA_FUNCTIONALITY
1091
context_setallcr(PyObject *self, PyObject *value, void *closure UNUSED)
1096
x = PyLong_AsSsize_t(value);
1097
if (x == -1 && PyErr_Occurred()) {
1100
BOUNDS_CHECK(x, INT_MIN, INT_MAX);
1103
if (!mpd_qsetcr(ctx, (int)x)) {
1104
return value_error_int("valid values for _allcr are 0 or 1");
1112
context_getattr(PyObject *self, PyObject *name)
1116
if (PyUnicode_Check(name)) {
1117
if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1118
retval = ((PyDecContextObject *)self)->traps;
1122
if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1123
retval = ((PyDecContextObject *)self)->flags;
1129
return PyObject_GenericGetAttr(self, name);
1133
context_setattr(PyObject *self, PyObject *name, PyObject *value)
1135
if (value == NULL) {
1136
PyErr_SetString(PyExc_AttributeError,
1137
"context attributes cannot be deleted");
1141
if (PyUnicode_Check(name)) {
1142
if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
1143
return context_settraps_dict(self, value);
1145
if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
1146
return context_setstatus_dict(self, value);
1150
return PyObject_GenericSetAttr(self, name, value);
1154
context_clear_traps(PyObject *self, PyObject *dummy UNUSED)
1156
CTX(self)->traps = 0;
1161
context_clear_flags(PyObject *self, PyObject *dummy UNUSED)
1163
CTX(self)->status = 0;
1167
#define DEC_DFLT_EMAX 999999
1168
#define DEC_DFLT_EMIN -999999
1170
static mpd_context_t dflt_ctx = {
1171
28, DEC_DFLT_EMAX, DEC_DFLT_EMIN,
1172
MPD_IEEE_Invalid_operation|MPD_Division_by_zero|MPD_Overflow,
1173
0, 0, MPD_ROUND_HALF_EVEN, 0, 1
1177
context_new(PyTypeObject *type, PyObject *args UNUSED, PyObject *kwds UNUSED)
1179
PyDecContextObject *self = NULL;
1182
if (type == &PyDecContext_Type) {
1183
self = PyObject_New(PyDecContextObject, &PyDecContext_Type);
1186
self = (PyDecContextObject *)type->tp_alloc(type, 0);
1193
self->traps = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL);
1194
if (self->traps == NULL) {
1199
self->flags = PyObject_CallObject((PyObject *)PyDecSignalDict_Type, NULL);
1200
if (self->flags == NULL) {
1207
if (default_context_template) {
1208
*ctx = *CTX(default_context_template);
1214
SdFlagAddr(self->traps) = &ctx->traps;
1215
SdFlagAddr(self->flags) = &ctx->status;
1218
#ifndef WITHOUT_THREADS
1219
self->tstate = NULL;
1222
return (PyObject *)self;
1226
context_dealloc(PyDecContextObject *self)
1228
#ifndef WITHOUT_THREADS
1229
if (self == cached_context) {
1230
cached_context = NULL;
1233
Py_XDECREF(self->traps);
1234
Py_XDECREF(self->flags);
1235
Py_TYPE(self)->tp_free(self);
1239
context_init(PyObject *self, PyObject *args, PyObject *kwds)
1241
static char *kwlist[] = {
1242
"prec", "rounding", "Emin", "Emax", "capitals", "clamp",
1243
"flags", "traps", NULL
1245
PyObject *prec = Py_None;
1246
PyObject *rounding = Py_None;
1247
PyObject *emin = Py_None;
1248
PyObject *emax = Py_None;
1249
PyObject *capitals = Py_None;
1250
PyObject *clamp = Py_None;
1251
PyObject *status = Py_None;
1252
PyObject *traps = Py_None;
1255
assert(PyTuple_Check(args));
1257
if (!PyArg_ParseTupleAndKeywords(
1259
"|OOOOOOOO", kwlist,
1260
&prec, &rounding, &emin, &emax, &capitals, &clamp, &status, &traps
1265
if (prec != Py_None && context_setprec(self, prec, NULL) < 0) {
1268
if (rounding != Py_None && context_setround(self, rounding, NULL) < 0) {
1271
if (emin != Py_None && context_setemin(self, emin, NULL) < 0) {
1274
if (emax != Py_None && context_setemax(self, emax, NULL) < 0) {
1277
if (capitals != Py_None && context_setcapitals(self, capitals, NULL) < 0) {
1280
if (clamp != Py_None && context_setclamp(self, clamp, NULL) < 0) {
1284
if (traps != Py_None) {
1285
if (PyList_Check(traps)) {
1286
ret = context_settraps_list(self, traps);
1288
#ifdef EXTRA_FUNCTIONALITY
1289
else if (PyLong_Check(traps)) {
1290
ret = context_settraps(self, traps, NULL);
1294
ret = context_settraps_dict(self, traps);
1300
if (status != Py_None) {
1301
if (PyList_Check(status)) {
1302
ret = context_setstatus_list(self, status);
1304
#ifdef EXTRA_FUNCTIONALITY
1305
else if (PyLong_Check(status)) {
1306
ret = context_setstatus(self, status, NULL);
1310
ret = context_setstatus_dict(self, status);
1321
context_repr(PyDecContextObject *self)
1324
char flags[MPD_MAX_SIGNAL_LIST];
1325
char traps[MPD_MAX_SIGNAL_LIST];
1328
assert(PyDecContext_Check(self));
1331
mem = MPD_MAX_SIGNAL_LIST;
1332
n = mpd_lsnprint_signals(flags, mem, ctx->status, dec_signal_string);
1333
if (n < 0 || n >= mem) {
1334
INTERNAL_ERROR_PTR("context_repr");
1337
n = mpd_lsnprint_signals(traps, mem, ctx->traps, dec_signal_string);
1338
if (n < 0 || n >= mem) {
1339
INTERNAL_ERROR_PTR("context_repr");
1342
return PyUnicode_FromFormat(
1343
"Context(prec=%zd, rounding=%s, Emin=%zd, Emax=%zd, "
1344
"capitals=%d, clamp=%d, flags=%s, traps=%s)",
1345
ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1346
self->capitals, ctx->clamp, flags, traps);
1350
init_basic_context(PyObject *v)
1352
mpd_context_t ctx = dflt_ctx;
1355
ctx.traps |= (MPD_Underflow|MPD_Clamped);
1356
ctx.round = MPD_ROUND_HALF_UP;
1363
init_extended_context(PyObject *v)
1365
mpd_context_t ctx = dflt_ctx;
1374
#ifdef EXTRA_FUNCTIONALITY
1375
/* Factory function for creating IEEE interchange format contexts */
1377
ieee_context(PyObject *dummy UNUSED, PyObject *v)
1383
bits = PyLong_AsSsize_t(v);
1384
if (bits == -1 && PyErr_Occurred()) {
1387
if (bits <= 0 || bits > INT_MAX) {
1390
if (mpd_ieee_context(&ctx, (int)bits) < 0) {
1394
context = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1395
if (context == NULL) {
1398
*CTX(context) = ctx;
1403
PyErr_Format(PyExc_ValueError,
1404
"argument must be a multiple of 32, with a maximum of %d",
1405
MPD_IEEE_CONTEXT_MAX_BITS);
1412
context_copy(PyObject *self, PyObject *args UNUSED)
1416
copy = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
1421
*CTX(copy) = *CTX(self);
1422
CTX(copy)->newtrap = 0;
1423
CtxCaps(copy) = CtxCaps(self);
1429
context_reduce(PyObject *self, PyObject *args UNUSED)
1438
flags = signals_as_list(ctx->status);
1439
if (flags == NULL) {
1442
traps = signals_as_list(ctx->traps);
1443
if (traps == NULL) {
1448
ret = Py_BuildValue(
1451
ctx->prec, mpd_round_string[ctx->round], ctx->emin, ctx->emax,
1452
CtxCaps(self), ctx->clamp, flags, traps
1461
static PyGetSetDef context_getsets [] =
1463
{ "prec", (getter)context_getprec, (setter)context_setprec, NULL, NULL},
1464
{ "Emax", (getter)context_getemax, (setter)context_setemax, NULL, NULL},
1465
{ "Emin", (getter)context_getemin, (setter)context_setemin, NULL, NULL},
1466
{ "rounding", (getter)context_getround, (setter)context_setround, NULL, NULL},
1467
{ "capitals", (getter)context_getcapitals, (setter)context_setcapitals, NULL, NULL},
1468
{ "clamp", (getter)context_getclamp, (setter)context_setclamp, NULL, NULL},
1469
#ifdef EXTRA_FUNCTIONALITY
1470
{ "_allcr", (getter)context_getallcr, (setter)context_setallcr, NULL, NULL},
1471
{ "_traps", (getter)context_gettraps, (setter)context_settraps, NULL, NULL},
1472
{ "_flags", (getter)context_getstatus, (setter)context_setstatus, NULL, NULL},
1478
#define CONTEXT_CHECK(obj) \
1479
if (!PyDecContext_Check(obj)) { \
1480
PyErr_SetString(PyExc_TypeError, \
1481
"argument must be a context"); \
1485
#define CONTEXT_CHECK_VA(obj) \
1486
if (obj == Py_None) { \
1487
CURRENT_CONTEXT(obj); \
1489
else if (!PyDecContext_Check(obj)) { \
1490
PyErr_SetString(PyExc_TypeError, \
1491
"optional argument must be a context"); \
1496
/******************************************************************************/
1497
/* Global, thread local and temporary contexts */
1498
/******************************************************************************/
1500
#ifdef WITHOUT_THREADS
1501
/* Return borrowed reference to the current context. When compiled
1502
* without threads, this is always the module context. */
1503
static int module_context_set = 0;
1505
current_context(void)
1507
/* In decimal.py, the module context is automatically initialized
1508
* from the DefaultContext when it is first accessed. This
1509
* complicates the code and has a speed penalty of 1-2%. */
1510
if (module_context_set) {
1511
return module_context;
1514
*CTX(module_context) = *CTX(default_context_template);
1515
CTX(module_context)->status = 0;
1516
CTX(module_context)->newtrap = 0;
1517
CtxCaps(module_context) = CtxCaps(default_context_template);
1519
module_context_set = 1;
1520
return module_context;
1523
/* ctxobj := borrowed reference to the current context */
1524
#define CURRENT_CONTEXT(ctxobj) \
1525
ctxobj = current_context()
1527
/* ctx := pointer to the mpd_context_t struct of the current context */
1528
#define CURRENT_CONTEXT_ADDR(ctx) \
1529
ctx = CTX(current_context())
1531
/* Return a new reference to the current context */
1533
PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
1537
CURRENT_CONTEXT(context);
1543
/* Set the module context to a new context, decrement old reference */
1545
PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1549
/* If the new context is one of the templates, make a copy.
1550
* This is the current behavior of decimal.py. */
1551
if (v == default_context_template ||
1552
v == basic_context_template ||
1553
v == extended_context_template) {
1554
v = context_copy(v, NULL);
1564
Py_XDECREF(module_context);
1566
module_context_set = 1;
1571
* Thread local storage currently has a speed penalty of about 4%.
1572
* All functions that map Python's arithmetic operators to mpdecimal
1573
* functions have to look up the current context for each and every
1577
/* Get the context from the thread state dictionary. */
1579
current_context_from_dict(void)
1582
PyObject *tl_context;
1583
PyThreadState *tstate;
1585
dict = PyThreadState_GetDict();
1587
PyErr_SetString(PyExc_RuntimeError,
1588
"cannot get thread state");
1592
tl_context = PyDict_GetItemWithError(dict, tls_context_key);
1593
if (tl_context != NULL) {
1594
/* We already have a thread local context. */
1595
CONTEXT_CHECK(tl_context);
1598
if (PyErr_Occurred()) {
1602
/* Set up a new thread local context. */
1603
tl_context = context_copy(default_context_template, NULL);
1604
if (tl_context == NULL) {
1607
CTX(tl_context)->status = 0;
1609
if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) {
1610
Py_DECREF(tl_context);
1613
Py_DECREF(tl_context);
1616
/* Cache the context of the current thread, assuming that it
1617
* will be accessed several times before a thread switch. */
1618
tstate = PyThreadState_GET();
1620
cached_context = (PyDecContextObject *)tl_context;
1621
cached_context->tstate = tstate;
1624
/* Borrowed reference with refcount==1 */
1628
/* Return borrowed reference to thread local context. */
1630
current_context(void)
1632
PyThreadState *tstate;
1634
tstate = PyThreadState_GET();
1635
if (cached_context && cached_context->tstate == tstate) {
1636
return (PyObject *)cached_context;
1639
return current_context_from_dict();
1642
/* ctxobj := borrowed reference to the current context */
1643
#define CURRENT_CONTEXT(ctxobj) \
1644
ctxobj = current_context(); \
1645
if (ctxobj == NULL) { \
1649
/* ctx := pointer to the mpd_context_t struct of the current context */
1650
#define CURRENT_CONTEXT_ADDR(ctx) { \
1651
PyObject *_c_t_x_o_b_j = current_context(); \
1652
if (_c_t_x_o_b_j == NULL) { \
1655
ctx = CTX(_c_t_x_o_b_j); \
1658
/* Return a new reference to the current context */
1660
PyDec_GetCurrentContext(PyObject *self UNUSED, PyObject *args UNUSED)
1664
context = current_context();
1665
if (context == NULL) {
1673
/* Set the thread local context to a new context, decrement old reference */
1675
PyDec_SetCurrentContext(PyObject *self UNUSED, PyObject *v)
1681
dict = PyThreadState_GetDict();
1683
PyErr_SetString(PyExc_RuntimeError,
1684
"cannot get thread state");
1688
/* If the new context is one of the templates, make a copy.
1689
* This is the current behavior of decimal.py. */
1690
if (v == default_context_template ||
1691
v == basic_context_template ||
1692
v == extended_context_template) {
1693
v = context_copy(v, NULL);
1703
cached_context = NULL;
1704
if (PyDict_SetItem(dict, tls_context_key, v) < 0) {
1714
/* Context manager object for the 'with' statement. The manager
1715
* owns one reference to the global (outer) context and one
1716
* to the local (inner) context. */
1718
ctxmanager_new(PyTypeObject *type UNUSED, PyObject *args, PyObject *kwds)
1720
static char *kwlist[] = {"ctx", NULL};
1721
PyDecContextManagerObject *self;
1722
PyObject *local = Py_None;
1725
CURRENT_CONTEXT(global);
1726
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &local)) {
1729
if (local == Py_None) {
1732
else if (!PyDecContext_Check(local)) {
1733
PyErr_SetString(PyExc_TypeError,
1734
"optional argument must be a context");
1738
self = PyObject_New(PyDecContextManagerObject,
1739
&PyDecContextManager_Type);
1744
self->local = context_copy(local, NULL);
1745
if (self->local == NULL) {
1746
self->global = NULL;
1750
self->global = global;
1751
Py_INCREF(self->global);
1753
return (PyObject *)self;
1757
ctxmanager_dealloc(PyDecContextManagerObject *self)
1759
Py_XDECREF(self->local);
1760
Py_XDECREF(self->global);
1765
ctxmanager_set_local(PyDecContextManagerObject *self, PyObject *args UNUSED)
1769
ret = PyDec_SetCurrentContext(NULL, self->local);
1775
Py_INCREF(self->local);
1780
ctxmanager_restore_global(PyDecContextManagerObject *self,
1781
PyObject *args UNUSED)
1785
ret = PyDec_SetCurrentContext(NULL, self->global);
1795
static PyMethodDef ctxmanager_methods[] = {
1796
{"__enter__", (PyCFunction)ctxmanager_set_local, METH_NOARGS, NULL},
1797
{"__exit__", (PyCFunction)ctxmanager_restore_global, METH_VARARGS, NULL},
1801
static PyTypeObject PyDecContextManager_Type =
1803
PyVarObject_HEAD_INIT(NULL, 0)
1804
"decimal.ContextManager", /* tp_name */
1805
sizeof(PyDecContextManagerObject), /* tp_basicsize */
1806
0, /* tp_itemsize */
1807
(destructor) ctxmanager_dealloc, /* tp_dealloc */
1809
(getattrfunc) 0, /* tp_getattr */
1810
(setattrfunc) 0, /* tp_setattr */
1811
0, /* tp_reserved */
1812
(reprfunc) 0, /* tp_repr */
1813
0, /* tp_as_number */
1814
0, /* tp_as_sequence */
1815
0, /* tp_as_mapping */
1819
(getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */
1820
(setattrofunc) 0, /* tp_setattro */
1821
(PyBufferProcs *) 0, /* tp_as_buffer */
1822
Py_TPFLAGS_DEFAULT, /* tp_flags */
1824
0, /* tp_traverse */
1826
0, /* tp_richcompare */
1827
0, /* tp_weaklistoffset */
1829
0, /* tp_iternext */
1830
ctxmanager_methods, /* tp_methods */
1834
/******************************************************************************/
1835
/* New Decimal Object */
1836
/******************************************************************************/
1839
PyDecType_New(PyTypeObject *type)
1843
if (type == &PyDec_Type) {
1844
dec = PyObject_New(PyDecObject, &PyDec_Type);
1847
dec = (PyDecObject *)type->tp_alloc(type, 0);
1855
MPD(dec)->flags = MPD_STATIC|MPD_STATIC_DATA;
1857
MPD(dec)->digits = 0;
1859
MPD(dec)->alloc = _Py_DEC_MINALLOC;
1860
MPD(dec)->data = dec->data;
1862
return (PyObject *)dec;
1864
#define dec_alloc() PyDecType_New(&PyDec_Type)
1867
dec_dealloc(PyObject *dec)
1870
Py_TYPE(dec)->tp_free(dec);
1874
/******************************************************************************/
1875
/* Conversions to Decimal */
1876
/******************************************************************************/
1878
Py_LOCAL_INLINE(int)
1879
is_space(enum PyUnicode_Kind kind, void *data, Py_ssize_t pos)
1881
Py_UCS4 ch = PyUnicode_READ(kind, data, pos);
1882
return Py_UNICODE_ISSPACE(ch);
1885
/* Return the ASCII representation of a numeric Unicode string. The numeric
1886
string may contain ascii characters in the range [1, 127], any Unicode
1887
space and any unicode digit. If strip_ws is true, leading and trailing
1888
whitespace is stripped.
1890
Return NULL if malloc fails and an empty string if invalid characters
1893
numeric_as_ascii(const PyObject *u, int strip_ws)
1895
enum PyUnicode_Kind kind;
1902
if (PyUnicode_READY(u) == -1) {
1906
kind = PyUnicode_KIND(u);
1907
data = PyUnicode_DATA(u);
1908
len = PyUnicode_GET_LENGTH(u);
1910
cp = res = PyMem_Malloc(len+1);
1918
while (len > 0 && is_space(kind, data, len-1)) {
1921
while (j < len && is_space(kind, data, j)) {
1926
for (; j < len; j++) {
1927
ch = PyUnicode_READ(kind, data, j);
1928
if (0 < ch && ch <= 127) {
1932
if (Py_UNICODE_ISSPACE(ch)) {
1936
d = Py_UNICODE_TODECIMAL(ch);
1938
/* empty string triggers ConversionSyntax */
1948
/* Return a new PyDecObject or a subtype from a C string. Use the context
1949
during conversion. */
1951
PyDecType_FromCString(PyTypeObject *type, const char *s,
1955
uint32_t status = 0;
1957
dec = PyDecType_New(type);
1962
mpd_qset_string(MPD(dec), s, CTX(context), &status);
1963
if (dec_addstatus(context, status)) {
1970
/* Return a new PyDecObject or a subtype from a C string. Attempt exact
1971
conversion. If the operand cannot be converted exactly, set
1972
InvalidOperation. */
1974
PyDecType_FromCStringExact(PyTypeObject *type, const char *s,
1978
uint32_t status = 0;
1979
mpd_context_t maxctx;
1981
dec = PyDecType_New(type);
1986
mpd_maxcontext(&maxctx);
1988
mpd_qset_string(MPD(dec), s, &maxctx, &status);
1989
if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
1990
/* we want exact results */
1991
mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
1993
status &= MPD_Errors;
1994
if (dec_addstatus(context, status)) {
2002
/* Return a new PyDecObject or a subtype from a PyUnicodeObject. */
2004
PyDecType_FromUnicode(PyTypeObject *type, const PyObject *u,
2010
s = numeric_as_ascii(u, 0);
2015
dec = PyDecType_FromCString(type, s, context);
2020
/* Return a new PyDecObject or a subtype from a PyUnicodeObject. Attempt exact
2021
* conversion. If the conversion is not exact, fail with InvalidOperation.
2022
* Allow leading and trailing whitespace in the input operand. */
2024
PyDecType_FromUnicodeExactWS(PyTypeObject *type, const PyObject *u,
2030
s = numeric_as_ascii(u, 1);
2035
dec = PyDecType_FromCStringExact(type, s, context);
2040
/* Set PyDecObject from triple without any error checking. */
2041
Py_LOCAL_INLINE(void)
2042
_dec_settriple(PyObject *dec, uint8_t sign, uint32_t v, mpd_ssize_t exp)
2046
MPD(dec)->data[0] = v;
2051
r = v - q * MPD_RADIX;
2052
MPD(dec)->data[1] = q;
2053
MPD(dec)->data[0] = r;
2054
MPD(dec)->len = q ? 2 : 1;
2056
mpd_set_flags(MPD(dec), sign);
2057
MPD(dec)->exp = exp;
2058
mpd_setdigits(MPD(dec));
2061
/* Return a new PyDecObject from an mpd_ssize_t. */
2063
PyDecType_FromSsize(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2066
uint32_t status = 0;
2068
dec = PyDecType_New(type);
2073
mpd_qset_ssize(MPD(dec), v, CTX(context), &status);
2074
if (dec_addstatus(context, status)) {
2081
/* Return a new PyDecObject from an mpd_ssize_t. Conversion is exact. */
2083
PyDecType_FromSsizeExact(PyTypeObject *type, mpd_ssize_t v, PyObject *context)
2086
uint32_t status = 0;
2087
mpd_context_t maxctx;
2089
dec = PyDecType_New(type);
2094
mpd_maxcontext(&maxctx);
2096
mpd_qset_ssize(MPD(dec), v, &maxctx, &status);
2097
if (dec_addstatus(context, status)) {
2104
/* Convert from a PyLongObject. The context is not modified; flags set
2105
during conversion are accumulated in the status parameter. */
2107
dec_from_long(PyTypeObject *type, const PyObject *v,
2108
const mpd_context_t *ctx, uint32_t *status)
2111
PyLongObject *l = (PyLongObject *)v;
2116
dec = PyDecType_New(type);
2121
ob_size = Py_SIZE(l);
2123
_dec_settriple(dec, MPD_POS, 0, 0);
2137
_dec_settriple(dec, sign, *l->ob_digit, 0);
2138
mpd_qfinalize(MPD(dec), ctx, status);
2142
#if PYLONG_BITS_IN_DIGIT == 30
2143
mpd_qimport_u32(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2145
#elif PYLONG_BITS_IN_DIGIT == 15
2146
mpd_qimport_u16(MPD(dec), l->ob_digit, len, sign, PyLong_BASE,
2149
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
2155
/* Return a new PyDecObject from a PyLongObject. Use the context for
2158
PyDecType_FromLong(PyTypeObject *type, const PyObject *pylong,
2162
uint32_t status = 0;
2164
dec = dec_from_long(type, pylong, CTX(context), &status);
2169
if (dec_addstatus(context, status)) {
2177
/* Return a new PyDecObject from a PyLongObject. Use a maximum context
2178
for conversion. If the conversion is not exact, set InvalidOperation. */
2180
PyDecType_FromLongExact(PyTypeObject *type, const PyObject *pylong,
2184
uint32_t status = 0;
2185
mpd_context_t maxctx;
2187
mpd_maxcontext(&maxctx);
2188
dec = dec_from_long(type, pylong, &maxctx, &status);
2193
if (status & (MPD_Inexact|MPD_Rounded|MPD_Clamped)) {
2194
/* we want exact results */
2195
mpd_seterror(MPD(dec), MPD_Invalid_operation, &status);
2197
status &= MPD_Errors;
2198
if (dec_addstatus(context, status)) {
2206
/* Return a PyDecObject or a subtype from a PyFloatObject.
2207
Conversion is exact. */
2209
PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v,
2212
PyObject *dec, *tmp;
2213
PyObject *n, *d, *n_d;
2218
uint32_t status = 0;
2219
mpd_context_t maxctx;
2222
assert(PyType_IsSubtype(type, &PyDec_Type));
2224
if (PyLong_Check(v)) {
2225
return PyDecType_FromLongExact(type, v, context);
2227
if (!PyFloat_Check(v)) {
2228
PyErr_SetString(PyExc_TypeError,
2229
"argument must be int of float");
2233
x = PyFloat_AsDouble(v);
2234
if (x == -1.0 && PyErr_Occurred()) {
2237
sign = (copysign(1.0, x) == 1.0) ? 0 : 1;
2239
if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
2240
dec = PyDecType_New(type);
2245
/* decimal.py calls repr(float(+-nan)),
2246
* which always gives a positive result. */
2247
mpd_setspecial(MPD(dec), MPD_POS, MPD_NAN);
2250
mpd_setspecial(MPD(dec), sign, MPD_INF);
2255
/* absolute value of the float */
2256
tmp = PyObject_CallMethod(v, "__abs__", NULL);
2261
/* float as integer ratio: numerator/denominator */
2262
n_d = PyObject_CallMethod(tmp, "as_integer_ratio", NULL);
2267
n = PyTuple_GET_ITEM(n_d, 0);
2268
d = PyTuple_GET_ITEM(n_d, 1);
2270
tmp = PyObject_CallMethod(d, "bit_length", NULL);
2275
k = PyLong_AsSsize_t(tmp);
2277
if (k == -1 && PyErr_Occurred()) {
2283
dec = PyDecType_FromLongExact(type, n, context);
2303
mpd_maxcontext(&maxctx);
2304
mpd_qset_uint(d1, 5, &maxctx, &status);
2305
mpd_qset_ssize(d2, k, &maxctx, &status);
2306
mpd_qpow(d1, d1, d2, &maxctx, &status);
2307
if (dec_addstatus(context, status)) {
2314
/* result = n * 5**k */
2315
mpd_qmul(MPD(dec), MPD(dec), d1, &maxctx, &status);
2318
if (dec_addstatus(context, status)) {
2322
/* result = +- n * 5**k * 10**-k */
2323
mpd_set_sign(MPD(dec), sign);
2330
PyDecType_FromFloat(PyTypeObject *type, PyObject *v,
2334
uint32_t status = 0;
2336
dec = PyDecType_FromFloatExact(type, v, context);
2341
mpd_qfinalize(MPD(dec), CTX(context), &status);
2342
if (dec_addstatus(context, status)) {
2350
/* Return a new PyDecObject or a subtype from a Decimal. */
2352
PyDecType_FromDecimalExact(PyTypeObject *type, PyObject *v, PyObject *context)
2355
uint32_t status = 0;
2357
if (type == &PyDec_Type && PyDec_CheckExact(v)) {
2362
dec = PyDecType_New(type);
2367
mpd_qcopy(MPD(dec), MPD(v), &status);
2368
if (dec_addstatus(context, status)) {
2377
sequence_as_tuple(PyObject *v, PyObject *ex, const char *mesg)
2379
if (PyTuple_Check(v)) {
2383
if (PyList_Check(v)) {
2384
return PyList_AsTuple(v);
2387
PyErr_SetString(ex, mesg);
2391
/* Return a new C string representation of a DecimalTuple. */
2393
dectuple_as_str(PyObject *dectuple)
2395
PyObject *digits = NULL, *tmp;
2396
char *decstring = NULL;
2397
char sign_special[6];
2400
mpd_ssize_t exp = 0;
2401
Py_ssize_t i, mem, tsize;
2402
int is_infinite = 0;
2405
assert(PyTuple_Check(dectuple));
2407
if (PyTuple_Size(dectuple) != 3) {
2408
PyErr_SetString(PyExc_ValueError,
2409
"argument must be a sequence of length 3");
2414
tmp = PyTuple_GET_ITEM(dectuple, 0);
2415
if (!PyLong_Check(tmp)) {
2416
PyErr_SetString(PyExc_ValueError,
2417
"sign must be an integer with the value 0 or 1");
2420
sign = PyLong_AsLong(tmp);
2421
if (sign == -1 && PyErr_Occurred()) {
2424
if (sign != 0 && sign != 1) {
2425
PyErr_SetString(PyExc_ValueError,
2426
"sign must be an integer with the value 0 or 1");
2429
sign_special[0] = sign ? '-' : '+';
2430
sign_special[1] = '\0';
2432
/* exponent or encoding for a special number */
2433
tmp = PyTuple_GET_ITEM(dectuple, 2);
2434
if (PyUnicode_Check(tmp)) {
2436
if (PyUnicode_CompareWithASCIIString(tmp, "F") == 0) {
2437
strcat(sign_special, "Inf");
2440
else if (PyUnicode_CompareWithASCIIString(tmp, "n") == 0) {
2441
strcat(sign_special, "NaN");
2443
else if (PyUnicode_CompareWithASCIIString(tmp, "N") == 0) {
2444
strcat(sign_special, "sNaN");
2447
PyErr_SetString(PyExc_ValueError,
2448
"string argument in the third position "
2449
"must be 'F', 'n' or 'N'");
2455
if (!PyLong_Check(tmp)) {
2456
PyErr_SetString(PyExc_ValueError,
2457
"exponent must be an integer");
2460
exp = PyLong_AsSsize_t(tmp);
2461
if (exp == -1 && PyErr_Occurred()) {
2467
digits = sequence_as_tuple(PyTuple_GET_ITEM(dectuple, 1), PyExc_ValueError,
2468
"coefficient must be a tuple of digits");
2469
if (digits == NULL) {
2473
tsize = PyTuple_Size(digits);
2474
/* [sign][coeffdigits+1][E][-][expdigits+1]['\0'] */
2475
mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2;
2476
cp = decstring = PyMem_Malloc(mem);
2477
if (decstring == NULL) {
2482
n = snprintf(cp, mem, "%s", sign_special);
2483
if (n < 0 || n >= mem) {
2484
PyErr_SetString(PyExc_RuntimeError,
2485
"internal error in dec_sequence_as_str");
2490
if (tsize == 0 && sign_special[1] == '\0') {
2491
/* empty tuple: zero coefficient, except for special numbers */
2494
for (i = 0; i < tsize; i++) {
2495
tmp = PyTuple_GET_ITEM(digits, i);
2496
if (!PyLong_Check(tmp)) {
2497
PyErr_SetString(PyExc_ValueError,
2498
"coefficient must be a tuple of digits");
2501
l = PyLong_AsLong(tmp);
2502
if (l == -1 && PyErr_Occurred()) {
2505
if (l < 0 || l > 9) {
2506
PyErr_SetString(PyExc_ValueError,
2507
"coefficient must be a tuple of digits");
2511
/* accept but ignore any well-formed coefficient for compatibility
2515
*cp++ = (char)l + '0';
2519
if (sign_special[1] == '\0') {
2520
/* not a special number */
2522
n = snprintf(cp, MPD_EXPDIGITS+2, "%" PRI_mpd_ssize_t, exp);
2523
if (n < 0 || n >= MPD_EXPDIGITS+2) {
2524
PyErr_SetString(PyExc_RuntimeError,
2525
"internal error in dec_sequence_as_str");
2536
if (decstring) PyMem_Free(decstring);
2540
/* Currently accepts tuples and lists. */
2542
PyDecType_FromSequence(PyTypeObject *type, PyObject *v,
2549
dectuple = sequence_as_tuple(v, PyExc_TypeError,
2550
"argument must be a tuple or list");
2551
if (dectuple == NULL) {
2555
s = dectuple_as_str(dectuple);
2556
Py_DECREF(dectuple);
2561
dec = PyDecType_FromCString(type, s, context);
2567
/* Currently accepts tuples and lists. */
2569
PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
2576
dectuple = sequence_as_tuple(v, PyExc_TypeError,
2577
"argument must be a tuple or list");
2578
if (dectuple == NULL) {
2582
s = dectuple_as_str(dectuple);
2583
Py_DECREF(dectuple);
2588
dec = PyDecType_FromCStringExact(type, s, context);
2594
#define PyDec_FromCString(str, context) \
2595
PyDecType_FromCString(&PyDec_Type, str, context)
2596
#define PyDec_FromCStringExact(str, context) \
2597
PyDecType_FromCStringExact(&PyDec_Type, str, context)
2599
#define PyDec_FromUnicode(unicode, context) \
2600
PyDecType_FromUnicode(&PyDec_Type, unicode, context)
2601
#define PyDec_FromUnicodeExact(unicode, context) \
2602
PyDecType_FromUnicodeExact(&PyDec_Type, unicode, context)
2603
#define PyDec_FromUnicodeExactWS(unicode, context) \
2604
PyDecType_FromUnicodeExactWS(&PyDec_Type, unicode, context)
2606
#define PyDec_FromSsize(v, context) \
2607
PyDecType_FromSsize(&PyDec_Type, v, context)
2608
#define PyDec_FromSsizeExact(v, context) \
2609
PyDecType_FromSsizeExact(&PyDec_Type, v, context)
2611
#define PyDec_FromLong(pylong, context) \
2612
PyDecType_FromLong(&PyDec_Type, pylong, context)
2613
#define PyDec_FromLongExact(pylong, context) \
2614
PyDecType_FromLongExact(&PyDec_Type, pylong, context)
2616
#define PyDec_FromFloat(pyfloat, context) \
2617
PyDecType_FromFloat(&PyDec_Type, pyfloat, context)
2618
#define PyDec_FromFloatExact(pyfloat, context) \
2619
PyDecType_FromFloatExact(&PyDec_Type, pyfloat, context)
2621
#define PyDec_FromSequence(sequence, context) \
2622
PyDecType_FromSequence(&PyDec_Type, sequence, context)
2623
#define PyDec_FromSequenceExact(sequence, context) \
2624
PyDecType_FromSequenceExact(&PyDec_Type, sequence, context)
2628
dec_from_float(PyObject *dec, PyObject *pyfloat)
2632
CURRENT_CONTEXT(context);
2633
return PyDecType_FromFloatExact((PyTypeObject *)dec, pyfloat, context);
2636
/* create_decimal_from_float */
2638
ctx_from_float(PyObject *context, PyObject *v)
2640
return PyDec_FromFloat(v, context);
2643
/* Apply the context to the input operand. Return a new PyDecObject. */
2645
dec_apply(PyObject *v, PyObject *context)
2648
uint32_t status = 0;
2650
result = dec_alloc();
2651
if (result == NULL) {
2655
mpd_qcopy(MPD(result), MPD(v), &status);
2656
if (dec_addstatus(context, status)) {
2661
mpd_qfinalize(MPD(result), CTX(context), &status);
2662
if (dec_addstatus(context, status)) {
2670
/* 'v' can have any type accepted by the Decimal constructor. Attempt
2671
an exact conversion. If the result does not meet the restrictions
2672
for an mpd_t, fail with InvalidOperation. */
2674
PyDecType_FromObjectExact(PyTypeObject *type, PyObject *v, PyObject *context)
2677
return PyDecType_FromSsizeExact(type, 0, context);
2679
else if (PyDec_Check(v)) {
2680
return PyDecType_FromDecimalExact(type, v, context);
2682
else if (PyUnicode_Check(v)) {
2683
return PyDecType_FromUnicodeExactWS(type, v, context);
2685
else if (PyLong_Check(v)) {
2686
return PyDecType_FromLongExact(type, v, context);
2688
else if (PyTuple_Check(v) || PyList_Check(v)) {
2689
return PyDecType_FromSequenceExact(type, v, context);
2691
else if (PyFloat_Check(v)) {
2692
if (dec_addstatus(context, MPD_Float_operation)) {
2695
return PyDecType_FromFloatExact(type, v, context);
2698
PyErr_Format(PyExc_TypeError,
2699
"conversion from %s to Decimal is not supported",
2700
v->ob_type->tp_name);
2705
/* The context is used during conversion. This function is the
2706
equivalent of context.create_decimal(). */
2708
PyDec_FromObject(PyObject *v, PyObject *context)
2711
return PyDec_FromSsize(0, context);
2713
else if (PyDec_Check(v)) {
2714
mpd_context_t *ctx = CTX(context);
2715
if (mpd_isnan(MPD(v)) &&
2716
MPD(v)->digits > ctx->prec - ctx->clamp) {
2717
/* Special case: too many NaN payload digits */
2719
if (dec_addstatus(context, MPD_Conversion_syntax)) {
2722
result = dec_alloc();
2723
if (result == NULL) {
2726
mpd_setspecial(MPD(result), MPD_POS, MPD_NAN);
2729
return dec_apply(v, context);
2731
else if (PyUnicode_Check(v)) {
2732
return PyDec_FromUnicode(v, context);
2734
else if (PyLong_Check(v)) {
2735
return PyDec_FromLong(v, context);
2737
else if (PyTuple_Check(v) || PyList_Check(v)) {
2738
return PyDec_FromSequence(v, context);
2740
else if (PyFloat_Check(v)) {
2741
if (dec_addstatus(context, MPD_Float_operation)) {
2744
return PyDec_FromFloat(v, context);
2747
PyErr_Format(PyExc_TypeError,
2748
"conversion from %s to Decimal is not supported",
2749
v->ob_type->tp_name);
2755
dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
2757
static char *kwlist[] = {"value", "context", NULL};
2759
PyObject *context = Py_None;
2761
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
2765
CONTEXT_CHECK_VA(context);
2767
return PyDecType_FromObjectExact(type, v, context);
2771
ctx_create_decimal(PyObject *context, PyObject *args)
2775
if (!PyArg_ParseTuple(args, "|O", &v)) {
2779
return PyDec_FromObject(v, context);
2783
/******************************************************************************/
2784
/* Implicit conversions to Decimal */
2785
/******************************************************************************/
2787
/* Try to convert PyObject v to a new PyDecObject conv. If the conversion
2788
fails, set conv to NULL (exception is set). If the conversion is not
2789
implemented, set conv to Py_NotImplemented. */
2792
Py_LOCAL_INLINE(int)
2793
convert_op(int type_err, PyObject **conv, PyObject *v, PyObject *context)
2796
if (PyDec_Check(v)) {
2801
if (PyLong_Check(v)) {
2802
*conv = PyDec_FromLongExact(v, context);
2803
if (*conv == NULL) {
2810
PyErr_Format(PyExc_TypeError,
2811
"conversion from %s to Decimal is not supported",
2812
v->ob_type->tp_name);
2815
Py_INCREF(Py_NotImplemented);
2816
*conv = Py_NotImplemented;
2821
/* Return NotImplemented for unsupported types. */
2822
#define CONVERT_OP(a, v, context) \
2823
if (!convert_op(NOT_IMPL, a, v, context)) { \
2827
#define CONVERT_BINOP(a, b, v, w, context) \
2828
if (!convert_op(NOT_IMPL, a, v, context)) { \
2831
if (!convert_op(NOT_IMPL, b, w, context)) { \
2836
#define CONVERT_TERNOP(a, b, c, v, w, x, context) \
2837
if (!convert_op(NOT_IMPL, a, v, context)) { \
2840
if (!convert_op(NOT_IMPL, b, w, context)) { \
2844
if (!convert_op(NOT_IMPL, c, x, context)) { \
2850
/* Raise TypeError for unsupported types. */
2851
#define CONVERT_OP_RAISE(a, v, context) \
2852
if (!convert_op(TYPE_ERR, a, v, context)) { \
2856
#define CONVERT_BINOP_RAISE(a, b, v, w, context) \
2857
if (!convert_op(TYPE_ERR, a, v, context)) { \
2860
if (!convert_op(TYPE_ERR, b, w, context)) { \
2865
#define CONVERT_TERNOP_RAISE(a, b, c, v, w, x, context) \
2866
if (!convert_op(TYPE_ERR, a, v, context)) { \
2869
if (!convert_op(TYPE_ERR, b, w, context)) { \
2873
if (!convert_op(TYPE_ERR, c, x, context)) { \
2880
/******************************************************************************/
2881
/* Implicit conversions to Decimal for comparison */
2882
/******************************************************************************/
2884
/* Convert rationals for comparison */
2885
static PyObject *Rational = NULL;
2887
multiply_by_denominator(PyObject *v, PyObject *r, PyObject *context)
2890
PyObject *tmp = NULL;
2891
PyObject *denom = NULL;
2892
uint32_t status = 0;
2893
mpd_context_t maxctx;
2897
/* v is not special, r is a rational */
2898
tmp = PyObject_GetAttrString(r, "denominator");
2902
denom = PyDec_FromLongExact(tmp, context);
2904
if (denom == NULL) {
2908
vv = mpd_qncopy(MPD(v));
2914
result = dec_alloc();
2915
if (result == NULL) {
2921
mpd_maxcontext(&maxctx);
2922
/* Prevent Overflow in the following multiplication. The result of
2923
the multiplication is only used in mpd_qcmp, which can handle
2924
values that are technically out of bounds, like (for 32-bit)
2925
99999999999999999999...99999999e+425000000. */
2928
mpd_qmul(MPD(result), vv, MPD(denom), &maxctx, &status);
2929
MPD(result)->exp = exp;
2933
/* If any status has been accumulated during the multiplication,
2934
the result is invalid. This is very unlikely, since even the
2935
32-bit version supports 425000000 digits. */
2937
PyErr_SetString(PyExc_ValueError,
2938
"exact conversion for comparison failed");
2947
numerator_as_decimal(PyObject *r, PyObject *context)
2949
PyObject *tmp, *num;
2951
tmp = PyObject_GetAttrString(r, "numerator");
2956
num = PyDec_FromLongExact(tmp, context);
2961
/* Convert v and w for comparison. v is a Decimal. If w is a Rational, both
2962
v and w have to be transformed. Return 1 for success, with new references
2963
to the converted objects in vcmp and wcmp. Return 0 for failure. In that
2964
case wcmp is either NULL or Py_NotImplemented (new reference) and vcmp
2967
convert_op_cmp(PyObject **vcmp, PyObject **wcmp, PyObject *v, PyObject *w,
2968
int op, PyObject *context)
2970
mpd_context_t *ctx = CTX(context);
2974
if (PyDec_Check(w)) {
2978
else if (PyLong_Check(w)) {
2979
*wcmp = PyDec_FromLongExact(w, context);
2981
else if (PyFloat_Check(w)) {
2982
if (op != Py_EQ && op != Py_NE &&
2983
dec_addstatus(context, MPD_Float_operation)) {
2987
ctx->status |= MPD_Float_operation;
2988
*wcmp = PyDec_FromFloatExact(w, context);
2991
else if (PyComplex_Check(w) && (op == Py_EQ || op == Py_NE)) {
2992
Py_complex c = PyComplex_AsCComplex(w);
2993
if (c.real == -1.0 && PyErr_Occurred()) {
2996
else if (c.imag == 0.0) {
2997
PyObject *tmp = PyFloat_FromDouble(c.real);
3002
ctx->status |= MPD_Float_operation;
3003
*wcmp = PyDec_FromFloatExact(tmp, context);
3008
Py_INCREF(Py_NotImplemented);
3009
*wcmp = Py_NotImplemented;
3013
int is_rational = PyObject_IsInstance(w, Rational);
3014
if (is_rational < 0) {
3017
else if (is_rational > 0) {
3018
*wcmp = numerator_as_decimal(w, context);
3019
if (*wcmp && !mpd_isspecial(MPD(v))) {
3020
*vcmp = multiply_by_denominator(v, w, context);
3021
if (*vcmp == NULL) {
3027
Py_INCREF(Py_NotImplemented);
3028
*wcmp = Py_NotImplemented;
3032
if (*wcmp == NULL || *wcmp == Py_NotImplemented) {
3041
#define CONVERT_BINOP_CMP(vcmp, wcmp, v, w, op, ctx) \
3042
if (!convert_op_cmp(vcmp, wcmp, v, w, op, ctx)) { \
3047
/******************************************************************************/
3048
/* Conversions from decimal */
3049
/******************************************************************************/
3052
unicode_fromascii(const char *s, Py_ssize_t size)
3056
res = PyUnicode_New(size, 127);
3061
memcpy(PyUnicode_1BYTE_DATA(res), s, size);
3065
/* PyDecObject as a string. The default module context is only used for
3066
the value of 'capitals'. */
3068
dec_str(PyObject *dec)
3070
PyObject *res, *context;
3074
CURRENT_CONTEXT(context);
3075
size = mpd_to_sci_size(&cp, MPD(dec), CtxCaps(context));
3081
res = unicode_fromascii(cp, size);
3086
/* Representation of a PyDecObject. */
3088
dec_repr(PyObject *dec)
3090
PyObject *res, *context;
3093
CURRENT_CONTEXT(context);
3094
cp = mpd_to_sci(MPD(dec), CtxCaps(context));
3100
res = PyUnicode_FromFormat("Decimal('%s')", cp);
3105
/* Return a duplicate of src, copy embedded null characters. */
3107
dec_strdup(const char *src, Py_ssize_t size)
3109
char *dest = PyMem_Malloc(size+1);
3115
memcpy(dest, src, size);
3121
dec_replace_fillchar(char *dest)
3123
while (*dest != '\0') {
3124
if (*dest == '\xff') *dest = '\0';
3129
/* Convert decimal_point or thousands_sep, which may be multibyte or in
3130
the range [128, 255], to a UTF8 string. */
3132
dotsep_as_utf8(const char *s)
3139
n = mbstowcs(buf, s, 2);
3140
if (n != 1) { /* Issue #7442 */
3141
PyErr_SetString(PyExc_ValueError,
3142
"invalid decimal point or unsupported "
3143
"combination of LC_CTYPE and LC_NUMERIC");
3146
tmp = PyUnicode_FromWideChar(buf, n);
3150
utf8 = PyUnicode_AsUTF8String(tmp);
3155
/* Formatted representation of a PyDecObject. */
3157
dec_format(PyObject *dec, PyObject *args)
3159
PyObject *result = NULL;
3160
PyObject *override = NULL;
3161
PyObject *dot = NULL;
3162
PyObject *sep = NULL;
3163
PyObject *grouping = NULL;
3168
char *decstring = NULL;
3169
uint32_t status = 0;
3170
int replace_fillchar = 0;
3174
CURRENT_CONTEXT(context);
3175
if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) {
3179
if (PyUnicode_Check(fmtarg)) {
3180
fmt = PyUnicode_AsUTF8AndSize(fmtarg, &size);
3184
if (size > 0 && fmt[0] == '\0') {
3185
/* NUL fill character: must be replaced with a valid UTF-8 char
3186
before calling mpd_parse_fmt_str(). */
3187
replace_fillchar = 1;
3188
fmt = dec_strdup(fmt, size);
3196
PyErr_SetString(PyExc_TypeError,
3197
"format arg must be str");
3201
if (!mpd_parse_fmt_str(&spec, fmt, CtxCaps(context))) {
3202
PyErr_SetString(PyExc_ValueError,
3203
"invalid format string");
3206
if (replace_fillchar) {
3207
/* In order to avoid clobbering parts of UTF-8 thousands separators or
3208
decimal points when the substitution is reversed later, the actual
3209
placeholder must be an invalid UTF-8 byte. */
3210
spec.fill[0] = '\xff';
3211
spec.fill[1] = '\0';
3215
/* Values for decimal_point, thousands_sep and grouping can
3216
be explicitly specified in the override dict. These values
3217
take precedence over the values obtained from localeconv()
3218
in mpd_parse_fmt_str(). The feature is not documented and
3219
is only used in test_decimal. */
3220
if (!PyDict_Check(override)) {
3221
PyErr_SetString(PyExc_TypeError,
3222
"optional argument must be a dict");
3225
if ((dot = PyDict_GetItemString(override, "decimal_point"))) {
3226
if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) {
3229
spec.dot = PyBytes_AS_STRING(dot);
3231
if ((sep = PyDict_GetItemString(override, "thousands_sep"))) {
3232
if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) {
3235
spec.sep = PyBytes_AS_STRING(sep);
3237
if ((grouping = PyDict_GetItemString(override, "grouping"))) {
3238
if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) {
3241
spec.grouping = PyBytes_AS_STRING(grouping);
3243
if (mpd_validate_lconv(&spec) < 0) {
3244
PyErr_SetString(PyExc_ValueError,
3245
"invalid override dict");
3250
size_t n = strlen(spec.dot);
3251
if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) {
3252
/* fix locale dependent non-ascii characters */
3253
dot = dotsep_as_utf8(spec.dot);
3257
spec.dot = PyBytes_AS_STRING(dot);
3259
n = strlen(spec.sep);
3260
if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) {
3261
/* fix locale dependent non-ascii characters */
3262
sep = dotsep_as_utf8(spec.sep);
3266
spec.sep = PyBytes_AS_STRING(sep);
3271
decstring = mpd_qformat_spec(MPD(dec), &spec, CTX(context), &status);
3272
if (decstring == NULL) {
3273
if (status & MPD_Malloc_error) {
3277
PyErr_SetString(PyExc_ValueError,
3278
"format specification exceeds internal limits of _decimal");
3282
size = strlen(decstring);
3283
if (replace_fillchar) {
3284
dec_replace_fillchar(decstring);
3287
result = PyUnicode_DecodeUTF8(decstring, size, NULL);
3291
Py_XDECREF(grouping);
3294
if (replace_fillchar) PyMem_Free(fmt);
3295
if (decstring) mpd_free(decstring);
3299
/* Return a PyLongObject from a PyDecObject, using the specified rounding
3300
* mode. The context precision is not observed. */
3302
dec_as_long(PyObject *dec, PyObject *context, int round)
3304
PyLongObject *pylong;
3309
mpd_context_t workctx;
3310
uint32_t status = 0;
3312
if (mpd_isspecial(MPD(dec))) {
3313
if (mpd_isnan(MPD(dec))) {
3314
PyErr_SetString(PyExc_ValueError,
3315
"cannot convert NaN to integer");
3318
PyErr_SetString(PyExc_OverflowError,
3319
"cannot convert Infinity to integer");
3329
workctx = *CTX(context);
3330
workctx.round = round;
3331
mpd_qround_to_int(x, MPD(dec), &workctx, &status);
3332
if (dec_addstatus(context, status)) {
3339
#if PYLONG_BITS_IN_DIGIT == 30
3340
n = mpd_qexport_u32(&ob_digit, 0, PyLong_BASE, x, &status);
3341
#elif PYLONG_BITS_IN_DIGIT == 15
3342
n = mpd_qexport_u16(&ob_digit, 0, PyLong_BASE, x, &status);
3344
#error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
3347
if (n == SIZE_MAX) {
3354
pylong = _PyLong_New(n);
3355
if (pylong == NULL) {
3361
memcpy(pylong->ob_digit, ob_digit, n * sizeof(digit));
3365
while ((i > 0) && (pylong->ob_digit[i-1] == 0)) {
3369
Py_SIZE(pylong) = i;
3370
if (mpd_isnegative(x) && !mpd_iszero(x)) {
3371
Py_SIZE(pylong) = -i;
3375
return (PyObject *) pylong;
3379
PyDec_ToIntegralValue(PyObject *dec, PyObject *args, PyObject *kwds)
3381
static char *kwlist[] = {"rounding", "context", NULL};
3383
PyObject *rounding = Py_None;
3384
PyObject *context = Py_None;
3385
uint32_t status = 0;
3386
mpd_context_t workctx;
3388
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
3389
&rounding, &context)) {
3392
CONTEXT_CHECK_VA(context);
3394
workctx = *CTX(context);
3395
if (rounding != Py_None) {
3396
int round = getround(rounding);
3400
if (!mpd_qsetround(&workctx, round)) {
3401
INTERNAL_ERROR_PTR("PyDec_ToIntegralValue"); /* GCOV_NOT_REACHED */
3405
result = dec_alloc();
3406
if (result == NULL) {
3410
mpd_qround_to_int(MPD(result), MPD(dec), &workctx, &status);
3411
if (dec_addstatus(context, status)) {
3420
PyDec_ToIntegralExact(PyObject *dec, PyObject *args, PyObject *kwds)
3422
static char *kwlist[] = {"rounding", "context", NULL};
3424
PyObject *rounding = Py_None;
3425
PyObject *context = Py_None;
3426
uint32_t status = 0;
3427
mpd_context_t workctx;
3429
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
3430
&rounding, &context)) {
3433
CONTEXT_CHECK_VA(context);
3435
workctx = *CTX(context);
3436
if (rounding != Py_None) {
3437
int round = getround(rounding);
3441
if (!mpd_qsetround(&workctx, round)) {
3442
INTERNAL_ERROR_PTR("PyDec_ToIntegralExact"); /* GCOV_NOT_REACHED */
3446
result = dec_alloc();
3447
if (result == NULL) {
3451
mpd_qround_to_intx(MPD(result), MPD(dec), &workctx, &status);
3452
if (dec_addstatus(context, status)) {
3461
PyDec_AsFloat(PyObject *dec)
3465
if (mpd_isnan(MPD(dec))) {
3466
if (mpd_issnan(MPD(dec))) {
3467
PyErr_SetString(PyExc_ValueError,
3468
"cannot convert signaling NaN to float");
3471
if (mpd_isnegative(MPD(dec))) {
3472
s = PyUnicode_FromString("-nan");
3475
s = PyUnicode_FromString("nan");
3486
f = PyFloat_FromString(s);
3493
PyDec_Round(PyObject *dec, PyObject *args)
3497
uint32_t status = 0;
3501
CURRENT_CONTEXT(context);
3502
if (!PyArg_ParseTuple(args, "|O", &x)) {
3507
mpd_uint_t dq[1] = {1};
3508
mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq};
3511
if (!PyLong_Check(x)) {
3512
PyErr_SetString(PyExc_TypeError,
3513
"optional arg must be an integer");
3517
y = PyLong_AsSsize_t(x);
3518
if (y == -1 && PyErr_Occurred()) {
3521
result = dec_alloc();
3522
if (result == NULL) {
3526
q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y;
3527
mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status);
3528
if (dec_addstatus(context, status)) {
3536
return dec_as_long(dec, context, MPD_ROUND_HALF_EVEN);
3540
static PyObject *DecimalTuple = NULL;
3541
/* Return the DecimalTuple representation of a PyDecObject. */
3543
PyDec_AsTuple(PyObject *dec, PyObject *dummy UNUSED)
3545
PyObject *result = NULL;
3546
PyObject *sign = NULL;
3547
PyObject *coeff = NULL;
3548
PyObject *expt = NULL;
3549
PyObject *tmp = NULL;
3551
char *intstring = NULL;
3552
Py_ssize_t intlen, i;
3555
x = mpd_qncopy(MPD(dec));
3561
sign = PyLong_FromUnsignedLong(mpd_sign(MPD(dec)));
3566
if (mpd_isinfinite(x)) {
3567
expt = PyUnicode_FromString("F");
3571
/* decimal.py has non-compliant infinity payloads. */
3572
coeff = Py_BuildValue("(i)", 0);
3573
if (coeff == NULL) {
3579
expt = PyUnicode_FromString(mpd_isqnan(x)?"n":"N");
3582
expt = PyLong_FromSsize_t(MPD(dec)->exp);
3588
/* coefficient is defined */
3591
/* make an integer */
3593
/* clear NaN and sign */
3595
intstring = mpd_to_sci(x, 1);
3596
if (intstring == NULL) {
3601
intlen = strlen(intstring);
3602
coeff = PyTuple_New(intlen);
3603
if (coeff == NULL) {
3607
for (i = 0; i < intlen; i++) {
3608
tmp = PyLong_FromLong(intstring[i]-'0');
3612
PyTuple_SET_ITEM(coeff, i, tmp);
3616
coeff = PyTuple_New(0);
3617
if (coeff == NULL) {
3623
result = PyObject_CallFunctionObjArgs(DecimalTuple,
3624
sign, coeff, expt, NULL);
3628
if (intstring) mpd_free(intstring);
3636
/******************************************************************************/
3637
/* Macros for converting mpdecimal functions to Decimal methods */
3638
/******************************************************************************/
3640
/* Unary number method that uses the default module context. */
3641
#define Dec_UnaryNumberMethod(MPDFUNC) \
3643
nm_##MPDFUNC(PyObject *self) \
3646
PyObject *context; \
3647
uint32_t status = 0; \
3649
CURRENT_CONTEXT(context); \
3650
if ((result = dec_alloc()) == NULL) { \
3654
MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \
3655
if (dec_addstatus(context, status)) { \
3656
Py_DECREF(result); \
3663
/* Binary number method that uses default module context. */
3664
#define Dec_BinaryNumberMethod(MPDFUNC) \
3666
nm_##MPDFUNC(PyObject *self, PyObject *other) \
3670
PyObject *context; \
3671
uint32_t status = 0; \
3673
CURRENT_CONTEXT(context) ; \
3674
CONVERT_BINOP(&a, &b, self, other, context); \
3676
if ((result = dec_alloc()) == NULL) { \
3682
MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3685
if (dec_addstatus(context, status)) { \
3686
Py_DECREF(result); \
3693
/* Boolean function without a context arg. */
3694
#define Dec_BoolFunc(MPDFUNC) \
3696
dec_##MPDFUNC(PyObject *self, PyObject *dummy UNUSED) \
3698
return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \
3701
/* Boolean function with an optional context arg. */
3702
#define Dec_BoolFuncVA(MPDFUNC) \
3704
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3706
static char *kwlist[] = {"context", NULL}; \
3707
PyObject *context = Py_None; \
3709
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
3713
CONTEXT_CHECK_VA(context); \
3715
return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \
3718
/* Unary function with an optional context arg. */
3719
#define Dec_UnaryFuncVA(MPDFUNC) \
3721
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3723
static char *kwlist[] = {"context", NULL}; \
3725
PyObject *context = Py_None; \
3726
uint32_t status = 0; \
3728
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \
3732
CONTEXT_CHECK_VA(context); \
3734
if ((result = dec_alloc()) == NULL) { \
3738
MPDFUNC(MPD(result), MPD(self), CTX(context), &status); \
3739
if (dec_addstatus(context, status)) { \
3740
Py_DECREF(result); \
3747
/* Binary function with an optional context arg. */
3748
#define Dec_BinaryFuncVA(MPDFUNC) \
3750
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3752
static char *kwlist[] = {"other", "context", NULL}; \
3756
PyObject *context = Py_None; \
3757
uint32_t status = 0; \
3759
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
3760
&other, &context)) { \
3763
CONTEXT_CHECK_VA(context); \
3764
CONVERT_BINOP_RAISE(&a, &b, self, other, context); \
3766
if ((result = dec_alloc()) == NULL) { \
3772
MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
3775
if (dec_addstatus(context, status)) { \
3776
Py_DECREF(result); \
3783
/* Binary function with an optional context arg. Actual MPDFUNC does
3784
NOT take a context. The context is used to record InvalidOperation
3785
if the second operand cannot be converted exactly. */
3786
#define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \
3788
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3790
static char *kwlist[] = {"other", "context", NULL}; \
3791
PyObject *context = Py_None; \
3796
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist, \
3797
&other, &context)) { \
3800
CONTEXT_CHECK_VA(context); \
3801
CONVERT_BINOP_RAISE(&a, &b, self, other, context); \
3803
if ((result = dec_alloc()) == NULL) { \
3809
MPDFUNC(MPD(result), MPD(a), MPD(b)); \
3816
/* Ternary function with an optional context arg. */
3817
#define Dec_TernaryFuncVA(MPDFUNC) \
3819
dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \
3821
static char *kwlist[] = {"other", "third", "context", NULL}; \
3822
PyObject *other, *third; \
3823
PyObject *a, *b, *c; \
3825
PyObject *context = Py_None; \
3826
uint32_t status = 0; \
3828
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, \
3829
&other, &third, &context)) { \
3832
CONTEXT_CHECK_VA(context); \
3833
CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context); \
3835
if ((result = dec_alloc()) == NULL) { \
3842
MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \
3846
if (dec_addstatus(context, status)) { \
3847
Py_DECREF(result); \
3855
/**********************************************/
3856
/* Number methods */
3857
/**********************************************/
3859
Dec_UnaryNumberMethod(mpd_qminus)
3860
Dec_UnaryNumberMethod(mpd_qplus)
3861
Dec_UnaryNumberMethod(mpd_qabs)
3863
Dec_BinaryNumberMethod(mpd_qadd)
3864
Dec_BinaryNumberMethod(mpd_qsub)
3865
Dec_BinaryNumberMethod(mpd_qmul)
3866
Dec_BinaryNumberMethod(mpd_qdiv)
3867
Dec_BinaryNumberMethod(mpd_qrem)
3868
Dec_BinaryNumberMethod(mpd_qdivint)
3871
nm_dec_as_long(PyObject *dec)
3875
CURRENT_CONTEXT(context);
3876
return dec_as_long(dec, context, MPD_ROUND_DOWN);
3880
nm_nonzero(PyObject *v)
3882
return !mpd_iszero(MPD(v));
3886
nm_mpd_qdivmod(PyObject *v, PyObject *w)
3891
uint32_t status = 0;
3894
CURRENT_CONTEXT(context);
3895
CONVERT_BINOP(&a, &b, v, w, context);
3911
mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status);
3914
if (dec_addstatus(context, status)) {
3920
ret = Py_BuildValue("(OO)", q, r);
3926
static mpd_uint_t data_zero[1] = {0};
3927
static const mpd_t zero = {MPD_STATIC|MPD_CONST_DATA, 0, 1, 1, 1, data_zero};
3930
nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod)
3932
PyObject *a, *b, *c = NULL;
3935
uint32_t status = 0;
3937
CURRENT_CONTEXT(context);
3938
CONVERT_BINOP(&a, &b, base, exp, context);
3940
if (mod != Py_None) {
3941
if (!convert_op(NOT_IMPL, &c, mod, context)) {
3948
result = dec_alloc();
3949
if (result == NULL) {
3957
mpd_qpow(MPD(result), MPD(a), MPD(b),
3958
CTX(context), &status);
3961
mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c),
3962
CTX(context), &status);
3967
if (dec_addstatus(context, status)) {
3976
/******************************************************************************/
3977
/* Decimal Methods */
3978
/******************************************************************************/
3980
/* Unary arithmetic functions, optional context arg */
3981
Dec_UnaryFuncVA(mpd_qexp)
3982
Dec_UnaryFuncVA(mpd_qln)
3983
Dec_UnaryFuncVA(mpd_qlog10)
3984
Dec_UnaryFuncVA(mpd_qnext_minus)
3985
Dec_UnaryFuncVA(mpd_qnext_plus)
3986
Dec_UnaryFuncVA(mpd_qreduce)
3987
Dec_UnaryFuncVA(mpd_qsqrt)
3989
/* Binary arithmetic functions, optional context arg */
3990
Dec_BinaryFuncVA(mpd_qcompare)
3991
Dec_BinaryFuncVA(mpd_qcompare_signal)
3992
Dec_BinaryFuncVA(mpd_qmax)
3993
Dec_BinaryFuncVA(mpd_qmax_mag)
3994
Dec_BinaryFuncVA(mpd_qmin)
3995
Dec_BinaryFuncVA(mpd_qmin_mag)
3996
Dec_BinaryFuncVA(mpd_qnext_toward)
3997
Dec_BinaryFuncVA(mpd_qrem_near)
3999
/* Ternary arithmetic functions, optional context arg */
4000
Dec_TernaryFuncVA(mpd_qfma)
4002
/* Boolean functions, no context arg */
4003
Dec_BoolFunc(mpd_iscanonical)
4004
Dec_BoolFunc(mpd_isfinite)
4005
Dec_BoolFunc(mpd_isinfinite)
4006
Dec_BoolFunc(mpd_isnan)
4007
Dec_BoolFunc(mpd_isqnan)
4008
Dec_BoolFunc(mpd_issnan)
4009
Dec_BoolFunc(mpd_issigned)
4010
Dec_BoolFunc(mpd_iszero)
4012
/* Boolean functions, optional context arg */
4013
Dec_BoolFuncVA(mpd_isnormal)
4014
Dec_BoolFuncVA(mpd_issubnormal)
4016
/* Unary functions, no context arg */
4018
dec_mpd_adjexp(PyObject *self, PyObject *dummy UNUSED)
4022
if (mpd_isspecial(MPD(self))) {
4026
retval = mpd_adjexp(MPD(self));
4029
return PyLong_FromSsize_t(retval);
4033
dec_canonical(PyObject *self, PyObject *dummy UNUSED)
4040
dec_conjugate(PyObject *self, PyObject *dummy UNUSED)
4047
dec_mpd_radix(PyObject *self UNUSED, PyObject *dummy UNUSED)
4051
result = dec_alloc();
4052
if (result == NULL) {
4056
_dec_settriple(result, MPD_POS, 10, 0);
4061
dec_mpd_qcopy_abs(PyObject *self, PyObject *dummy UNUSED)
4064
uint32_t status = 0;
4066
if ((result = dec_alloc()) == NULL) {
4070
mpd_qcopy_abs(MPD(result), MPD(self), &status);
4071
if (status & MPD_Malloc_error) {
4081
dec_mpd_qcopy_negate(PyObject *self, PyObject *dummy UNUSED)
4084
uint32_t status = 0;
4086
if ((result = dec_alloc()) == NULL) {
4090
mpd_qcopy_negate(MPD(result), MPD(self), &status);
4091
if (status & MPD_Malloc_error) {
4100
/* Unary functions, optional context arg */
4101
Dec_UnaryFuncVA(mpd_qinvert)
4102
Dec_UnaryFuncVA(mpd_qlogb)
4105
dec_mpd_class(PyObject *self, PyObject *args, PyObject *kwds)
4107
static char *kwlist[] = {"context", NULL};
4108
PyObject *context = Py_None;
4111
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
4115
CONTEXT_CHECK_VA(context);
4117
cp = mpd_class(MPD(self), CTX(context));
4118
return PyUnicode_FromString(cp);
4122
dec_mpd_to_eng(PyObject *self, PyObject *args, PyObject *kwds)
4124
static char *kwlist[] = {"context", NULL};
4126
PyObject *context = Py_None;
4130
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
4134
CONTEXT_CHECK_VA(context);
4136
size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context));
4142
result = unicode_fromascii(s, size);
4148
/* Binary functions, optional context arg for conversion errors */
4149
Dec_BinaryFuncVA_NO_CTX(mpd_compare_total)
4150
Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag)
4153
dec_mpd_qcopy_sign(PyObject *self, PyObject *args, PyObject *kwds)
4155
static char *kwlist[] = {"other", "context", NULL};
4159
PyObject *context = Py_None;
4160
uint32_t status = 0;
4162
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
4163
&other, &context)) {
4166
CONTEXT_CHECK_VA(context);
4167
CONVERT_BINOP_RAISE(&a, &b, self, other, context);
4169
result = dec_alloc();
4170
if (result == NULL) {
4176
mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
4179
if (dec_addstatus(context, status)) {
4188
dec_mpd_same_quantum(PyObject *self, PyObject *args, PyObject *kwds)
4190
static char *kwlist[] = {"other", "context", NULL};
4194
PyObject *context = Py_None;
4196
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,
4197
&other, &context)) {
4200
CONTEXT_CHECK_VA(context);
4201
CONVERT_BINOP_RAISE(&a, &b, self, other, context);
4203
result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false();
4210
/* Binary functions, optional context arg */
4211
Dec_BinaryFuncVA(mpd_qand)
4212
Dec_BinaryFuncVA(mpd_qor)
4213
Dec_BinaryFuncVA(mpd_qxor)
4215
Dec_BinaryFuncVA(mpd_qrotate)
4216
Dec_BinaryFuncVA(mpd_qscaleb)
4217
Dec_BinaryFuncVA(mpd_qshift)
4220
dec_mpd_qquantize(PyObject *v, PyObject *args, PyObject *kwds)
4222
static char *kwlist[] = {"exp", "rounding", "context", NULL};
4223
PyObject *rounding = Py_None;
4224
PyObject *context = Py_None;
4225
PyObject *w, *a, *b;
4227
uint32_t status = 0;
4228
mpd_context_t workctx;
4230
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO", kwlist,
4231
&w, &rounding, &context)) {
4234
CONTEXT_CHECK_VA(context);
4236
workctx = *CTX(context);
4237
if (rounding != Py_None) {
4238
int round = getround(rounding);
4242
if (!mpd_qsetround(&workctx, round)) {
4243
INTERNAL_ERROR_PTR("dec_mpd_qquantize"); /* GCOV_NOT_REACHED */
4247
CONVERT_BINOP_RAISE(&a, &b, v, w, context);
4249
result = dec_alloc();
4250
if (result == NULL) {
4256
mpd_qquantize(MPD(result), MPD(a), MPD(b), &workctx, &status);
4259
if (dec_addstatus(context, status)) {
4267
/* Special methods */
4269
dec_richcompare(PyObject *v, PyObject *w, int op)
4274
uint32_t status = 0;
4275
int a_issnan, b_issnan;
4278
assert(PyDec_Check(v));
4280
CURRENT_CONTEXT(context);
4281
CONVERT_BINOP_CMP(&a, &b, v, w, op, context);
4283
a_issnan = mpd_issnan(MPD(a));
4284
b_issnan = mpd_issnan(MPD(b));
4286
r = mpd_qcmp(MPD(a), MPD(b), &status);
4290
/* sNaNs or op={le,ge,lt,gt} always signal. */
4291
if (a_issnan || b_issnan || (op != Py_EQ && op != Py_NE)) {
4292
if (dec_addstatus(context, status)) {
4296
/* qNaN comparison with op={eq,ne} or comparison
4297
* with InvalidOperation disabled. */
4298
return (op == Py_NE) ? incr_true() : incr_false();
4322
return PyBool_FromLong(r);
4327
dec_ceil(PyObject *self, PyObject *dummy UNUSED)
4331
CURRENT_CONTEXT(context);
4332
return dec_as_long(self, context, MPD_ROUND_CEILING);
4337
dec_complex(PyObject *self, PyObject *dummy UNUSED)
4342
f = PyDec_AsFloat(self);
4347
x = PyFloat_AsDouble(f);
4349
if (x == -1.0 && PyErr_Occurred()) {
4353
return PyComplex_FromDoubles(x, 0);
4356
/* __copy__ and __deepcopy__ */
4358
dec_copy(PyObject *self, PyObject *dummy UNUSED)
4366
dec_floor(PyObject *self, PyObject *dummy UNUSED)
4370
CURRENT_CONTEXT(context);
4371
return dec_as_long(self, context, MPD_ROUND_FLOOR);
4374
/* Always uses the module context */
4376
_dec_hash(PyDecObject *v)
4378
#if defined(CONFIG_64) && _PyHASH_BITS == 61
4380
mpd_uint_t p_data[1] = {2305843009213693951ULL};
4381
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
4382
/* Inverse of 10 modulo p */
4383
mpd_uint_t inv10_p_data[1] = {2075258708292324556ULL};
4384
mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4385
0, 19, 1, 1, inv10_p_data};
4386
#elif defined(CONFIG_32) && _PyHASH_BITS == 31
4388
mpd_uint_t p_data[2] = {147483647UL, 2};
4389
mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data};
4390
/* Inverse of 10 modulo p */
4391
mpd_uint_t inv10_p_data[2] = {503238553UL, 1};
4392
mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4393
0, 10, 2, 2, inv10_p_data};
4395
#error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS"
4397
const Py_hash_t py_hash_inf = 314159;
4398
const Py_hash_t py_hash_nan = 0;
4399
mpd_uint_t ten_data[1] = {10};
4400
mpd_t ten = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
4401
0, 2, 1, 1, ten_data};
4403
mpd_t *exp_hash = NULL;
4406
uint32_t status = 0;
4407
mpd_context_t maxctx;
4411
context = current_context();
4412
if (context == NULL) {
4416
if (mpd_isspecial(MPD(v))) {
4417
if (mpd_issnan(MPD(v))) {
4418
PyErr_SetString(PyExc_TypeError,
4419
"Cannot hash a signaling NaN value");
4422
else if (mpd_isnan(MPD(v))) {
4426
return py_hash_inf * mpd_arith_sign(MPD(v));
4430
mpd_maxcontext(&maxctx);
4431
exp_hash = mpd_qnew();
4432
if (exp_hash == NULL) {
4441
* exp(v): exponent of v
4442
* int(v): coefficient of v
4446
/* 10**exp(v) % p */
4447
mpd_qsset_ssize(tmp, exp, &maxctx, &status);
4448
mpd_qpowmod(exp_hash, &ten, tmp, &p, &maxctx, &status);
4451
/* inv10_p**(-exp(v)) % p */
4452
mpd_qsset_ssize(tmp, -exp, &maxctx, &status);
4453
mpd_qpowmod(exp_hash, &inv10_p, tmp, &p, &maxctx, &status);
4456
/* hash = (int(v) * exp_hash) % p */
4457
if (!mpd_qcopy(tmp, MPD(v), &status)) {
4461
mpd_set_positive(tmp);
4463
maxctx.prec = MPD_MAX_PREC + 21;
4464
maxctx.emax = MPD_MAX_EMAX + 21;
4465
maxctx.emin = MPD_MIN_EMIN - 21;
4467
mpd_qmul(tmp, tmp, exp_hash, &maxctx, &status);
4468
mpd_qrem(tmp, tmp, &p, &maxctx, &status);
4470
result = mpd_qget_ssize(tmp, &status);
4471
result = mpd_ispositive(MPD(v)) ? result : -result;
4472
result = (result == -1) ? -2 : result;
4475
if (status & MPD_Malloc_error) {
4479
PyErr_SetString(PyExc_RuntimeError, /* GCOV_NOT_REACHED */
4480
"dec_hash: internal error: please report"); /* GCOV_NOT_REACHED */
4482
result = -1; /* GCOV_NOT_REACHED */
4487
if (exp_hash) mpd_del(exp_hash);
4488
if (tmp) mpd_del(tmp);
4498
dec_hash(PyDecObject *self)
4500
if (self->hash == -1) {
4501
self->hash = _dec_hash(self);
4509
dec_reduce(PyObject *self, PyObject *dummy UNUSED)
4511
PyObject *result, *str;
4513
str = dec_str(self);
4518
result = Py_BuildValue("O(O)", Py_TYPE(self), str);
4526
dec_sizeof(PyObject *v, PyObject *dummy UNUSED)
4530
res = sizeof(PyDecObject);
4531
if (mpd_isdynamic_data(MPD(v))) {
4532
res += MPD(v)->alloc * sizeof(mpd_uint_t);
4534
return PyLong_FromSsize_t(res);
4539
dec_trunc(PyObject *self, PyObject *dummy UNUSED)
4543
CURRENT_CONTEXT(context);
4544
return dec_as_long(self, context, MPD_ROUND_DOWN);
4549
dec_real(PyObject *self, void *closure UNUSED)
4556
dec_imag(PyObject *self UNUSED, void *closure UNUSED)
4560
result = dec_alloc();
4561
if (result == NULL) {
4565
_dec_settriple(result, MPD_POS, 0, 0);
4570
static PyGetSetDef dec_getsets [] =
4572
{ "real", (getter)dec_real, NULL, NULL, NULL},
4573
{ "imag", (getter)dec_imag, NULL, NULL, NULL},
4577
static PyNumberMethods dec_number_methods =
4579
(binaryfunc) nm_mpd_qadd,
4580
(binaryfunc) nm_mpd_qsub,
4581
(binaryfunc) nm_mpd_qmul,
4582
(binaryfunc) nm_mpd_qrem,
4583
(binaryfunc) nm_mpd_qdivmod,
4584
(ternaryfunc) nm_mpd_qpow,
4585
(unaryfunc) nm_mpd_qminus,
4586
(unaryfunc) nm_mpd_qplus,
4587
(unaryfunc) nm_mpd_qabs,
4588
(inquiry) nm_nonzero,
4589
(unaryfunc) 0, /* no bit-complement */
4590
(binaryfunc) 0, /* no shiftl */
4591
(binaryfunc) 0, /* no shiftr */
4592
(binaryfunc) 0, /* no bit-and */
4593
(binaryfunc) 0, /* no bit-xor */
4594
(binaryfunc) 0, /* no bit-ior */
4595
(unaryfunc) nm_dec_as_long,
4596
0, /* nb_reserved */
4597
(unaryfunc) PyDec_AsFloat,
4598
0, /* binaryfunc nb_inplace_add; */
4599
0, /* binaryfunc nb_inplace_subtract; */
4600
0, /* binaryfunc nb_inplace_multiply; */
4601
0, /* binaryfunc nb_inplace_remainder; */
4602
0, /* ternaryfunc nb_inplace_power; */
4603
0, /* binaryfunc nb_inplace_lshift; */
4604
0, /* binaryfunc nb_inplace_rshift; */
4605
0, /* binaryfunc nb_inplace_and; */
4606
0, /* binaryfunc nb_inplace_xor; */
4607
0, /* binaryfunc nb_inplace_or; */
4608
(binaryfunc) nm_mpd_qdivint, /* binaryfunc nb_floor_divide; */
4609
(binaryfunc) nm_mpd_qdiv, /* binaryfunc nb_true_divide; */
4610
0, /* binaryfunc nb_inplace_floor_divide; */
4611
0, /* binaryfunc nb_inplace_true_divide; */
4614
static PyMethodDef dec_methods [] =
4616
/* Unary arithmetic functions, optional context arg */
4617
{ "exp", (PyCFunction)dec_mpd_qexp, METH_VARARGS|METH_KEYWORDS, doc_exp },
4618
{ "ln", (PyCFunction)dec_mpd_qln, METH_VARARGS|METH_KEYWORDS, doc_ln },
4619
{ "log10", (PyCFunction)dec_mpd_qlog10, METH_VARARGS|METH_KEYWORDS, doc_log10 },
4620
{ "next_minus", (PyCFunction)dec_mpd_qnext_minus, METH_VARARGS|METH_KEYWORDS, doc_next_minus },
4621
{ "next_plus", (PyCFunction)dec_mpd_qnext_plus, METH_VARARGS|METH_KEYWORDS, doc_next_plus },
4622
{ "normalize", (PyCFunction)dec_mpd_qreduce, METH_VARARGS|METH_KEYWORDS, doc_normalize },
4623
{ "to_integral", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral },
4624
{ "to_integral_exact", (PyCFunction)PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact },
4625
{ "to_integral_value", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value },
4626
{ "sqrt", (PyCFunction)dec_mpd_qsqrt, METH_VARARGS|METH_KEYWORDS, doc_sqrt },
4628
/* Binary arithmetic functions, optional context arg */
4629
{ "compare", (PyCFunction)dec_mpd_qcompare, METH_VARARGS|METH_KEYWORDS, doc_compare },
4630
{ "compare_signal", (PyCFunction)dec_mpd_qcompare_signal, METH_VARARGS|METH_KEYWORDS, doc_compare_signal },
4631
{ "max", (PyCFunction)dec_mpd_qmax, METH_VARARGS|METH_KEYWORDS, doc_max },
4632
{ "max_mag", (PyCFunction)dec_mpd_qmax_mag, METH_VARARGS|METH_KEYWORDS, doc_max_mag },
4633
{ "min", (PyCFunction)dec_mpd_qmin, METH_VARARGS|METH_KEYWORDS, doc_min },
4634
{ "min_mag", (PyCFunction)dec_mpd_qmin_mag, METH_VARARGS|METH_KEYWORDS, doc_min_mag },
4635
{ "next_toward", (PyCFunction)dec_mpd_qnext_toward, METH_VARARGS|METH_KEYWORDS, doc_next_toward },
4636
{ "quantize", (PyCFunction)dec_mpd_qquantize, METH_VARARGS|METH_KEYWORDS, doc_quantize },
4637
{ "remainder_near", (PyCFunction)dec_mpd_qrem_near, METH_VARARGS|METH_KEYWORDS, doc_remainder_near },
4639
/* Ternary arithmetic functions, optional context arg */
4640
{ "fma", (PyCFunction)dec_mpd_qfma, METH_VARARGS|METH_KEYWORDS, doc_fma },
4642
/* Boolean functions, no context arg */
4643
{ "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical },
4644
{ "is_finite", dec_mpd_isfinite, METH_NOARGS, doc_is_finite },
4645
{ "is_infinite", dec_mpd_isinfinite, METH_NOARGS, doc_is_infinite },
4646
{ "is_nan", dec_mpd_isnan, METH_NOARGS, doc_is_nan },
4647
{ "is_qnan", dec_mpd_isqnan, METH_NOARGS, doc_is_qnan },
4648
{ "is_snan", dec_mpd_issnan, METH_NOARGS, doc_is_snan },
4649
{ "is_signed", dec_mpd_issigned, METH_NOARGS, doc_is_signed },
4650
{ "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero },
4652
/* Boolean functions, optional context arg */
4653
{ "is_normal", (PyCFunction)dec_mpd_isnormal, METH_VARARGS|METH_KEYWORDS, doc_is_normal },
4654
{ "is_subnormal", (PyCFunction)dec_mpd_issubnormal, METH_VARARGS|METH_KEYWORDS, doc_is_subnormal },
4656
/* Unary functions, no context arg */
4657
{ "adjusted", dec_mpd_adjexp, METH_NOARGS, doc_adjusted },
4658
{ "canonical", dec_canonical, METH_NOARGS, doc_canonical },
4659
{ "conjugate", dec_conjugate, METH_NOARGS, doc_conjugate },
4660
{ "radix", dec_mpd_radix, METH_NOARGS, doc_radix },
4662
/* Unary functions, optional context arg for conversion errors */
4663
{ "copy_abs", dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs },
4664
{ "copy_negate", dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate },
4666
/* Unary functions, optional context arg */
4667
{ "logb", (PyCFunction)dec_mpd_qlogb, METH_VARARGS|METH_KEYWORDS, doc_logb },
4668
{ "logical_invert", (PyCFunction)dec_mpd_qinvert, METH_VARARGS|METH_KEYWORDS, doc_logical_invert },
4669
{ "number_class", (PyCFunction)dec_mpd_class, METH_VARARGS|METH_KEYWORDS, doc_number_class },
4670
{ "to_eng_string", (PyCFunction)dec_mpd_to_eng, METH_VARARGS|METH_KEYWORDS, doc_to_eng_string },
4672
/* Binary functions, optional context arg for conversion errors */
4673
{ "compare_total", (PyCFunction)dec_mpd_compare_total, METH_VARARGS|METH_KEYWORDS, doc_compare_total },
4674
{ "compare_total_mag", (PyCFunction)dec_mpd_compare_total_mag, METH_VARARGS|METH_KEYWORDS, doc_compare_total_mag },
4675
{ "copy_sign", (PyCFunction)dec_mpd_qcopy_sign, METH_VARARGS|METH_KEYWORDS, doc_copy_sign },
4676
{ "same_quantum", (PyCFunction)dec_mpd_same_quantum, METH_VARARGS|METH_KEYWORDS, doc_same_quantum },
4678
/* Binary functions, optional context arg */
4679
{ "logical_and", (PyCFunction)dec_mpd_qand, METH_VARARGS|METH_KEYWORDS, doc_logical_and },
4680
{ "logical_or", (PyCFunction)dec_mpd_qor, METH_VARARGS|METH_KEYWORDS, doc_logical_or },
4681
{ "logical_xor", (PyCFunction)dec_mpd_qxor, METH_VARARGS|METH_KEYWORDS, doc_logical_xor },
4682
{ "rotate", (PyCFunction)dec_mpd_qrotate, METH_VARARGS|METH_KEYWORDS, doc_rotate },
4683
{ "scaleb", (PyCFunction)dec_mpd_qscaleb, METH_VARARGS|METH_KEYWORDS, doc_scaleb },
4684
{ "shift", (PyCFunction)dec_mpd_qshift, METH_VARARGS|METH_KEYWORDS, doc_shift },
4687
{ "from_float", dec_from_float, METH_O|METH_CLASS, doc_from_float },
4688
{ "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple },
4690
/* Special methods */
4691
{ "__copy__", dec_copy, METH_NOARGS, NULL },
4692
{ "__deepcopy__", dec_copy, METH_O, NULL },
4693
{ "__format__", dec_format, METH_VARARGS, NULL },
4694
{ "__reduce__", dec_reduce, METH_NOARGS, NULL },
4695
{ "__round__", PyDec_Round, METH_VARARGS, NULL },
4696
{ "__ceil__", dec_ceil, METH_NOARGS, NULL },
4697
{ "__floor__", dec_floor, METH_NOARGS, NULL },
4698
{ "__trunc__", dec_trunc, METH_NOARGS, NULL },
4699
{ "__complex__", dec_complex, METH_NOARGS, NULL },
4700
{ "__sizeof__", dec_sizeof, METH_NOARGS, NULL },
4705
static PyTypeObject PyDec_Type =
4707
PyVarObject_HEAD_INIT(NULL, 0)
4708
"decimal.Decimal", /* tp_name */
4709
sizeof(PyDecObject), /* tp_basicsize */
4710
0, /* tp_itemsize */
4711
(destructor) dec_dealloc, /* tp_dealloc */
4713
(getattrfunc) 0, /* tp_getattr */
4714
(setattrfunc) 0, /* tp_setattr */
4715
0, /* tp_reserved */
4716
(reprfunc) dec_repr, /* tp_repr */
4717
&dec_number_methods, /* tp_as_number */
4718
0, /* tp_as_sequence */
4719
0, /* tp_as_mapping */
4720
(hashfunc) dec_hash, /* tp_hash */
4722
(reprfunc) dec_str, /* tp_str */
4723
(getattrofunc) PyObject_GenericGetAttr, /* tp_getattro */
4724
(setattrofunc) 0, /* tp_setattro */
4725
(PyBufferProcs *) 0, /* tp_as_buffer */
4726
(Py_TPFLAGS_DEFAULT|
4727
Py_TPFLAGS_BASETYPE), /* tp_flags */
4728
doc_decimal, /* tp_doc */
4729
0, /* tp_traverse */
4731
dec_richcompare, /* tp_richcompare */
4732
0, /* tp_weaklistoffset */
4734
0, /* tp_iternext */
4735
dec_methods, /* tp_methods */
4737
dec_getsets, /* tp_getset */
4740
0, /* tp_descr_get */
4741
0, /* tp_descr_set */
4742
0, /* tp_dictoffset */
4745
dec_new, /* tp_new */
4746
PyObject_Del, /* tp_free */
4750
/******************************************************************************/
4751
/* Context Object, Part 2 */
4752
/******************************************************************************/
4755
/************************************************************************/
4756
/* Macros for converting mpdecimal functions to Context methods */
4757
/************************************************************************/
4759
/* Boolean context method. */
4760
#define DecCtx_BoolFunc(MPDFUNC) \
4762
ctx_##MPDFUNC(PyObject *context, PyObject *v) \
4767
CONVERT_OP_RAISE(&a, v, context); \
4769
ret = MPDFUNC(MPD(a), CTX(context)) ? incr_true() : incr_false(); \
4774
/* Boolean context method. MPDFUNC does NOT use a context. */
4775
#define DecCtx_BoolFunc_NO_CTX(MPDFUNC) \
4777
ctx_##MPDFUNC(PyObject *context, PyObject *v) \
4782
CONVERT_OP_RAISE(&a, v, context); \
4784
ret = MPDFUNC(MPD(a)) ? incr_true() : incr_false(); \
4789
/* Unary context method. */
4790
#define DecCtx_UnaryFunc(MPDFUNC) \
4792
ctx_##MPDFUNC(PyObject *context, PyObject *v) \
4794
PyObject *result, *a; \
4795
uint32_t status = 0; \
4797
CONVERT_OP_RAISE(&a, v, context); \
4799
if ((result = dec_alloc()) == NULL) { \
4804
MPDFUNC(MPD(result), MPD(a), CTX(context), &status); \
4806
if (dec_addstatus(context, status)) { \
4807
Py_DECREF(result); \
4814
/* Binary context method. */
4815
#define DecCtx_BinaryFunc(MPDFUNC) \
4817
ctx_##MPDFUNC(PyObject *context, PyObject *args) \
4822
uint32_t status = 0; \
4824
if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \
4828
CONVERT_BINOP_RAISE(&a, &b, v, w, context); \
4830
if ((result = dec_alloc()) == NULL) { \
4836
MPDFUNC(MPD(result), MPD(a), MPD(b), CTX(context), &status); \
4839
if (dec_addstatus(context, status)) { \
4840
Py_DECREF(result); \
4848
* Binary context method. The context is only used for conversion.
4849
* The actual MPDFUNC does NOT take a context arg.
4851
#define DecCtx_BinaryFunc_NO_CTX(MPDFUNC) \
4853
ctx_##MPDFUNC(PyObject *context, PyObject *args) \
4859
if (!PyArg_ParseTuple(args, "OO", &v, &w)) { \
4863
CONVERT_BINOP_RAISE(&a, &b, v, w, context); \
4865
if ((result = dec_alloc()) == NULL) { \
4871
MPDFUNC(MPD(result), MPD(a), MPD(b)); \
4878
/* Ternary context method. */
4879
#define DecCtx_TernaryFunc(MPDFUNC) \
4881
ctx_##MPDFUNC(PyObject *context, PyObject *args) \
4883
PyObject *v, *w, *x; \
4884
PyObject *a, *b, *c; \
4886
uint32_t status = 0; \
4888
if (!PyArg_ParseTuple(args, "OOO", &v, &w, &x)) { \
4892
CONVERT_TERNOP_RAISE(&a, &b, &c, v, w, x, context); \
4894
if ((result = dec_alloc()) == NULL) { \
4901
MPDFUNC(MPD(result), MPD(a), MPD(b), MPD(c), CTX(context), &status); \
4905
if (dec_addstatus(context, status)) { \
4906
Py_DECREF(result); \
4914
/* Unary arithmetic functions */
4915
DecCtx_UnaryFunc(mpd_qabs)
4916
DecCtx_UnaryFunc(mpd_qexp)
4917
DecCtx_UnaryFunc(mpd_qln)
4918
DecCtx_UnaryFunc(mpd_qlog10)
4919
DecCtx_UnaryFunc(mpd_qminus)
4920
DecCtx_UnaryFunc(mpd_qnext_minus)
4921
DecCtx_UnaryFunc(mpd_qnext_plus)
4922
DecCtx_UnaryFunc(mpd_qplus)
4923
DecCtx_UnaryFunc(mpd_qreduce)
4924
DecCtx_UnaryFunc(mpd_qround_to_int)
4925
DecCtx_UnaryFunc(mpd_qround_to_intx)
4926
DecCtx_UnaryFunc(mpd_qsqrt)
4928
/* Binary arithmetic functions */
4929
DecCtx_BinaryFunc(mpd_qadd)
4930
DecCtx_BinaryFunc(mpd_qcompare)
4931
DecCtx_BinaryFunc(mpd_qcompare_signal)
4932
DecCtx_BinaryFunc(mpd_qdiv)
4933
DecCtx_BinaryFunc(mpd_qdivint)
4934
DecCtx_BinaryFunc(mpd_qmax)
4935
DecCtx_BinaryFunc(mpd_qmax_mag)
4936
DecCtx_BinaryFunc(mpd_qmin)
4937
DecCtx_BinaryFunc(mpd_qmin_mag)
4938
DecCtx_BinaryFunc(mpd_qmul)
4939
DecCtx_BinaryFunc(mpd_qnext_toward)
4940
DecCtx_BinaryFunc(mpd_qquantize)
4941
DecCtx_BinaryFunc(mpd_qrem)
4942
DecCtx_BinaryFunc(mpd_qrem_near)
4943
DecCtx_BinaryFunc(mpd_qsub)
4946
ctx_mpd_qdivmod(PyObject *context, PyObject *args)
4951
uint32_t status = 0;
4954
if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
4958
CONVERT_BINOP_RAISE(&a, &b, v, w, context);
4974
mpd_qdivmod(MPD(q), MPD(r), MPD(a), MPD(b), CTX(context), &status);
4977
if (dec_addstatus(context, status)) {
4983
ret = Py_BuildValue("(OO)", q, r);
4989
/* Binary or ternary arithmetic functions */
4991
ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds)
4993
static char *kwlist[] = {"a", "b", "modulo", NULL};
4994
PyObject *base, *exp, *mod = Py_None;
4995
PyObject *a, *b, *c = NULL;
4997
uint32_t status = 0;
4999
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist,
5000
&base, &exp, &mod)) {
5004
CONVERT_BINOP_RAISE(&a, &b, base, exp, context);
5006
if (mod != Py_None) {
5007
if (!convert_op(TYPE_ERR, &c, mod, context)) {
5014
result = dec_alloc();
5015
if (result == NULL) {
5023
mpd_qpow(MPD(result), MPD(a), MPD(b),
5024
CTX(context), &status);
5027
mpd_qpowmod(MPD(result), MPD(a), MPD(b), MPD(c),
5028
CTX(context), &status);
5033
if (dec_addstatus(context, status)) {
5041
/* Ternary arithmetic functions */
5042
DecCtx_TernaryFunc(mpd_qfma)
5046
ctx_mpd_radix(PyObject *context, PyObject *dummy)
5048
return dec_mpd_radix(context, dummy);
5051
/* Boolean functions: single decimal argument */
5052
DecCtx_BoolFunc(mpd_isnormal)
5053
DecCtx_BoolFunc(mpd_issubnormal)
5054
DecCtx_BoolFunc_NO_CTX(mpd_isfinite)
5055
DecCtx_BoolFunc_NO_CTX(mpd_isinfinite)
5056
DecCtx_BoolFunc_NO_CTX(mpd_isnan)
5057
DecCtx_BoolFunc_NO_CTX(mpd_isqnan)
5058
DecCtx_BoolFunc_NO_CTX(mpd_issigned)
5059
DecCtx_BoolFunc_NO_CTX(mpd_issnan)
5060
DecCtx_BoolFunc_NO_CTX(mpd_iszero)
5063
ctx_iscanonical(PyObject *context UNUSED, PyObject *v)
5065
if (!PyDec_Check(v)) {
5066
PyErr_SetString(PyExc_TypeError,
5067
"argument must be a Decimal");
5071
return mpd_iscanonical(MPD(v)) ? incr_true() : incr_false();
5074
/* Functions with a single decimal argument */
5076
PyDecContext_Apply(PyObject *context, PyObject *v)
5078
PyObject *result, *a;
5080
CONVERT_OP_RAISE(&a, v, context);
5082
result = dec_apply(a, context);
5088
ctx_canonical(PyObject *context UNUSED, PyObject *v)
5090
if (!PyDec_Check(v)) {
5091
PyErr_SetString(PyExc_TypeError,
5092
"argument must be a Decimal");
5101
ctx_mpd_qcopy_abs(PyObject *context, PyObject *v)
5103
PyObject *result, *a;
5104
uint32_t status = 0;
5106
CONVERT_OP_RAISE(&a, v, context);
5108
result = dec_alloc();
5109
if (result == NULL) {
5114
mpd_qcopy_abs(MPD(result), MPD(a), &status);
5116
if (dec_addstatus(context, status)) {
5125
ctx_copy_decimal(PyObject *context, PyObject *v)
5129
CONVERT_OP_RAISE(&result, v, context);
5134
ctx_mpd_qcopy_negate(PyObject *context, PyObject *v)
5136
PyObject *result, *a;
5137
uint32_t status = 0;
5139
CONVERT_OP_RAISE(&a, v, context);
5141
result = dec_alloc();
5142
if (result == NULL) {
5147
mpd_qcopy_negate(MPD(result), MPD(a), &status);
5149
if (dec_addstatus(context, status)) {
5157
DecCtx_UnaryFunc(mpd_qlogb)
5158
DecCtx_UnaryFunc(mpd_qinvert)
5161
ctx_mpd_class(PyObject *context, PyObject *v)
5166
CONVERT_OP_RAISE(&a, v, context);
5168
cp = mpd_class(MPD(a), CTX(context));
5171
return PyUnicode_FromString(cp);
5175
ctx_mpd_to_sci(PyObject *context, PyObject *v)
5182
CONVERT_OP_RAISE(&a, v, context);
5184
size = mpd_to_sci_size(&s, MPD(a), CtxCaps(context));
5191
result = unicode_fromascii(s, size);
5198
ctx_mpd_to_eng(PyObject *context, PyObject *v)
5205
CONVERT_OP_RAISE(&a, v, context);
5207
size = mpd_to_eng_size(&s, MPD(a), CtxCaps(context));
5214
result = unicode_fromascii(s, size);
5220
/* Functions with two decimal arguments */
5221
DecCtx_BinaryFunc_NO_CTX(mpd_compare_total)
5222
DecCtx_BinaryFunc_NO_CTX(mpd_compare_total_mag)
5225
ctx_mpd_qcopy_sign(PyObject *context, PyObject *args)
5230
uint32_t status = 0;
5232
if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5236
CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5238
result = dec_alloc();
5239
if (result == NULL) {
5245
mpd_qcopy_sign(MPD(result), MPD(a), MPD(b), &status);
5248
if (dec_addstatus(context, status)) {
5256
DecCtx_BinaryFunc(mpd_qand)
5257
DecCtx_BinaryFunc(mpd_qor)
5258
DecCtx_BinaryFunc(mpd_qxor)
5260
DecCtx_BinaryFunc(mpd_qrotate)
5261
DecCtx_BinaryFunc(mpd_qscaleb)
5262
DecCtx_BinaryFunc(mpd_qshift)
5265
ctx_mpd_same_quantum(PyObject *context, PyObject *args)
5271
if (!PyArg_ParseTuple(args, "OO", &v, &w)) {
5275
CONVERT_BINOP_RAISE(&a, &b, v, w, context);
5277
result = mpd_same_quantum(MPD(a), MPD(b)) ? incr_true() : incr_false();
5285
static PyMethodDef context_methods [] =
5287
/* Unary arithmetic functions */
5288
{ "abs", ctx_mpd_qabs, METH_O, doc_ctx_abs },
5289
{ "exp", ctx_mpd_qexp, METH_O, doc_ctx_exp },
5290
{ "ln", ctx_mpd_qln, METH_O, doc_ctx_ln },
5291
{ "log10", ctx_mpd_qlog10, METH_O, doc_ctx_log10 },
5292
{ "minus", ctx_mpd_qminus, METH_O, doc_ctx_minus },
5293
{ "next_minus", ctx_mpd_qnext_minus, METH_O, doc_ctx_next_minus },
5294
{ "next_plus", ctx_mpd_qnext_plus, METH_O, doc_ctx_next_plus },
5295
{ "normalize", ctx_mpd_qreduce, METH_O, doc_ctx_normalize },
5296
{ "plus", ctx_mpd_qplus, METH_O, doc_ctx_plus },
5297
{ "to_integral", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral },
5298
{ "to_integral_exact", ctx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact },
5299
{ "to_integral_value", ctx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value },
5300
{ "sqrt", ctx_mpd_qsqrt, METH_O, doc_ctx_sqrt },
5302
/* Binary arithmetic functions */
5303
{ "add", ctx_mpd_qadd, METH_VARARGS, doc_ctx_add },
5304
{ "compare", ctx_mpd_qcompare, METH_VARARGS, doc_ctx_compare },
5305
{ "compare_signal", ctx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal },
5306
{ "divide", ctx_mpd_qdiv, METH_VARARGS, doc_ctx_divide },
5307
{ "divide_int", ctx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int },
5308
{ "divmod", ctx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod },
5309
{ "max", ctx_mpd_qmax, METH_VARARGS, doc_ctx_max },
5310
{ "max_mag", ctx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag },
5311
{ "min", ctx_mpd_qmin, METH_VARARGS, doc_ctx_min },
5312
{ "min_mag", ctx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag },
5313
{ "multiply", ctx_mpd_qmul, METH_VARARGS, doc_ctx_multiply },
5314
{ "next_toward", ctx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward },
5315
{ "quantize", ctx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize },
5316
{ "remainder", ctx_mpd_qrem, METH_VARARGS, doc_ctx_remainder },
5317
{ "remainder_near", ctx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near },
5318
{ "subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract },
5320
/* Binary or ternary arithmetic functions */
5321
{ "power", (PyCFunction)ctx_mpd_qpow, METH_VARARGS|METH_KEYWORDS, doc_ctx_power },
5323
/* Ternary arithmetic functions */
5324
{ "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma },
5327
{ "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny },
5328
{ "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop },
5329
{ "radix", ctx_mpd_radix, METH_NOARGS, doc_ctx_radix },
5331
/* Boolean functions */
5332
{ "is_canonical", ctx_iscanonical, METH_O, doc_ctx_is_canonical },
5333
{ "is_finite", ctx_mpd_isfinite, METH_O, doc_ctx_is_finite },
5334
{ "is_infinite", ctx_mpd_isinfinite, METH_O, doc_ctx_is_infinite },
5335
{ "is_nan", ctx_mpd_isnan, METH_O, doc_ctx_is_nan },
5336
{ "is_normal", ctx_mpd_isnormal, METH_O, doc_ctx_is_normal },
5337
{ "is_qnan", ctx_mpd_isqnan, METH_O, doc_ctx_is_qnan },
5338
{ "is_signed", ctx_mpd_issigned, METH_O, doc_ctx_is_signed },
5339
{ "is_snan", ctx_mpd_issnan, METH_O, doc_ctx_is_snan },
5340
{ "is_subnormal", ctx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal },
5341
{ "is_zero", ctx_mpd_iszero, METH_O, doc_ctx_is_zero },
5343
/* Functions with a single decimal argument */
5344
{ "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */
5345
#ifdef EXTRA_FUNCTIONALITY
5346
{ "apply", PyDecContext_Apply, METH_O, doc_ctx_apply },
5348
{ "canonical", ctx_canonical, METH_O, doc_ctx_canonical },
5349
{ "copy_abs", ctx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs },
5350
{ "copy_decimal", ctx_copy_decimal, METH_O, doc_ctx_copy_decimal },
5351
{ "copy_negate", ctx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate },
5352
{ "logb", ctx_mpd_qlogb, METH_O, doc_ctx_logb },
5353
{ "logical_invert", ctx_mpd_qinvert, METH_O, doc_ctx_logical_invert },
5354
{ "number_class", ctx_mpd_class, METH_O, doc_ctx_number_class },
5355
{ "to_sci_string", ctx_mpd_to_sci, METH_O, doc_ctx_to_sci_string },
5356
{ "to_eng_string", ctx_mpd_to_eng, METH_O, doc_ctx_to_eng_string },
5358
/* Functions with two decimal arguments */
5359
{ "compare_total", ctx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total },
5360
{ "compare_total_mag", ctx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag },
5361
{ "copy_sign", ctx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign },
5362
{ "logical_and", ctx_mpd_qand, METH_VARARGS, doc_ctx_logical_and },
5363
{ "logical_or", ctx_mpd_qor, METH_VARARGS, doc_ctx_logical_or },
5364
{ "logical_xor", ctx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor },
5365
{ "rotate", ctx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate },
5366
{ "same_quantum", ctx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum },
5367
{ "scaleb", ctx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb },
5368
{ "shift", ctx_mpd_qshift, METH_VARARGS, doc_ctx_shift },
5370
/* Set context values */
5371
{ "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags },
5372
{ "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps },
5375
/* Unsafe set functions with relaxed range checks */
5376
{ "_unsafe_setprec", context_unsafe_setprec, METH_O, NULL },
5377
{ "_unsafe_setemin", context_unsafe_setemin, METH_O, NULL },
5378
{ "_unsafe_setemax", context_unsafe_setemax, METH_O, NULL },
5382
{ "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL },
5383
{ "__reduce__", context_reduce, METH_NOARGS, NULL },
5384
{ "copy", (PyCFunction)context_copy, METH_NOARGS, doc_ctx_copy },
5385
{ "create_decimal", ctx_create_decimal, METH_VARARGS, doc_ctx_create_decimal },
5386
{ "create_decimal_from_float", ctx_from_float, METH_O, doc_ctx_create_decimal_from_float },
5391
static PyTypeObject PyDecContext_Type =
5393
PyVarObject_HEAD_INIT(NULL, 0)
5394
"decimal.Context", /* tp_name */
5395
sizeof(PyDecContextObject), /* tp_basicsize */
5396
0, /* tp_itemsize */
5397
(destructor) context_dealloc, /* tp_dealloc */
5399
(getattrfunc) 0, /* tp_getattr */
5400
(setattrfunc) 0, /* tp_setattr */
5401
0, /* tp_reserved */
5402
(reprfunc) context_repr, /* tp_repr */
5403
0, /* tp_as_number */
5404
0, /* tp_as_sequence */
5405
0, /* tp_as_mapping */
5406
(hashfunc) 0, /* tp_hash */
5408
(reprfunc) context_repr, /* tp_str */
5409
(getattrofunc) context_getattr, /* tp_getattro */
5410
(setattrofunc) context_setattr, /* tp_setattro */
5411
(PyBufferProcs *) 0, /* tp_as_buffer */
5412
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /* tp_flags */
5413
doc_context, /* tp_doc */
5414
0, /* tp_traverse */
5416
0, /* tp_richcompare */
5417
0, /* tp_weaklistoffset */
5419
0, /* tp_iternext */
5420
context_methods, /* tp_methods */
5422
context_getsets, /* tp_getset */
5425
0, /* tp_descr_get */
5426
0, /* tp_descr_set */
5427
0, /* tp_dictoffset */
5428
context_init, /* tp_init */
5430
context_new, /* tp_new */
5431
PyObject_Del, /* tp_free */
5435
static PyMethodDef _decimal_methods [] =
5437
{ "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext},
5438
{ "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext},
5439
{ "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS|METH_KEYWORDS, doc_localcontext},
5440
#ifdef EXTRA_FUNCTIONALITY
5441
{ "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context},
5443
{ NULL, NULL, 1, NULL }
5446
static struct PyModuleDef _decimal_module = {
5447
PyModuleDef_HEAD_INIT,
5458
struct ssize_constmap { const char *name; mpd_ssize_t val; };
5459
static struct ssize_constmap ssize_constants [] = {
5460
{"MAX_PREC", MPD_MAX_PREC},
5461
{"MAX_EMAX", MPD_MAX_EMAX},
5462
{"MIN_EMIN", MPD_MIN_EMIN},
5463
{"MIN_ETINY", MPD_MIN_ETINY},
5467
struct int_constmap { const char *name; int val; };
5468
static struct int_constmap int_constants [] = {
5470
#ifdef EXTRA_FUNCTIONALITY
5471
{"DECIMAL32", MPD_DECIMAL32},
5472
{"DECIMAL64", MPD_DECIMAL64},
5473
{"DECIMAL128", MPD_DECIMAL128},
5474
{"IEEE_CONTEXT_MAX_BITS", MPD_IEEE_CONTEXT_MAX_BITS},
5475
/* int condition flags */
5476
{"DecClamped", MPD_Clamped},
5477
{"DecConversionSyntax", MPD_Conversion_syntax},
5478
{"DecDivisionByZero", MPD_Division_by_zero},
5479
{"DecDivisionImpossible", MPD_Division_impossible},
5480
{"DecDivisionUndefined", MPD_Division_undefined},
5481
{"DecFpuError", MPD_Fpu_error},
5482
{"DecInexact", MPD_Inexact},
5483
{"DecInvalidContext", MPD_Invalid_context},
5484
{"DecInvalidOperation", MPD_Invalid_operation},
5485
{"DecIEEEInvalidOperation", MPD_IEEE_Invalid_operation},
5486
{"DecMallocError", MPD_Malloc_error},
5487
{"DecFloatOperation", MPD_Float_operation},
5488
{"DecOverflow", MPD_Overflow},
5489
{"DecRounded", MPD_Rounded},
5490
{"DecSubnormal", MPD_Subnormal},
5491
{"DecUnderflow", MPD_Underflow},
5492
{"DecErrors", MPD_Errors},
5493
{"DecTraps", MPD_Traps},
5499
#define CHECK_INT(expr) \
5500
do { if ((expr) < 0) goto error; } while (0)
5501
#define ASSIGN_PTR(result, expr) \
5502
do { result = (expr); if (result == NULL) goto error; } while (0)
5503
#define CHECK_PTR(expr) \
5504
do { if ((expr) == NULL) goto error; } while (0)
5507
PyInit__decimal(void)
5510
PyObject *numbers = NULL;
5511
PyObject *Number = NULL;
5512
PyObject *collections = NULL;
5513
PyObject *MutableMapping = NULL;
5514
PyObject *obj = NULL;
5516
struct ssize_constmap *ssize_cm;
5517
struct int_constmap *int_cm;
5522
mpd_traphandler = dec_traphandler;
5523
mpd_mallocfunc = PyMem_Malloc;
5524
mpd_reallocfunc = PyMem_Realloc;
5525
mpd_callocfunc = mpd_callocfunc_em;
5526
mpd_free = PyMem_Free;
5527
mpd_setminalloc(_Py_DEC_MINALLOC);
5531
PyDec_Type.tp_base = &PyBaseObject_Type;
5532
PyDecContext_Type.tp_base = &PyBaseObject_Type;
5533
PyDecContextManager_Type.tp_base = &PyBaseObject_Type;
5534
PyDecSignalDictMixin_Type.tp_base = &PyBaseObject_Type;
5536
CHECK_INT(PyType_Ready(&PyDec_Type));
5537
CHECK_INT(PyType_Ready(&PyDecContext_Type));
5538
CHECK_INT(PyType_Ready(&PyDecSignalDictMixin_Type));
5539
CHECK_INT(PyType_Ready(&PyDecContextManager_Type));
5541
ASSIGN_PTR(obj, PyUnicode_FromString("decimal"));
5542
CHECK_INT(PyDict_SetItemString(PyDec_Type.tp_dict, "__module__", obj));
5543
CHECK_INT(PyDict_SetItemString(PyDecContext_Type.tp_dict,
5544
"__module__", obj));
5548
/* Numeric abstract base classes */
5549
ASSIGN_PTR(numbers, PyImport_ImportModule("numbers"));
5550
ASSIGN_PTR(Number, PyObject_GetAttrString(numbers, "Number"));
5551
/* Register Decimal with the Number abstract base class */
5552
ASSIGN_PTR(obj, PyObject_CallMethod(Number, "register", "(O)",
5553
(PyObject *)&PyDec_Type));
5555
/* Rational is a global variable used for fraction comparisons. */
5556
ASSIGN_PTR(Rational, PyObject_GetAttrString(numbers, "Rational"));
5557
/* Done with numbers, Number */
5562
ASSIGN_PTR(collections, PyImport_ImportModule("collections"));
5563
ASSIGN_PTR(DecimalTuple, PyObject_CallMethod(collections,
5564
"namedtuple", "(ss)", "DecimalTuple",
5565
"sign digits exponent"));
5566
/* MutableMapping */
5567
ASSIGN_PTR(MutableMapping, PyObject_GetAttrString(collections,
5569
/* Create SignalDict type */
5570
ASSIGN_PTR(PyDecSignalDict_Type,
5571
(PyTypeObject *)PyObject_CallFunction(
5572
(PyObject *)&PyType_Type, "s(OO){}",
5573
"SignalDict", &PyDecSignalDictMixin_Type,
5576
/* Done with collections, MutableMapping */
5577
Py_CLEAR(collections);
5578
Py_CLEAR(MutableMapping);
5581
/* Create the module */
5582
ASSIGN_PTR(m, PyModule_Create(&_decimal_module));
5585
/* Add types to the module */
5586
Py_INCREF(&PyDec_Type);
5587
CHECK_INT(PyModule_AddObject(m, "Decimal", (PyObject *)&PyDec_Type));
5588
Py_INCREF(&PyDecContext_Type);
5589
CHECK_INT(PyModule_AddObject(m, "Context",
5590
(PyObject *)&PyDecContext_Type));
5591
Py_INCREF(DecimalTuple);
5592
CHECK_INT(PyModule_AddObject(m, "DecimalTuple", DecimalTuple));
5595
/* Create top level exception */
5596
ASSIGN_PTR(DecimalException, PyErr_NewException(
5597
"decimal.DecimalException",
5598
PyExc_ArithmeticError, NULL));
5599
Py_INCREF(DecimalException);
5600
CHECK_INT(PyModule_AddObject(m, "DecimalException", DecimalException));
5602
/* Create signal tuple */
5603
ASSIGN_PTR(SignalTuple, PyTuple_New(SIGNAL_MAP_LEN));
5605
/* Add exceptions that correspond to IEEE signals */
5606
for (i = SIGNAL_MAP_LEN-1; i >= 0; i--) {
5609
cm = signal_map + i;
5612
case MPD_Float_operation:
5613
base = PyTuple_Pack(2, DecimalException, PyExc_TypeError);
5615
case MPD_Division_by_zero:
5616
base = PyTuple_Pack(2, DecimalException, PyExc_ZeroDivisionError);
5619
base = PyTuple_Pack(2, signal_map[INEXACT].ex,
5620
signal_map[ROUNDED].ex);
5623
base = PyTuple_Pack(3, signal_map[INEXACT].ex,
5624
signal_map[ROUNDED].ex,
5625
signal_map[SUBNORMAL].ex);
5628
base = PyTuple_Pack(1, DecimalException);
5633
goto error; /* GCOV_NOT_REACHED */
5636
ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL));
5641
CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex));
5643
/* add to signal tuple */
5645
PyTuple_SET_ITEM(SignalTuple, i, cm->ex);
5649
* Unfortunately, InvalidOperation is a signal that comprises
5650
* several conditions, including InvalidOperation! Naming the
5651
* signal IEEEInvalidOperation would prevent the confusion.
5653
cond_map[0].ex = signal_map[0].ex;
5655
/* Add remaining exceptions, inherit from InvalidOperation */
5656
for (cm = cond_map+1; cm->name != NULL; cm++) {
5658
if (cm->flag == MPD_Division_undefined) {
5659
base = PyTuple_Pack(2, signal_map[0].ex, PyExc_ZeroDivisionError);
5662
base = PyTuple_Pack(1, signal_map[0].ex);
5665
goto error; /* GCOV_NOT_REACHED */
5668
ASSIGN_PTR(cm->ex, PyErr_NewException((char *)cm->fqname, base, NULL));
5672
CHECK_INT(PyModule_AddObject(m, cm->name, cm->ex));
5676
/* Init default context template first */
5677
ASSIGN_PTR(default_context_template,
5678
PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
5679
Py_INCREF(default_context_template);
5680
CHECK_INT(PyModule_AddObject(m, "DefaultContext",
5681
default_context_template));
5683
#ifdef WITHOUT_THREADS
5684
/* Init module context */
5685
ASSIGN_PTR(module_context,
5686
PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
5687
Py_INCREF(Py_False);
5688
CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_False));
5690
ASSIGN_PTR(tls_context_key, PyUnicode_FromString("___DECIMAL_CTX__"));
5692
CHECK_INT(PyModule_AddObject(m, "HAVE_THREADS", Py_True));
5695
/* Init basic context template */
5696
ASSIGN_PTR(basic_context_template,
5697
PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
5698
init_basic_context(basic_context_template);
5699
Py_INCREF(basic_context_template);
5700
CHECK_INT(PyModule_AddObject(m, "BasicContext",
5701
basic_context_template));
5703
/* Init extended context template */
5704
ASSIGN_PTR(extended_context_template,
5705
PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL));
5706
init_extended_context(extended_context_template);
5707
Py_INCREF(extended_context_template);
5708
CHECK_INT(PyModule_AddObject(m, "ExtendedContext",
5709
extended_context_template));
5712
/* Init mpd_ssize_t constants */
5713
for (ssize_cm = ssize_constants; ssize_cm->name != NULL; ssize_cm++) {
5714
ASSIGN_PTR(obj, PyLong_FromSsize_t(ssize_cm->val));
5715
CHECK_INT(PyModule_AddObject(m, ssize_cm->name, obj));
5719
/* Init int constants */
5720
for (int_cm = int_constants; int_cm->name != NULL; int_cm++) {
5721
CHECK_INT(PyModule_AddIntConstant(m, int_cm->name,
5725
/* Init string constants */
5726
for (i = 0; i < _PY_DEC_ROUND_GUARD; i++) {
5727
ASSIGN_PTR(round_map[i], PyUnicode_InternFromString(mpd_round_string[i]));
5728
Py_INCREF(round_map[i]);
5729
CHECK_INT(PyModule_AddObject(m, mpd_round_string[i], round_map[i]));
5732
/* Add specification version number */
5733
CHECK_INT(PyModule_AddStringConstant(m, "__version__", " 1.70"));
5740
Py_CLEAR(obj); /* GCOV_NOT_REACHED */
5741
Py_CLEAR(numbers); /* GCOV_NOT_REACHED */
5742
Py_CLEAR(Number); /* GCOV_NOT_REACHED */
5743
Py_CLEAR(Rational); /* GCOV_NOT_REACHED */
5744
Py_CLEAR(collections); /* GCOV_NOT_REACHED */
5745
Py_CLEAR(MutableMapping); /* GCOV_NOT_REACHED */
5746
Py_CLEAR(SignalTuple); /* GCOV_NOT_REACHED */
5747
Py_CLEAR(DecimalTuple); /* GCOV_NOT_REACHED */
5748
#ifdef WITHOUT_THREADS
5749
Py_CLEAR(module_context); /* GCOV_NOT_REACHED */
5751
Py_CLEAR(default_context_template); /* GCOV_NOT_REACHED */
5752
Py_CLEAR(tls_context_key); /* GCOV_NOT_REACHED */
5754
Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */
5755
Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */
5756
Py_CLEAR(m); /* GCOV_NOT_REACHED */
5758
return NULL; /* GCOV_NOT_REACHED */