From c01448e7e60552357077fce41557740274d8ec42 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sat, 16 Aug 2025 05:31:42 +0300 Subject: [PATCH] gh-73487: Convert _decimal to use Argument Clinic (part 2) --- .../pycore_global_objects_fini_generated.h | 11 + Include/internal/pycore_global_strings.h | 11 + .../internal/pycore_runtime_init_generated.h | 11 + .../internal/pycore_unicodeobject_generated.h | 44 + Modules/_decimal/_decimal.c | 400 ++++-- Modules/_decimal/clinic/_decimal.c.h | 1172 +++++++++++++++-- Modules/_decimal/docstrings.h | 116 -- 7 files changed, 1487 insertions(+), 278 deletions(-) diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h index 6c8ce475c69842..8b8ba649453d32 100644 --- a/Include/internal/pycore_global_objects_fini_generated.h +++ b/Include/internal/pycore_global_objects_fini_generated.h @@ -566,6 +566,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(type_params)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(utf_8)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(CANCELLED)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(Emax)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(Emin)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(FINISHED)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(False)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(JSONDecodeError)); @@ -847,10 +849,12 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(callback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cancel)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(capath)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(capitals)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(category)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cb_type)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(certfile)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(check_same_thread)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(clamp)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(clear)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(close)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(closed)); @@ -890,6 +894,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(coro)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(count)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(covariant)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(ctx)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cwd)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(d_parameter_type)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(data)); @@ -971,6 +976,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fix_imports)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flags)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(flush)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fmtarg)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(fold)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(follow_symlinks)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(format)); @@ -1110,6 +1116,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(module_globals)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(modules)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(modulo)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(month)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(mro)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(msg)); @@ -1160,6 +1167,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(outgoing)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(outpath)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(overlapped)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(override)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(owner)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pages)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(parameter)); @@ -1178,6 +1186,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos1)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(pos2)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(posix)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(prec)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(preserve_exc)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(print_file_and_line)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(priority)); @@ -1284,6 +1293,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(template)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(term)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(text)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(third)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(threading)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(throw)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(time)); @@ -1298,6 +1308,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) { _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traceback)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(trailers)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(translate)); + _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(traps)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(true)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(truncate)); _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(twice)); diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h index 55e48214728153..f6c30ed0e19ce2 100644 --- a/Include/internal/pycore_global_strings.h +++ b/Include/internal/pycore_global_strings.h @@ -57,6 +57,8 @@ struct _Py_global_strings { struct { STRUCT_FOR_ID(CANCELLED) + STRUCT_FOR_ID(Emax) + STRUCT_FOR_ID(Emin) STRUCT_FOR_ID(FINISHED) STRUCT_FOR_ID(False) STRUCT_FOR_ID(JSONDecodeError) @@ -338,10 +340,12 @@ struct _Py_global_strings { STRUCT_FOR_ID(callback) STRUCT_FOR_ID(cancel) STRUCT_FOR_ID(capath) + STRUCT_FOR_ID(capitals) STRUCT_FOR_ID(category) STRUCT_FOR_ID(cb_type) STRUCT_FOR_ID(certfile) STRUCT_FOR_ID(check_same_thread) + STRUCT_FOR_ID(clamp) STRUCT_FOR_ID(clear) STRUCT_FOR_ID(close) STRUCT_FOR_ID(closed) @@ -381,6 +385,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(coro) STRUCT_FOR_ID(count) STRUCT_FOR_ID(covariant) + STRUCT_FOR_ID(ctx) STRUCT_FOR_ID(cwd) STRUCT_FOR_ID(d_parameter_type) STRUCT_FOR_ID(data) @@ -462,6 +467,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(fix_imports) STRUCT_FOR_ID(flags) STRUCT_FOR_ID(flush) + STRUCT_FOR_ID(fmtarg) STRUCT_FOR_ID(fold) STRUCT_FOR_ID(follow_symlinks) STRUCT_FOR_ID(format) @@ -601,6 +607,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(module) STRUCT_FOR_ID(module_globals) STRUCT_FOR_ID(modules) + STRUCT_FOR_ID(modulo) STRUCT_FOR_ID(month) STRUCT_FOR_ID(mro) STRUCT_FOR_ID(msg) @@ -651,6 +658,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(outgoing) STRUCT_FOR_ID(outpath) STRUCT_FOR_ID(overlapped) + STRUCT_FOR_ID(override) STRUCT_FOR_ID(owner) STRUCT_FOR_ID(pages) STRUCT_FOR_ID(parameter) @@ -669,6 +677,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(pos1) STRUCT_FOR_ID(pos2) STRUCT_FOR_ID(posix) + STRUCT_FOR_ID(prec) STRUCT_FOR_ID(preserve_exc) STRUCT_FOR_ID(print_file_and_line) STRUCT_FOR_ID(priority) @@ -775,6 +784,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(template) STRUCT_FOR_ID(term) STRUCT_FOR_ID(text) + STRUCT_FOR_ID(third) STRUCT_FOR_ID(threading) STRUCT_FOR_ID(throw) STRUCT_FOR_ID(time) @@ -789,6 +799,7 @@ struct _Py_global_strings { STRUCT_FOR_ID(traceback) STRUCT_FOR_ID(trailers) STRUCT_FOR_ID(translate) + STRUCT_FOR_ID(traps) STRUCT_FOR_ID(true) STRUCT_FOR_ID(truncate) STRUCT_FOR_ID(twice) diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h index ea188d4f2bf8ed..bd0c053fb940f8 100644 --- a/Include/internal/pycore_runtime_init_generated.h +++ b/Include/internal/pycore_runtime_init_generated.h @@ -564,6 +564,8 @@ extern "C" { #define _Py_str_identifiers_INIT { \ INIT_ID(CANCELLED), \ + INIT_ID(Emax), \ + INIT_ID(Emin), \ INIT_ID(FINISHED), \ INIT_ID(False), \ INIT_ID(JSONDecodeError), \ @@ -845,10 +847,12 @@ extern "C" { INIT_ID(callback), \ INIT_ID(cancel), \ INIT_ID(capath), \ + INIT_ID(capitals), \ INIT_ID(category), \ INIT_ID(cb_type), \ INIT_ID(certfile), \ INIT_ID(check_same_thread), \ + INIT_ID(clamp), \ INIT_ID(clear), \ INIT_ID(close), \ INIT_ID(closed), \ @@ -888,6 +892,7 @@ extern "C" { INIT_ID(coro), \ INIT_ID(count), \ INIT_ID(covariant), \ + INIT_ID(ctx), \ INIT_ID(cwd), \ INIT_ID(d_parameter_type), \ INIT_ID(data), \ @@ -969,6 +974,7 @@ extern "C" { INIT_ID(fix_imports), \ INIT_ID(flags), \ INIT_ID(flush), \ + INIT_ID(fmtarg), \ INIT_ID(fold), \ INIT_ID(follow_symlinks), \ INIT_ID(format), \ @@ -1108,6 +1114,7 @@ extern "C" { INIT_ID(module), \ INIT_ID(module_globals), \ INIT_ID(modules), \ + INIT_ID(modulo), \ INIT_ID(month), \ INIT_ID(mro), \ INIT_ID(msg), \ @@ -1158,6 +1165,7 @@ extern "C" { INIT_ID(outgoing), \ INIT_ID(outpath), \ INIT_ID(overlapped), \ + INIT_ID(override), \ INIT_ID(owner), \ INIT_ID(pages), \ INIT_ID(parameter), \ @@ -1176,6 +1184,7 @@ extern "C" { INIT_ID(pos1), \ INIT_ID(pos2), \ INIT_ID(posix), \ + INIT_ID(prec), \ INIT_ID(preserve_exc), \ INIT_ID(print_file_and_line), \ INIT_ID(priority), \ @@ -1282,6 +1291,7 @@ extern "C" { INIT_ID(template), \ INIT_ID(term), \ INIT_ID(text), \ + INIT_ID(third), \ INIT_ID(threading), \ INIT_ID(throw), \ INIT_ID(time), \ @@ -1296,6 +1306,7 @@ extern "C" { INIT_ID(traceback), \ INIT_ID(trailers), \ INIT_ID(translate), \ + INIT_ID(traps), \ INIT_ID(true), \ INIT_ID(truncate), \ INIT_ID(twice), \ diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h index 044fdafef246ed..6090e2fc7d298e 100644 --- a/Include/internal/pycore_unicodeobject_generated.h +++ b/Include/internal/pycore_unicodeobject_generated.h @@ -16,6 +16,14 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(Emax); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(Emin); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(FINISHED); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -1140,6 +1148,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(capitals); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(category); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -1156,6 +1168,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(clamp); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(clear); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -1312,6 +1328,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(ctx); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(cwd); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -1636,6 +1656,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(fmtarg); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(fold); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2192,6 +2216,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(modulo); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(month); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2392,6 +2420,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(override); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(owner); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2464,6 +2496,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(prec); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(preserve_exc); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2888,6 +2924,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(third); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(threading); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); @@ -2944,6 +2984,10 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) { _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); assert(PyUnicode_GET_LENGTH(string) != 1); + string = &_Py_ID(traps); + _PyUnicode_InternStatic(interp, &string); + assert(_PyUnicode_CheckConsistency(string, 1)); + assert(PyUnicode_GET_LENGTH(string) != 1); string = &_Py_ID(true); _PyUnicode_InternStatic(interp, &string); assert(_PyUnicode_CheckConsistency(string, 1)); diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 46cedf83df1f00..e0dc980634933d 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -63,8 +63,9 @@ /*[clinic input] module _decimal class _decimal.Decimal "PyObject *" "&dec_spec" +class _decimal.Context "PyObject *" "&ctx_spec" [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e0e1f68f1f413f5f]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8c3aa7cfde934d7b]*/ struct PyDecContextObject; struct DecCondMap; @@ -1566,17 +1567,27 @@ init_extended_context(PyObject *v) } /* Factory function for creating IEEE interchange format contexts */ + +/*[clinic input] +_decimal.Decimal.IEEEContext + + self as module: self + bits: Py_ssize_t + / + +Return a context, initialized as one of the IEEE interchange formats. + +The argument must be a multiple of 32 and less than +IEEE_CONTEXT_MAX_BITS. +[clinic start generated code]*/ + static PyObject * -ieee_context(PyObject *module, PyObject *v) +_decimal_Decimal_IEEEContext_impl(PyObject *module, Py_ssize_t bits) +/*[clinic end generated code: output=042b8664fd2830f7 input=32882ba8f6a2d230]*/ { PyObject *context; - mpd_ssize_t bits; mpd_context_t ctx; - bits = PyLong_AsSsize_t(v); - if (bits == -1 && PyErr_Occurred()) { - return NULL; - } if (bits <= 0 || bits > INT_MAX) { goto error; } @@ -1775,7 +1786,7 @@ current_context(decimal_state *modstate) /* Return a new reference to the current context */ static PyObject * -PyDec_GetCurrentContext(PyObject *self, PyObject *Py_UNUSED(dummy)) +PyDec_GetCurrentContext(PyObject *self) { PyObject *context; decimal_state *state = get_module_state(self); @@ -1871,7 +1882,7 @@ current_context(decimal_state *state) /* Return a new reference to the current context */ static PyObject * -PyDec_GetCurrentContext(PyObject *self, PyObject *Py_UNUSED(dummy)) +PyDec_GetCurrentContext(PyObject *self) { decimal_state *state = get_module_state(self); return current_context(state); @@ -1910,36 +1921,75 @@ PyDec_SetCurrentContext(PyObject *self, PyObject *v) } #endif +/*[clinic input] +_decimal.Decimal.getcontext + +Get the current default context. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_getcontext_impl(PyObject *self) +/*[clinic end generated code: output=7efa232c0136dbba input=2d641118d62b25d4]*/ +{ + return PyDec_GetCurrentContext(self); +} + +/*[clinic input] +_decimal.Decimal.setcontext + + context: object + / + +Set a new default context. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_setcontext(PyObject *self, PyObject *context) +/*[clinic end generated code: output=20e7a377da25e02f input=4a5f0e2f660ee0e5]*/ +{ + return PyDec_SetCurrentContext(self, context); +} + /* Context manager object for the 'with' statement. The manager * owns one reference to the global (outer) context and one * to the local (inner) context. */ + +/*[clinic input] +@text_signature "($module, /, ctx=None, **kwargs)" +_decimal.Decimal.localcontext + + self as m: self + ctx as local: object = None + * + prec: object = None + rounding: object = None + Emin: object = None + Emax: object = None + capitals: object = None + clamp: object = None + flags: object = None + traps: object = None + +Return a context manager for a copy of the supplied context. + +That will set the default context to a copy of ctx on entry to the +with-statement and restore the previous default context when exiting +the with-statement. If no context is specified, a copy of the current +default context is used. +[clinic start generated code]*/ + static PyObject * -ctxmanager_new(PyObject *m, PyObject *args, PyObject *kwds) +_decimal_Decimal_localcontext_impl(PyObject *m, PyObject *local, + PyObject *prec, PyObject *rounding, + PyObject *Emin, PyObject *Emax, + PyObject *capitals, PyObject *clamp, + PyObject *flags, PyObject *traps) +/*[clinic end generated code: output=21cc25fbed642f2f input=77906e599937a9b5]*/ { - static char *kwlist[] = { - "ctx", "prec", "rounding", - "Emin", "Emax", "capitals", - "clamp", "flags", "traps", - NULL - }; - PyObject *local = Py_None; PyObject *global; - PyObject *prec = Py_None; - PyObject *rounding = Py_None; - PyObject *Emin = Py_None; - PyObject *Emax = Py_None; - PyObject *capitals = Py_None; - PyObject *clamp = Py_None; - PyObject *flags = Py_None; - PyObject *traps = Py_None; - decimal_state *state = get_module_state(m); CURRENT_CONTEXT(state, global); - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOOOO", kwlist, &local, - &prec, &rounding, &Emin, &Emax, &capitals, &clamp, &flags, &traps)) { - return NULL; - } if (local == Py_None) { local = global; } @@ -3569,15 +3619,26 @@ pydec_format(PyObject *dec, PyObject *context, PyObject *fmt, decimal_state *sta } /* Formatted representation of a PyDecObject. */ + +/*[clinic input] +_decimal.Decimal.__format__ + + self as dec: self + fmtarg: object + override: object(c_default="NULL") = None + +Formats the Decimal according to fmtarg. +[clinic start generated code]*/ + static PyObject * -dec_format(PyObject *dec, PyObject *args) +_decimal_Decimal___format___impl(PyObject *dec, PyObject *fmtarg, + PyObject *override) +/*[clinic end generated code: output=4b3640b7f0c8b6a5 input=b4aa4aad37438070]*/ { PyObject *result = NULL; - PyObject *override = NULL; PyObject *dot = NULL; PyObject *sep = NULL; PyObject *grouping = NULL; - PyObject *fmtarg; PyObject *context; mpd_spec_t spec; char *fmt; @@ -3585,14 +3646,8 @@ dec_format(PyObject *dec, PyObject *args) uint32_t status = 0; int replace_fillchar = 0; Py_ssize_t size; - - decimal_state *state = get_module_state_by_def(Py_TYPE(dec)); CURRENT_CONTEXT(state, context); - if (!PyArg_ParseTuple(args, "O|O", &fmtarg, &override)) { - return NULL; - } - if (PyUnicode_Check(fmtarg)) { fmt = (char *)PyUnicode_AsUTF8AndSize(fmtarg, &size); if (fmt == NULL) { @@ -4303,17 +4358,10 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ /* Unary function with an optional context arg. */ #define Dec_UnaryFuncVA(MPDFUNC) \ static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ +dec_##MPDFUNC(PyObject *self, PyObject *context) \ { \ - static char *kwlist[] = {"context", NULL}; \ PyObject *result; \ - PyObject *context = Py_None; \ uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, \ - &context)) { \ - return NULL; \ - } \ decimal_state *state = \ get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ @@ -4407,19 +4455,11 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ /* Ternary function with an optional context arg. */ #define Dec_TernaryFuncVA(MPDFUNC) \ static PyObject * \ -dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds) \ +dec_##MPDFUNC(PyObject *self, PyObject *other, PyObject *third, PyObject *context) \ { \ - static char *kwlist[] = {"other", "third", "context", NULL}; \ - PyObject *other, *third; \ PyObject *a, *b, *c; \ PyObject *result; \ - PyObject *context = Py_None; \ uint32_t status = 0; \ - \ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, \ - &other, &third, &context)) { \ - return NULL; \ - } \ decimal_state *state = get_module_state_by_def(Py_TYPE(self)); \ CONTEXT_CHECK_VA(state, context); \ CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context); \ @@ -4577,6 +4617,127 @@ Dec_UnaryFuncVA(mpd_qnext_plus) Dec_UnaryFuncVA(mpd_qreduce) Dec_UnaryFuncVA(mpd_qsqrt) +/*[clinic input] +_decimal.Decimal.exp + + context: object = None + +Return the value of the (natural) exponential function e**x. + +The function always uses the ROUND_HALF_EVEN mode and the result is +correctly rounded. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_exp_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=c0833b6e9b8c836f input=274784af925e60c9]*/ +{ + return dec_mpd_qexp(self, context); +} + +/*[clinic input] +_decimal.Decimal.ln + + context: object = None + +Return the natural (base e) logarithm of the operand. + +The function always uses the ROUND_HALF_EVEN mode and the result is +correctly rounded. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_ln_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=5191f4ef739b04b0 input=f267b224238c56e2]*/ +{ + return dec_mpd_qln(self, context); +} + +/*[clinic input] +_decimal.Decimal.log10 + + context: object = None + +Return the base ten logarithm of the operand. + +The function always uses the ROUND_HALF_EVEN mode and the result is +correctly rounded. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_log10_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=d5da63df75900275 input=d941f9335dc693cb]*/ +{ + return dec_mpd_qlog10(self, context); +} + +/*[clinic input] +_decimal.Decimal.next_minus + + context: object = None + +Returns the largest representable number smaller than itself. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_next_minus_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=aacbd758399f883f input=75666c6dc3cc8da9]*/ +{ + return dec_mpd_qnext_minus(self, context); +} + +/*[clinic input] +_decimal.Decimal.next_plus + + context: object = None + +Returns the smallest representable number larger than itself. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_next_plus_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=f3a7029a213c553c input=adcccf3f94e8da3f]*/ +{ + return dec_mpd_qnext_plus(self, context); +} + +/*[clinic input] +_decimal.Decimal.normalize + + context: object = None + +Normalize the number by stripping trailing 0s + +This also change anything equal to 0 to 0e0. Used for producing +canonical values for members of an equivalence class. For example, +Decimal('32.100') and Decimal('0.321000e+2') both normalize to +the equivalent value Decimal('32.1'). +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_normalize_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=db2c8b3c8eccff36 input=8f0504baa4e8c7de]*/ +{ + return dec_mpd_qreduce(self, context); +} + +/*[clinic input] +_decimal.Decimal.sqrt + + context: object = None + +Return the square root of the argument to full precision. + +The result is correctly rounded using the ROUND_HALF_EVEN rounding mode. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_sqrt_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=420722a199dd9c2b input=16df570867daf0d6]*/ +{ + return dec_mpd_qsqrt(self, context); +} + /* Binary arithmetic functions, optional context arg */ Dec_BinaryFuncVA(mpd_qcompare) Dec_BinaryFuncVA(mpd_qcompare_signal) @@ -4590,6 +4751,30 @@ Dec_BinaryFuncVA(mpd_qrem_near) /* Ternary arithmetic functions, optional context arg */ Dec_TernaryFuncVA(mpd_qfma) +/*[clinic input] +_decimal.Decimal.fma + + other: object + third: object + context: object = None + +Fused multiply-add. + +Return self*other+third with no rounding of the intermediate product +self*other. + + >>> Decimal(2).fma(3, 5) + Decimal('11') +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_fma_impl(PyObject *self, PyObject *other, PyObject *third, + PyObject *context) +/*[clinic end generated code: output=74a82b984e227b69 input=48f9aec6f389227a]*/ +{ + return dec_mpd_qfma(self, other, third, context); +} + /* Boolean functions, no context arg */ Dec_BoolFunc(mpd_iscanonical) Dec_BoolFunc(mpd_isfinite) @@ -4754,6 +4939,40 @@ _decimal_Decimal_copy_negate_impl(PyObject *self) Dec_UnaryFuncVA(mpd_qinvert) Dec_UnaryFuncVA(mpd_qlogb) +/*[clinic input] +_decimal.Decimal.logical_invert + + context: object = None + +Return the digit-wise inversion of the (logical) operand. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_logical_invert_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=59beb9b1b51b9f34 input=063cc759635d249b]*/ +{ + return dec_mpd_qinvert(self, context); +} + +/*[clinic input] +_decimal.Decimal.logb + + context: object = None + +Return the adjusted exponent of the operand as a Decimal instance. + +If the operand is a zero, then Decimal('-Infinity') is returned and the +DivisionByZero condition is raised. If the operand is an infinity then +Decimal('Infinity') is returned. +[clinic start generated code]*/ + +static PyObject * +_decimal_Decimal_logb_impl(PyObject *self, PyObject *context) +/*[clinic end generated code: output=f278db20b47f301c input=1a0de8e49b101734]*/ +{ + return dec_mpd_qlogb(self, context); +} + /*[clinic input] _decimal.Decimal.number_class @@ -5311,16 +5530,16 @@ static PyGetSetDef dec_getsets [] = static PyMethodDef dec_methods [] = { /* Unary arithmetic functions, optional context arg */ - { "exp", _PyCFunction_CAST(dec_mpd_qexp), METH_VARARGS|METH_KEYWORDS, doc_exp }, - { "ln", _PyCFunction_CAST(dec_mpd_qln), METH_VARARGS|METH_KEYWORDS, doc_ln }, - { "log10", _PyCFunction_CAST(dec_mpd_qlog10), METH_VARARGS|METH_KEYWORDS, doc_log10 }, - { "next_minus", _PyCFunction_CAST(dec_mpd_qnext_minus), METH_VARARGS|METH_KEYWORDS, doc_next_minus }, - { "next_plus", _PyCFunction_CAST(dec_mpd_qnext_plus), METH_VARARGS|METH_KEYWORDS, doc_next_plus }, - { "normalize", _PyCFunction_CAST(dec_mpd_qreduce), METH_VARARGS|METH_KEYWORDS, doc_normalize }, + _DECIMAL_DECIMAL_EXP_METHODDEF + _DECIMAL_DECIMAL_LN_METHODDEF + _DECIMAL_DECIMAL_LOG10_METHODDEF + _DECIMAL_DECIMAL_NEXT_MINUS_METHODDEF + _DECIMAL_DECIMAL_NEXT_PLUS_METHODDEF + _DECIMAL_DECIMAL_NORMALIZE_METHODDEF _DECIMAL_DECIMAL_TO_INTEGRAL_METHODDEF _DECIMAL_DECIMAL_TO_INTEGRAL_EXACT_METHODDEF _DECIMAL_DECIMAL_TO_INTEGRAL_VALUE_METHODDEF - { "sqrt", _PyCFunction_CAST(dec_mpd_qsqrt), METH_VARARGS|METH_KEYWORDS, doc_sqrt }, + _DECIMAL_DECIMAL_SQRT_METHODDEF /* Binary arithmetic functions, optional context arg */ { "compare", _PyCFunction_CAST(dec_mpd_qcompare), METH_VARARGS|METH_KEYWORDS, doc_compare }, @@ -5334,7 +5553,7 @@ static PyMethodDef dec_methods [] = { "remainder_near", _PyCFunction_CAST(dec_mpd_qrem_near), METH_VARARGS|METH_KEYWORDS, doc_remainder_near }, /* Ternary arithmetic functions, optional context arg */ - { "fma", _PyCFunction_CAST(dec_mpd_qfma), METH_VARARGS|METH_KEYWORDS, doc_fma }, + _DECIMAL_DECIMAL_FMA_METHODDEF /* Boolean functions, no context arg */ { "is_canonical", dec_mpd_iscanonical, METH_NOARGS, doc_is_canonical }, @@ -5361,8 +5580,8 @@ static PyMethodDef dec_methods [] = _DECIMAL_DECIMAL_COPY_NEGATE_METHODDEF /* Unary functions, optional context arg */ - { "logb", _PyCFunction_CAST(dec_mpd_qlogb), METH_VARARGS|METH_KEYWORDS, doc_logb }, - { "logical_invert", _PyCFunction_CAST(dec_mpd_qinvert), METH_VARARGS|METH_KEYWORDS, doc_logical_invert }, + _DECIMAL_DECIMAL_LOGB_METHODDEF + _DECIMAL_DECIMAL_LOGICAL_INVERT_METHODDEF _DECIMAL_DECIMAL_NUMBER_CLASS_METHODDEF _DECIMAL_DECIMAL_TO_ENG_STRING_METHODDEF @@ -5389,7 +5608,7 @@ static PyMethodDef dec_methods [] = /* Special methods */ { "__copy__", dec_copy, METH_NOARGS, NULL }, { "__deepcopy__", dec_copy, METH_O, NULL }, - { "__format__", dec_format, METH_VARARGS, NULL }, + _DECIMAL_DECIMAL___FORMAT___METHODDEF { "__reduce__", dec_reduce, METH_NOARGS, NULL }, { "__round__", PyDec_Round, METH_VARARGS, NULL }, { "__ceil__", dec_ceil, METH_NOARGS, NULL }, @@ -5686,20 +5905,41 @@ ctx_mpd_qdivmod(PyObject *context, PyObject *args) } /* Binary or ternary arithmetic functions */ + +/*[clinic input] +_decimal.Context.power + + self as context: self + a as base: object + b as exp: object + modulo as mod: object = None + +Compute a**b. + +If 'a' is negative, then 'b' must be integral. The result will be +inexact unless 'a' is integral and the result is finite and can be +expressed exactly in 'precision' digits. In the Python version the +result is always correctly rounded, in the C version the result is +almost always correctly rounded. + +If modulo is given, compute (a**b) % modulo. The following +restrictions hold: + + * all three arguments must be integral + * 'b' must be nonnegative + * at least one of 'a' or 'b' must be nonzero + * modulo must be nonzero and less than 10**prec in absolute value +[clinic start generated code]*/ + static PyObject * -ctx_mpd_qpow(PyObject *context, PyObject *args, PyObject *kwds) +_decimal_Context_power_impl(PyObject *context, PyObject *base, PyObject *exp, + PyObject *mod) +/*[clinic end generated code: output=d2e68694ec545245 input=e9aef844813de243]*/ { - static char *kwlist[] = {"a", "b", "modulo", NULL}; - PyObject *base, *exp, *mod = Py_None; PyObject *a, *b, *c = NULL; PyObject *result; uint32_t status = 0; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O", kwlist, - &base, &exp, &mod)) { - return NULL; - } - CONVERT_BINOP_RAISE(&a, &b, base, exp, context); if (mod != Py_None) { @@ -6020,7 +6260,7 @@ static PyMethodDef context_methods [] = { "subtract", ctx_mpd_qsub, METH_VARARGS, doc_ctx_subtract }, /* Binary or ternary arithmetic functions */ - { "power", _PyCFunction_CAST(ctx_mpd_qpow), METH_VARARGS|METH_KEYWORDS, doc_ctx_power }, + _DECIMAL_CONTEXT_POWER_METHODDEF /* Ternary arithmetic functions */ { "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma }, @@ -6117,10 +6357,10 @@ static PyType_Spec context_spec = { static PyMethodDef _decimal_methods [] = { - { "getcontext", PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, - { "setcontext", PyDec_SetCurrentContext, METH_O, doc_setcontext}, - { "localcontext", _PyCFunction_CAST(ctxmanager_new), METH_VARARGS|METH_KEYWORDS, doc_localcontext}, - { "IEEEContext", ieee_context, METH_O, doc_ieee_context}, + _DECIMAL_DECIMAL_GETCONTEXT_METHODDEF + _DECIMAL_DECIMAL_SETCONTEXT_METHODDEF + _DECIMAL_DECIMAL_LOCALCONTEXT_METHODDEF + _DECIMAL_DECIMAL_IEEECONTEXT_METHODDEF { NULL, NULL, 1, NULL } }; diff --git a/Modules/_decimal/clinic/_decimal.c.h b/Modules/_decimal/clinic/_decimal.c.h index 441515edbf60f6..47ee4417d89a3e 100644 --- a/Modules/_decimal/clinic/_decimal.c.h +++ b/Modules/_decimal/clinic/_decimal.c.h @@ -6,8 +6,207 @@ preserve # include "pycore_gc.h" // PyGC_Head # include "pycore_runtime.h" // _Py_ID() #endif +#include "pycore_abstract.h" // _PyNumber_Index() #include "pycore_modsupport.h" // _PyArg_UnpackKeywords() +PyDoc_STRVAR(_decimal_Decimal_IEEEContext__doc__, +"IEEEContext($self, bits, /)\n" +"--\n" +"\n" +"Return a context, initialized as one of the IEEE interchange formats.\n" +"\n" +"The argument must be a multiple of 32 and less than\n" +"IEEE_CONTEXT_MAX_BITS."); + +#define _DECIMAL_DECIMAL_IEEECONTEXT_METHODDEF \ + {"IEEEContext", (PyCFunction)_decimal_Decimal_IEEEContext, METH_O, _decimal_Decimal_IEEEContext__doc__}, + +static PyObject * +_decimal_Decimal_IEEEContext_impl(PyObject *module, Py_ssize_t bits); + +static PyObject * +_decimal_Decimal_IEEEContext(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + Py_ssize_t bits; + + { + Py_ssize_t ival = -1; + PyObject *iobj = _PyNumber_Index(arg); + if (iobj != NULL) { + ival = PyLong_AsSsize_t(iobj); + Py_DECREF(iobj); + } + if (ival == -1 && PyErr_Occurred()) { + goto exit; + } + bits = ival; + } + return_value = _decimal_Decimal_IEEEContext_impl(module, bits); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_getcontext__doc__, +"getcontext($self, /)\n" +"--\n" +"\n" +"Get the current default context."); + +#define _DECIMAL_DECIMAL_GETCONTEXT_METHODDEF \ + {"getcontext", (PyCFunction)_decimal_Decimal_getcontext, METH_NOARGS, _decimal_Decimal_getcontext__doc__}, + +static PyObject * +_decimal_Decimal_getcontext_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_getcontext(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_getcontext_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_setcontext__doc__, +"setcontext($self, context, /)\n" +"--\n" +"\n" +"Set a new default context."); + +#define _DECIMAL_DECIMAL_SETCONTEXT_METHODDEF \ + {"setcontext", (PyCFunction)_decimal_Decimal_setcontext, METH_O, _decimal_Decimal_setcontext__doc__}, + +PyDoc_STRVAR(_decimal_Decimal_localcontext__doc__, +"localcontext($module, /, ctx=None, **kwargs)\n" +"--\n" +"\n" +"Return a context manager for a copy of the supplied context.\n" +"\n" +"That will set the default context to a copy of ctx on entry to the\n" +"with-statement and restore the previous default context when exiting\n" +"the with-statement. If no context is specified, a copy of the current\n" +"default context is used."); + +#define _DECIMAL_DECIMAL_LOCALCONTEXT_METHODDEF \ + {"localcontext", _PyCFunction_CAST(_decimal_Decimal_localcontext), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_localcontext__doc__}, + +static PyObject * +_decimal_Decimal_localcontext_impl(PyObject *m, PyObject *local, + PyObject *prec, PyObject *rounding, + PyObject *Emin, PyObject *Emax, + PyObject *capitals, PyObject *clamp, + PyObject *flags, PyObject *traps); + +static PyObject * +_decimal_Decimal_localcontext(PyObject *m, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 9 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(ctx), &_Py_ID(prec), &_Py_ID(rounding), &_Py_ID(Emin), &_Py_ID(Emax), &_Py_ID(capitals), &_Py_ID(clamp), &_Py_ID(flags), &_Py_ID(traps), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"ctx", "prec", "rounding", "Emin", "Emax", "capitals", "clamp", "flags", "traps", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "localcontext", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[9]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *local = Py_None; + PyObject *prec = Py_None; + PyObject *rounding = Py_None; + PyObject *Emin = Py_None; + PyObject *Emax = Py_None; + PyObject *capitals = Py_None; + PyObject *clamp = Py_None; + PyObject *flags = Py_None; + PyObject *traps = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + local = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } +skip_optional_pos: + if (!noptargs) { + goto skip_optional_kwonly; + } + if (args[1]) { + prec = args[1]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[2]) { + rounding = args[2]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[3]) { + Emin = args[3]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[4]) { + Emax = args[4]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[5]) { + capitals = args[5]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[6]) { + clamp = args[6]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + if (args[7]) { + flags = args[7]; + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + traps = args[8]; +skip_optional_kwonly: + return_value = _decimal_Decimal_localcontext_impl(m, local, prec, rounding, Emin, Emax, capitals, clamp, flags, traps); + +exit: + return return_value; +} + PyDoc_STRVAR(_decimal_Decimal_from_float__doc__, "from_float($type, f, /)\n" "--\n" @@ -71,6 +270,72 @@ _decimal_Decimal_from_number(PyObject *type, PyObject *number) return return_value; } +PyDoc_STRVAR(_decimal_Decimal___format____doc__, +"__format__($self, /, fmtarg, override=None)\n" +"--\n" +"\n" +"Formats the Decimal according to fmtarg."); + +#define _DECIMAL_DECIMAL___FORMAT___METHODDEF \ + {"__format__", _PyCFunction_CAST(_decimal_Decimal___format__), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal___format____doc__}, + +static PyObject * +_decimal_Decimal___format___impl(PyObject *dec, PyObject *fmtarg, + PyObject *override); + +static PyObject * +_decimal_Decimal___format__(PyObject *dec, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(fmtarg), &_Py_ID(override), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"fmtarg", "override", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "__format__", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1; + PyObject *fmtarg; + PyObject *override = NULL; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + fmtarg = args[0]; + if (!noptargs) { + goto skip_optional_pos; + } + override = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal___format___impl(dec, fmtarg, override); + +exit: + return return_value; +} + PyDoc_STRVAR(_decimal_Decimal_as_integer_ratio__doc__, "as_integer_ratio($self, /)\n" "--\n" @@ -142,54 +407,612 @@ _decimal_Decimal_to_integral_value(PyObject *self, PyObject *const *args, Py_ssi #undef KWTUPLE PyObject *argsbuf[2]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *rounding = Py_None; + PyObject *rounding = Py_None; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + rounding = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_to_integral_value_impl(self, rounding, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_to_integral__doc__, +"to_integral($self, /, rounding=None, context=None)\n" +"--\n" +"\n" +"Identical to the to_integral_value() method.\n" +"\n" +"The to_integral() name has been kept for compatibility with older\n" +"versions."); + +#define _DECIMAL_DECIMAL_TO_INTEGRAL_METHODDEF \ + {"to_integral", _PyCFunction_CAST(_decimal_Decimal_to_integral), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral__doc__}, + +static PyObject * +_decimal_Decimal_to_integral_impl(PyObject *self, PyObject *rounding, + PyObject *context); + +static PyObject * +_decimal_Decimal_to_integral(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(rounding), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"rounding", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "to_integral", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *rounding = Py_None; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + rounding = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_to_integral_impl(self, rounding, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_to_integral_exact__doc__, +"to_integral_exact($self, /, rounding=None, context=None)\n" +"--\n" +"\n" +"Round to the nearest integer.\n" +"\n" +"Decimal.to_integral_exact() signals Inexact or Rounded as appropriate\n" +"if rounding occurs. The rounding mode is determined by the rounding\n" +"parameter if given, else by the given context. If neither parameter is\n" +"given, then the rounding mode of the current default context is used."); + +#define _DECIMAL_DECIMAL_TO_INTEGRAL_EXACT_METHODDEF \ + {"to_integral_exact", _PyCFunction_CAST(_decimal_Decimal_to_integral_exact), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral_exact__doc__}, + +static PyObject * +_decimal_Decimal_to_integral_exact_impl(PyObject *self, PyObject *rounding, + PyObject *context); + +static PyObject * +_decimal_Decimal_to_integral_exact(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 2 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(rounding), &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"rounding", "context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "to_integral_exact", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[2]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *rounding = Py_None; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + if (args[0]) { + rounding = args[0]; + if (!--noptargs) { + goto skip_optional_pos; + } + } + context = args[1]; +skip_optional_pos: + return_value = _decimal_Decimal_to_integral_exact_impl(self, rounding, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_as_tuple__doc__, +"as_tuple($self, /)\n" +"--\n" +"\n" +"Return a tuple representation of the number."); + +#define _DECIMAL_DECIMAL_AS_TUPLE_METHODDEF \ + {"as_tuple", (PyCFunction)_decimal_Decimal_as_tuple, METH_NOARGS, _decimal_Decimal_as_tuple__doc__}, + +static PyObject * +_decimal_Decimal_as_tuple_impl(PyObject *self); + +static PyObject * +_decimal_Decimal_as_tuple(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + return _decimal_Decimal_as_tuple_impl(self); +} + +PyDoc_STRVAR(_decimal_Decimal_exp__doc__, +"exp($self, /, context=None)\n" +"--\n" +"\n" +"Return the value of the (natural) exponential function e**x.\n" +"\n" +"The function always uses the ROUND_HALF_EVEN mode and the result is\n" +"correctly rounded."); + +#define _DECIMAL_DECIMAL_EXP_METHODDEF \ + {"exp", _PyCFunction_CAST(_decimal_Decimal_exp), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_exp__doc__}, + +static PyObject * +_decimal_Decimal_exp_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_exp(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "exp", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_exp_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_ln__doc__, +"ln($self, /, context=None)\n" +"--\n" +"\n" +"Return the natural (base e) logarithm of the operand.\n" +"\n" +"The function always uses the ROUND_HALF_EVEN mode and the result is\n" +"correctly rounded."); + +#define _DECIMAL_DECIMAL_LN_METHODDEF \ + {"ln", _PyCFunction_CAST(_decimal_Decimal_ln), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_ln__doc__}, + +static PyObject * +_decimal_Decimal_ln_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_ln(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "ln", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_ln_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_log10__doc__, +"log10($self, /, context=None)\n" +"--\n" +"\n" +"Return the base ten logarithm of the operand.\n" +"\n" +"The function always uses the ROUND_HALF_EVEN mode and the result is\n" +"correctly rounded."); + +#define _DECIMAL_DECIMAL_LOG10_METHODDEF \ + {"log10", _PyCFunction_CAST(_decimal_Decimal_log10), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_log10__doc__}, + +static PyObject * +_decimal_Decimal_log10_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_log10(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "log10", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_log10_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_next_minus__doc__, +"next_minus($self, /, context=None)\n" +"--\n" +"\n" +"Returns the largest representable number smaller than itself."); + +#define _DECIMAL_DECIMAL_NEXT_MINUS_METHODDEF \ + {"next_minus", _PyCFunction_CAST(_decimal_Decimal_next_minus), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_minus__doc__}, + +static PyObject * +_decimal_Decimal_next_minus_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_next_minus(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "next_minus", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_next_minus_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_next_plus__doc__, +"next_plus($self, /, context=None)\n" +"--\n" +"\n" +"Returns the smallest representable number larger than itself."); + +#define _DECIMAL_DECIMAL_NEXT_PLUS_METHODDEF \ + {"next_plus", _PyCFunction_CAST(_decimal_Decimal_next_plus), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_plus__doc__}, + +static PyObject * +_decimal_Decimal_next_plus_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_next_plus(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "next_plus", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_next_plus_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_normalize__doc__, +"normalize($self, /, context=None)\n" +"--\n" +"\n" +"Normalize the number by stripping trailing 0s\n" +"\n" +"This also change anything equal to 0 to 0e0. Used for producing\n" +"canonical values for members of an equivalence class. For example,\n" +"Decimal(\'32.100\') and Decimal(\'0.321000e+2\') both normalize to\n" +"the equivalent value Decimal(\'32.1\')."); + +#define _DECIMAL_DECIMAL_NORMALIZE_METHODDEF \ + {"normalize", _PyCFunction_CAST(_decimal_Decimal_normalize), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_normalize__doc__}, + +static PyObject * +_decimal_Decimal_normalize_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "normalize", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; PyObject *context = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, - /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); if (!args) { goto exit; } if (!noptargs) { goto skip_optional_pos; } - if (args[0]) { - rounding = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - context = args[1]; + context = args[0]; skip_optional_pos: - return_value = _decimal_Decimal_to_integral_value_impl(self, rounding, context); + return_value = _decimal_Decimal_normalize_impl(self, context); exit: return return_value; } -PyDoc_STRVAR(_decimal_Decimal_to_integral__doc__, -"to_integral($self, /, rounding=None, context=None)\n" +PyDoc_STRVAR(_decimal_Decimal_sqrt__doc__, +"sqrt($self, /, context=None)\n" "--\n" "\n" -"Identical to the to_integral_value() method.\n" +"Return the square root of the argument to full precision.\n" "\n" -"The to_integral() name has been kept for compatibility with older\n" -"versions."); +"The result is correctly rounded using the ROUND_HALF_EVEN rounding mode."); -#define _DECIMAL_DECIMAL_TO_INTEGRAL_METHODDEF \ - {"to_integral", _PyCFunction_CAST(_decimal_Decimal_to_integral), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral__doc__}, +#define _DECIMAL_DECIMAL_SQRT_METHODDEF \ + {"sqrt", _PyCFunction_CAST(_decimal_Decimal_sqrt), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_sqrt__doc__}, static PyObject * -_decimal_Decimal_to_integral_impl(PyObject *self, PyObject *rounding, - PyObject *context); +_decimal_Decimal_sqrt_impl(PyObject *self, PyObject *context); static PyObject * -_decimal_Decimal_to_integral(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_decimal_Decimal_sqrt(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 2 + #define NUM_KEYWORDS 1 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -198,7 +1021,7 @@ _decimal_Decimal_to_integral(PyObject *self, PyObject *const *args, Py_ssize_t n } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_hash = -1, - .ob_item = { &_Py_ID(rounding), &_Py_ID(context), }, + .ob_item = { &_Py_ID(context), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -207,65 +1030,59 @@ _decimal_Decimal_to_integral(PyObject *self, PyObject *const *args, Py_ssize_t n # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"rounding", "context", NULL}; + static const char * const _keywords[] = {"context", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .fname = "to_integral", + .fname = "sqrt", .kwtuple = KWTUPLE, }; #undef KWTUPLE - PyObject *argsbuf[2]; + PyObject *argsbuf[1]; Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *rounding = Py_None; PyObject *context = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, - /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); if (!args) { goto exit; } if (!noptargs) { goto skip_optional_pos; } - if (args[0]) { - rounding = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - context = args[1]; + context = args[0]; skip_optional_pos: - return_value = _decimal_Decimal_to_integral_impl(self, rounding, context); + return_value = _decimal_Decimal_sqrt_impl(self, context); exit: return return_value; } -PyDoc_STRVAR(_decimal_Decimal_to_integral_exact__doc__, -"to_integral_exact($self, /, rounding=None, context=None)\n" +PyDoc_STRVAR(_decimal_Decimal_fma__doc__, +"fma($self, /, other, third, context=None)\n" "--\n" "\n" -"Round to the nearest integer.\n" +"Fused multiply-add.\n" "\n" -"Decimal.to_integral_exact() signals Inexact or Rounded as appropriate\n" -"if rounding occurs. The rounding mode is determined by the rounding\n" -"parameter if given, else by the given context. If neither parameter is\n" -"given, then the rounding mode of the current default context is used."); +"Return self*other+third with no rounding of the intermediate product\n" +"self*other.\n" +"\n" +" >>> Decimal(2).fma(3, 5)\n" +" Decimal(\'11\')"); -#define _DECIMAL_DECIMAL_TO_INTEGRAL_EXACT_METHODDEF \ - {"to_integral_exact", _PyCFunction_CAST(_decimal_Decimal_to_integral_exact), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral_exact__doc__}, +#define _DECIMAL_DECIMAL_FMA_METHODDEF \ + {"fma", _PyCFunction_CAST(_decimal_Decimal_fma), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_fma__doc__}, static PyObject * -_decimal_Decimal_to_integral_exact_impl(PyObject *self, PyObject *rounding, - PyObject *context); +_decimal_Decimal_fma_impl(PyObject *self, PyObject *other, PyObject *third, + PyObject *context); static PyObject * -_decimal_Decimal_to_integral_exact(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +_decimal_Decimal_fma(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { PyObject *return_value = NULL; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 2 + #define NUM_KEYWORDS 3 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -274,7 +1091,7 @@ _decimal_Decimal_to_integral_exact(PyObject *self, PyObject *const *args, Py_ssi } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_hash = -1, - .ob_item = { &_Py_ID(rounding), &_Py_ID(context), }, + .ob_item = { &_Py_ID(other), &_Py_ID(third), &_Py_ID(context), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -283,58 +1100,37 @@ _decimal_Decimal_to_integral_exact(PyObject *self, PyObject *const *args, Py_ssi # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"rounding", "context", NULL}; + static const char * const _keywords[] = {"other", "third", "context", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, - .fname = "to_integral_exact", + .fname = "fma", .kwtuple = KWTUPLE, }; #undef KWTUPLE - PyObject *argsbuf[2]; - Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; - PyObject *rounding = Py_None; + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *other; + PyObject *third; PyObject *context = Py_None; args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, - /*minpos*/ 0, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); if (!args) { goto exit; } + other = args[0]; + third = args[1]; if (!noptargs) { goto skip_optional_pos; } - if (args[0]) { - rounding = args[0]; - if (!--noptargs) { - goto skip_optional_pos; - } - } - context = args[1]; + context = args[2]; skip_optional_pos: - return_value = _decimal_Decimal_to_integral_exact_impl(self, rounding, context); + return_value = _decimal_Decimal_fma_impl(self, other, third, context); exit: return return_value; } -PyDoc_STRVAR(_decimal_Decimal_as_tuple__doc__, -"as_tuple($self, /)\n" -"--\n" -"\n" -"Return a tuple representation of the number."); - -#define _DECIMAL_DECIMAL_AS_TUPLE_METHODDEF \ - {"as_tuple", (PyCFunction)_decimal_Decimal_as_tuple, METH_NOARGS, _decimal_Decimal_as_tuple__doc__}, - -static PyObject * -_decimal_Decimal_as_tuple_impl(PyObject *self); - -static PyObject * -_decimal_Decimal_as_tuple(PyObject *self, PyObject *Py_UNUSED(ignored)) -{ - return _decimal_Decimal_as_tuple_impl(self); -} - PyDoc_STRVAR(_decimal_Decimal_adjusted__doc__, "adjusted($self, /)\n" "--\n" @@ -455,6 +1251,136 @@ _decimal_Decimal_copy_negate(PyObject *self, PyObject *Py_UNUSED(ignored)) return _decimal_Decimal_copy_negate_impl(self); } +PyDoc_STRVAR(_decimal_Decimal_logical_invert__doc__, +"logical_invert($self, /, context=None)\n" +"--\n" +"\n" +"Return the digit-wise inversion of the (logical) operand."); + +#define _DECIMAL_DECIMAL_LOGICAL_INVERT_METHODDEF \ + {"logical_invert", _PyCFunction_CAST(_decimal_Decimal_logical_invert), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_invert__doc__}, + +static PyObject * +_decimal_Decimal_logical_invert_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_logical_invert(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "logical_invert", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_logical_invert_impl(self, context); + +exit: + return return_value; +} + +PyDoc_STRVAR(_decimal_Decimal_logb__doc__, +"logb($self, /, context=None)\n" +"--\n" +"\n" +"Return the adjusted exponent of the operand as a Decimal instance.\n" +"\n" +"If the operand is a zero, then Decimal(\'-Infinity\') is returned and the\n" +"DivisionByZero condition is raised. If the operand is an infinity then\n" +"Decimal(\'Infinity\') is returned."); + +#define _DECIMAL_DECIMAL_LOGB_METHODDEF \ + {"logb", _PyCFunction_CAST(_decimal_Decimal_logb), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logb__doc__}, + +static PyObject * +_decimal_Decimal_logb_impl(PyObject *self, PyObject *context); + +static PyObject * +_decimal_Decimal_logb(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 1 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { &_Py_ID(context), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"context", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "logb", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[1]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0; + PyObject *context = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + if (!noptargs) { + goto skip_optional_pos; + } + context = args[0]; +skip_optional_pos: + return_value = _decimal_Decimal_logb_impl(self, context); + +exit: + return return_value; +} + PyDoc_STRVAR(_decimal_Decimal_number_class__doc__, "number_class($self, /, context=None)\n" "--\n" @@ -846,4 +1772,86 @@ _decimal_Decimal_quantize(PyObject *self, PyObject *const *args, Py_ssize_t narg exit: return return_value; } -/*[clinic end generated code: output=f33166d1bf53e613 input=a9049054013a1b77]*/ + +PyDoc_STRVAR(_decimal_Context_power__doc__, +"power($self, /, a, b, modulo=None)\n" +"--\n" +"\n" +"Compute a**b.\n" +"\n" +"If \'a\' is negative, then \'b\' must be integral. The result will be\n" +"inexact unless \'a\' is integral and the result is finite and can be\n" +"expressed exactly in \'precision\' digits. In the Python version the\n" +"result is always correctly rounded, in the C version the result is\n" +"almost always correctly rounded.\n" +"\n" +"If modulo is given, compute (a**b) % modulo. The following\n" +"restrictions hold:\n" +"\n" +" * all three arguments must be integral\n" +" * \'b\' must be nonnegative\n" +" * at least one of \'a\' or \'b\' must be nonzero\n" +" * modulo must be nonzero and less than 10**prec in absolute value"); + +#define _DECIMAL_CONTEXT_POWER_METHODDEF \ + {"power", _PyCFunction_CAST(_decimal_Context_power), METH_FASTCALL|METH_KEYWORDS, _decimal_Context_power__doc__}, + +static PyObject * +_decimal_Context_power_impl(PyObject *context, PyObject *base, PyObject *exp, + PyObject *mod); + +static PyObject * +_decimal_Context_power(PyObject *context, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) +{ + PyObject *return_value = NULL; + #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) + + #define NUM_KEYWORDS 3 + static struct { + PyGC_Head _this_is_not_used; + PyObject_VAR_HEAD + Py_hash_t ob_hash; + PyObject *ob_item[NUM_KEYWORDS]; + } _kwtuple = { + .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) + .ob_hash = -1, + .ob_item = { _Py_LATIN1_CHR('a'), _Py_LATIN1_CHR('b'), &_Py_ID(modulo), }, + }; + #undef NUM_KEYWORDS + #define KWTUPLE (&_kwtuple.ob_base.ob_base) + + #else // !Py_BUILD_CORE + # define KWTUPLE NULL + #endif // !Py_BUILD_CORE + + static const char * const _keywords[] = {"a", "b", "modulo", NULL}; + static _PyArg_Parser _parser = { + .keywords = _keywords, + .fname = "power", + .kwtuple = KWTUPLE, + }; + #undef KWTUPLE + PyObject *argsbuf[3]; + Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2; + PyObject *base; + PyObject *exp; + PyObject *mod = Py_None; + + args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, + /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf); + if (!args) { + goto exit; + } + base = args[0]; + exp = args[1]; + if (!noptargs) { + goto skip_optional_pos; + } + mod = args[2]; +skip_optional_pos: + return_value = _decimal_Context_power_impl(context, base, exp, mod); + +exit: + return return_value; +} +/*[clinic end generated code: output=f6842a3ef7af9757 input=a9049054013a1b77]*/ diff --git a/Modules/_decimal/docstrings.h b/Modules/_decimal/docstrings.h index bd1c1d5295d717..248cb47fb5136e 100644 --- a/Modules/_decimal/docstrings.h +++ b/Modules/_decimal/docstrings.h @@ -19,32 +19,6 @@ PyDoc_STRVAR(doc__decimal, "C decimal arithmetic module"); -PyDoc_STRVAR(doc_getcontext, -"getcontext($module, /)\n--\n\n\ -Get the current default context.\n\ -\n"); - -PyDoc_STRVAR(doc_setcontext, -"setcontext($module, context, /)\n--\n\n\ -Set a new default context.\n\ -\n"); - -PyDoc_STRVAR(doc_localcontext, -"localcontext($module, /, ctx=None, **kwargs)\n--\n\n\ -Return a context manager that will set the default context to a copy of ctx\n\ -on entry to the with-statement and restore the previous default context when\n\ -exiting the with-statement. If no context is specified, a copy of the current\n\ -default context is used.\n\ -\n"); - -PyDoc_STRVAR(doc_ieee_context, -"IEEEContext($module, bits, /)\n--\n\n\ -Return a context object initialized to the proper values for one of the\n\ -IEEE interchange formats. The argument must be a multiple of 32 and less\n\ -than IEEE_CONTEXT_MAX_BITS.\n\ -\n"); - - /******************************************************************************/ /* Decimal Object and Methods */ /******************************************************************************/ @@ -106,23 +80,6 @@ and no rounding is performed. As an exception, the C version may raise\n\ InvalidOperation if the second operand cannot be converted exactly.\n\ \n"); -PyDoc_STRVAR(doc_exp, -"exp($self, /, context=None)\n--\n\n\ -Return the value of the (natural) exponential function e**x at the given\n\ -number. The function always uses the ROUND_HALF_EVEN mode and the result\n\ -is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_fma, -"fma($self, /, other, third, context=None)\n--\n\n\ -Fused multiply-add. Return self*other+third with no rounding of the\n\ -intermediate product self*other.\n\ -\n\ - >>> Decimal(2).fma(3, 5)\n\ - Decimal('11')\n\ -\n\ -\n"); - PyDoc_STRVAR(doc_is_canonical, "is_canonical($self, /)\n--\n\n\ Return True if the argument is canonical and False otherwise. Currently,\n\ @@ -184,36 +141,11 @@ Return True if the argument is a (positive or negative) zero and False\n\ otherwise.\n\ \n"); -PyDoc_STRVAR(doc_ln, -"ln($self, /, context=None)\n--\n\n\ -Return the natural (base e) logarithm of the operand. The function always\n\ -uses the ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_log10, -"log10($self, /, context=None)\n--\n\n\ -Return the base ten logarithm of the operand. The function always uses the\n\ -ROUND_HALF_EVEN mode and the result is correctly rounded.\n\ -\n"); - -PyDoc_STRVAR(doc_logb, -"logb($self, /, context=None)\n--\n\n\ -For a non-zero number, return the adjusted exponent of the operand as a\n\ -Decimal instance. If the operand is a zero, then Decimal('-Infinity') is\n\ -returned and the DivisionByZero condition is raised. If the operand is\n\ -an infinity then Decimal('Infinity') is returned.\n\ -\n"); - PyDoc_STRVAR(doc_logical_and, "logical_and($self, /, other, context=None)\n--\n\n\ Return the digit-wise 'and' of the two (logical) operands.\n\ \n"); -PyDoc_STRVAR(doc_logical_invert, -"logical_invert($self, /, context=None)\n--\n\n\ -Return the digit-wise inversion of the (logical) operand.\n\ -\n"); - PyDoc_STRVAR(doc_logical_or, "logical_or($self, /, other, context=None)\n--\n\n\ Return the digit-wise 'or' of the two (logical) operands.\n\ @@ -248,20 +180,6 @@ Similar to the min() method, but the comparison is done using the absolute\n\ values of the operands.\n\ \n"); -PyDoc_STRVAR(doc_next_minus, -"next_minus($self, /, context=None)\n--\n\n\ -Return the largest number representable in the given context (or in the\n\ -current default context if no context is given) that is smaller than the\n\ -given operand.\n\ -\n"); - -PyDoc_STRVAR(doc_next_plus, -"next_plus($self, /, context=None)\n--\n\n\ -Return the smallest number representable in the given context (or in the\n\ -current default context if no context is given) that is larger than the\n\ -given operand.\n\ -\n"); - PyDoc_STRVAR(doc_next_toward, "next_toward($self, /, other, context=None)\n--\n\n\ If the two operands are unequal, return the number closest to the first\n\ @@ -270,15 +188,6 @@ numerically equal, return a copy of the first operand with the sign set\n\ to be the same as the sign of the second operand.\n\ \n"); -PyDoc_STRVAR(doc_normalize, -"normalize($self, /, context=None)\n--\n\n\ -Normalize the number by stripping the rightmost trailing zeros and\n\ -converting any result equal to Decimal('0') to Decimal('0e0'). Used\n\ -for producing canonical values for members of an equivalence class.\n\ -For example, Decimal('32.100') and Decimal('0.321000e+2') both normalize\n\ -to the equivalent value Decimal('32.1').\n\ -\n"); - PyDoc_STRVAR(doc_remainder_near, "remainder_near($self, /, other, context=None)\n--\n\n\ Return the remainder from dividing self by other. This differs from\n\ @@ -320,13 +229,6 @@ right. Digits shifted into the coefficient are zeros. The sign and exponent\n\ of the first operand are unchanged.\n\ \n"); -PyDoc_STRVAR(doc_sqrt, -"sqrt($self, /, context=None)\n--\n\n\ -Return the square root of the argument to full precision. The result is\n\ -correctly rounded using the ROUND_HALF_EVEN rounding mode.\n\ -\n"); - - /******************************************************************************/ /* Context Object and Methods */ /******************************************************************************/ @@ -619,24 +521,6 @@ Plus corresponds to the unary prefix plus operator in Python, but applies\n\ the context to the result.\n\ \n"); -PyDoc_STRVAR(doc_ctx_power, -"power($self, /, a, b, modulo=None)\n--\n\n\ -Compute a**b. If 'a' is negative, then 'b' must be integral. The result\n\ -will be inexact unless 'a' is integral and the result is finite and can\n\ -be expressed exactly in 'precision' digits. In the Python version the\n\ -result is always correctly rounded, in the C version the result is almost\n\ -always correctly rounded.\n\ -\n\ -If modulo is given, compute (a**b) % modulo. The following restrictions\n\ -hold:\n\ -\n\ - * all three arguments must be integral\n\ - * 'b' must be nonnegative\n\ - * at least one of 'a' or 'b' must be nonzero\n\ - * modulo must be nonzero and less than 10**prec in absolute value\n\ -\n\ -\n"); - PyDoc_STRVAR(doc_ctx_quantize, "quantize($self, x, y, /)\n--\n\n\ Return a value equal to x (rounded), having the exponent of y.\n\