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