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