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