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