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