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