]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-73487: Convert ``_decimal`` to use Argument Clinic (part 3) (#137844)
authorSergey B Kirpichev <skirpichev@gmail.com>
Tue, 19 Aug 2025 08:20:06 +0000 (11:20 +0300)
committerGitHub <noreply@github.com>
Tue, 19 Aug 2025 08:20:06 +0000 (09:20 +0100)
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
Include/internal/pycore_global_objects_fini_generated.h
Include/internal/pycore_global_strings.h
Include/internal/pycore_runtime_init_generated.h
Include/internal/pycore_unicodeobject_generated.h
Modules/_decimal/_decimal.c
Modules/_decimal/clinic/_decimal.c.h
Modules/_decimal/docstrings.h

index c5a08e05e7028705fd2d92ee5f5fa2302ca6578c..2078c201b4558d66ed4f0aff360476948b6e132b 100644 (file)
@@ -1296,6 +1296,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));
index 9e49e4497750a0eed0d74b23d600846d1f66e6fd..a7ebaf76c908c8eb589aa3da51f7c1151cef8ed6 100644 (file)
@@ -787,6 +787,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)
index 5c65cb218dedbbef0d350acbb8295f2cb8fbb3f1..27669c50cd6101e08114a666903254a6249e2730 100644 (file)
@@ -1294,6 +1294,7 @@ extern "C" {
     INIT_ID(template), \
     INIT_ID(term), \
     INIT_ID(text), \
+    INIT_ID(third), \
     INIT_ID(threading), \
     INIT_ID(throw), \
     INIT_ID(time), \
index 4905007b95f8fa1dbcdab9ff15b9297dc873cecc..c9b8a8b50510a23e726bf7752bad0a9cccc1fee4 100644 (file)
@@ -2936,6 +2936,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));
index 52ed5a532efd27816bf9f621e2f60db11df068ef..f10ddef6c8c04b76915d3b1e920b6c874154344e 100644 (file)
@@ -63,9 +63,9 @@
 /*[clinic input]
 module _decimal
 class _decimal.Decimal "PyObject *" "&dec_spec"
-class _decimal.Context "PyObject *" "&ctx_spec"
+class _decimal.Context "PyObject *" "&context_spec"
 [clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=8c3aa7cfde934d7b]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a6a6c0bdf4e576ef]*/
 
 struct PyDecContextObject;
 struct DecCondMap;
@@ -4009,10 +4009,7 @@ _decimal_Decimal_to_integral_value_impl(PyObject *self, PyObject *rounding,
 }
 
 /*[clinic input]
-_decimal.Decimal.to_integral
-
-    rounding: object = None
-    context: object = None
+_decimal.Decimal.to_integral = _decimal.Decimal.to_integral_value
 
 Identical to the to_integral_value() method.
 
@@ -4023,16 +4020,13 @@ versions.
 static PyObject *
 _decimal_Decimal_to_integral_impl(PyObject *self, PyObject *rounding,
                                   PyObject *context)
-/*[clinic end generated code: output=a0c7188686ee7f5c input=8eac6def038d13b9]*/
+/*[clinic end generated code: output=a0c7188686ee7f5c input=709b54618ecd0d8b]*/
 {
     return _decimal_Decimal_to_integral_value_impl(self, rounding, context);
 }
 
 /*[clinic input]
-_decimal.Decimal.to_integral_exact
-
-    rounding: object = None
-    context: object = None
+_decimal.Decimal.to_integral_exact = _decimal.Decimal.to_integral_value
 
 Round to the nearest integer.
 
@@ -4045,7 +4039,7 @@ given, then the rounding mode of the current default context is used.
 static PyObject *
 _decimal_Decimal_to_integral_exact_impl(PyObject *self, PyObject *rounding,
                                         PyObject *context)
-/*[clinic end generated code: output=8b004f9b45ac7746 input=c290166f59c1d6ab]*/
+/*[clinic end generated code: output=8b004f9b45ac7746 input=fabce7a744b8087c]*/
 {
     PyObject *result;
     uint32_t status = 0;
@@ -4328,38 +4322,24 @@ dec_##MPDFUNC(PyObject *self, PyObject *Py_UNUSED(dummy))   \
     return MPDFUNC(MPD(self)) ? incr_true() : incr_false(); \
 }
 
-/* Boolean function with an optional context arg. */
+/* Boolean function with an optional context arg.
+   Argument Clinic provides PyObject *self, PyObject *context
+*/
 #define Dec_BoolFuncVA(MPDFUNC) \
-static PyObject *                                                         \
-dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)             \
 {                                                                         \
-    static char *kwlist[] = {"context", NULL};                            \
-    PyObject *context = Py_None;                                          \
-                                                                          \
-    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);                                     \
                                                                           \
     return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \
 }
 
-/* Unary function with an optional context arg. */
+/* Unary function with an optional context arg.
+   Argument Clinic provides PyObject *self, PyObject *context
+*/
 #define Dec_UnaryFuncVA(MPDFUNC) \
-static PyObject *                                              \
-dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)  \
 {                                                              \
-    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);                          \
@@ -4377,22 +4357,14 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)  \
     return result;                                             \
 }
 
-/* Binary function with an optional context arg. */
+/* Binary function with an optional context arg.
+   Argument Clinic provides PyObject *self, PyObject *other, PyObject *context
+*/
 #define Dec_BinaryFuncVA(MPDFUNC) \
-static PyObject *                                                \
-dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)    \
 {                                                                \
-    static char *kwlist[] = {"other", "context", NULL};          \
-    PyObject *other;                                             \
     PyObject *a, *b;                                             \
     PyObject *result;                                            \
-    PyObject *context = Py_None;                                 \
     uint32_t status = 0;                                         \
-                                                                 \
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O", kwlist,  \
-                                     &other, &context)) {        \
-        return NULL;                                             \
-    }                                                            \
     decimal_state *state =                                       \
         get_module_state_by_def(Py_TYPE(self));                  \
     CONTEXT_CHECK_VA(state, context);                            \
@@ -4450,22 +4422,15 @@ dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)   \
     return result;                                              \
 }
 
-/* Ternary function with an optional context arg. */
+/* Ternary function with an optional context arg.
+   Argument Clinic provides PyObject *self, PyObject *other, PyObject *third,
+                            PyObject *context
+*/
 #define Dec_TernaryFuncVA(MPDFUNC) \
-static PyObject *                                                        \
-dec_##MPDFUNC(PyObject *self, PyObject *args, PyObject *kwds)            \
 {                                                                        \
-    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);       \
@@ -4615,25 +4580,249 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod)
 /******************************************************************************/
 
 /* Unary arithmetic functions, optional context arg */
+
+/*[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]*/
 Dec_UnaryFuncVA(mpd_qexp)
+
+/*[clinic input]
+_decimal.Decimal.ln = _decimal.Decimal.exp
+
+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=d353c51ec00d1cff]*/
 Dec_UnaryFuncVA(mpd_qln)
+
+/*[clinic input]
+_decimal.Decimal.log10 = _decimal.Decimal.exp
+
+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=48a6be60154c0b46]*/
 Dec_UnaryFuncVA(mpd_qlog10)
+
+/*[clinic input]
+_decimal.Decimal.next_minus = _decimal.Decimal.exp
+
+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=666b348f71e6c090]*/
 Dec_UnaryFuncVA(mpd_qnext_minus)
+
+/*[clinic input]
+_decimal.Decimal.next_plus = _decimal.Decimal.exp
+
+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=04e105060ad1fa15]*/
 Dec_UnaryFuncVA(mpd_qnext_plus)
+
+/*[clinic input]
+_decimal.Decimal.normalize = _decimal.Decimal.exp
+
+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=d5ee63acd904d4de]*/
 Dec_UnaryFuncVA(mpd_qreduce)
+
+/*[clinic input]
+_decimal.Decimal.sqrt = _decimal.Decimal.exp
+
+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=3a76afbd39dc20b9]*/
 Dec_UnaryFuncVA(mpd_qsqrt)
 
 /* Binary arithmetic functions, optional context arg */
+
+/*[clinic input]
+_decimal.Decimal.compare
+
+    other: object
+    context: object = None
+
+Compare self to other.
+
+Return a decimal value:
+
+    a or b is a NaN ==> Decimal('NaN')
+    a < b           ==> Decimal('-1')
+    a == b          ==> Decimal('0')
+    a > b           ==> Decimal('1')
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_compare_impl(PyObject *self, PyObject *other,
+                              PyObject *context)
+/*[clinic end generated code: output=d6967aa3578b9d48 input=1b7b75a2a154e520]*/
 Dec_BinaryFuncVA(mpd_qcompare)
+
+/*[clinic input]
+_decimal.Decimal.compare_signal = _decimal.Decimal.compare
+
+Identical to compare, except that all NaNs signal.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_compare_signal_impl(PyObject *self, PyObject *other,
+                                     PyObject *context)
+/*[clinic end generated code: output=0b8d0ff43f6c8a95 input=a52a39d1c6fc369d]*/
 Dec_BinaryFuncVA(mpd_qcompare_signal)
+
+/*[clinic input]
+_decimal.Decimal.max = _decimal.Decimal.compare
+
+Maximum of self and other.
+
+If one operand is a quiet NaN and the other is numeric, the numeric
+operand is returned.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_max_impl(PyObject *self, PyObject *other, PyObject *context)
+/*[clinic end generated code: output=f3a5c5d76761c9ff input=2ae2582f551296d8]*/
 Dec_BinaryFuncVA(mpd_qmax)
+
+/*[clinic input]
+_decimal.Decimal.max_mag = _decimal.Decimal.compare
+
+As the max() method, but compares the absolute values of the operands.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_max_mag_impl(PyObject *self, PyObject *other,
+                              PyObject *context)
+/*[clinic end generated code: output=52b0451987bac65f input=88b105e66cf138c5]*/
 Dec_BinaryFuncVA(mpd_qmax_mag)
+
+/*[clinic input]
+_decimal.Decimal.min = _decimal.Decimal.compare
+
+Minimum of self and other.
+
+If one operand is a quiet NaN and the other is numeric, the numeric
+operand is returned.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_min_impl(PyObject *self, PyObject *other, PyObject *context)
+/*[clinic end generated code: output=d2f38ecb9d6f0493 input=2a70f2c087c418c9]*/
 Dec_BinaryFuncVA(mpd_qmin)
+
+/*[clinic input]
+_decimal.Decimal.min_mag = _decimal.Decimal.compare
+
+As the min() method, but compares the absolute values of the operands.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_min_mag_impl(PyObject *self, PyObject *other,
+                              PyObject *context)
+/*[clinic end generated code: output=aa3391935f6c8fc9 input=351fa3c0e592746a]*/
 Dec_BinaryFuncVA(mpd_qmin_mag)
+
+/*[clinic input]
+_decimal.Decimal.next_toward = _decimal.Decimal.compare
+
+Returns the number closest to self, in the direction towards other.
+
+If the two operands are unequal, return the number closest to the first
+operand in the direction of the second operand.  If both operands are
+numerically equal, return a copy of the first operand with the sign set
+to be the same as the sign of the second operand.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_next_toward_impl(PyObject *self, PyObject *other,
+                                  PyObject *context)
+/*[clinic end generated code: output=edb933755644af69 input=fdf0091ea6e9e416]*/
 Dec_BinaryFuncVA(mpd_qnext_toward)
+
+/*[clinic input]
+_decimal.Decimal.remainder_near = _decimal.Decimal.compare
+
+Return the remainder from dividing self by other.
+
+This differs from self % other in that the sign of the remainder is
+chosen so as to minimize its absolute value. More precisely, the return
+value is self - n * other where n is the integer nearest to the exact
+value of self / other, and if two integers are equally near then the
+even one is chosen.
+
+If the result is zero then its sign will be the sign of self.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_remainder_near_impl(PyObject *self, PyObject *other,
+                                     PyObject *context)
+/*[clinic end generated code: output=6ce0fb3b0faff2f9 input=eb5a8dfe3470b794]*/
 Dec_BinaryFuncVA(mpd_qrem_near)
 
 /* Ternary arithmetic functions, optional context arg */
+
+/*[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]*/
 Dec_TernaryFuncVA(mpd_qfma)
 
 /* Boolean functions, no context arg */
@@ -4647,7 +4836,32 @@ Dec_BoolFunc(mpd_issigned)
 Dec_BoolFunc(mpd_iszero)
 
 /* Boolean functions, optional context arg */
+
+/*[clinic input]
+_decimal.Decimal.is_normal = _decimal.Decimal.exp
+
+Return True if the argument is a normal number and False otherwise.
+
+Normal number is a finite nonzero number, which is not subnormal.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_is_normal_impl(PyObject *self, PyObject *context)
+/*[clinic end generated code: output=40cc429d388eb464 input=9afe43b9db9f4818]*/
 Dec_BoolFuncVA(mpd_isnormal)
+
+/*[clinic input]
+_decimal.Decimal.is_subnormal = _decimal.Decimal.exp
+
+Return True if the argument is subnormal, and False otherwise.
+
+A number is subnormal if it is non-zero, finite, and has an adjusted
+exponent less than Emin.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_is_subnormal_impl(PyObject *self, PyObject *context)
+/*[clinic end generated code: output=6f7d422b1f387d7f input=11839c122c185b8b]*/
 Dec_BoolFuncVA(mpd_issubnormal)
 
 /* Unary functions, no context arg */
@@ -4797,13 +5011,35 @@ _decimal_Decimal_copy_negate_impl(PyObject *self)
 }
 
 /* Unary functions, optional context arg */
+
+/*[clinic input]
+_decimal.Decimal.logical_invert = _decimal.Decimal.exp
+
+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=3531dac8b9548dad]*/
 Dec_UnaryFuncVA(mpd_qinvert)
-Dec_UnaryFuncVA(mpd_qlogb)
 
 /*[clinic input]
-_decimal.Decimal.number_class
+_decimal.Decimal.logb = _decimal.Decimal.exp
 
-    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=a8df027d1b8a2b17]*/
+Dec_UnaryFuncVA(mpd_qlogb)
+
+/*[clinic input]
+_decimal.Decimal.number_class = _decimal.Decimal.exp
 
 Return a string describing the class of the operand.
 
@@ -4827,7 +5063,7 @@ The returned value is one of the following ten strings:
 
 static PyObject *
 _decimal_Decimal_number_class_impl(PyObject *self, PyObject *context)
-/*[clinic end generated code: output=3044cd45966b4949 input=f3d6cdda603e8b89]*/
+/*[clinic end generated code: output=3044cd45966b4949 input=447095d2677fa0ca]*/
 {
     const char *cp;
 
@@ -4839,9 +5075,7 @@ _decimal_Decimal_number_class_impl(PyObject *self, PyObject *context)
 }
 
 /*[clinic input]
-_decimal.Decimal.to_eng_string
-
-    context: object = None
+_decimal.Decimal.to_eng_string = _decimal.Decimal.exp
 
 Convert to an engineering-type string.
 
@@ -4856,7 +5090,7 @@ operation.
 
 static PyObject *
 _decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context)
-/*[clinic end generated code: output=d386194c25ffffa7 input=2e13e7c7c1bad2ad]*/
+/*[clinic end generated code: output=d386194c25ffffa7 input=b2cb7e01e268e45d]*/
 {
     PyObject *result;
     mpd_ssize_t size;
@@ -4882,10 +5116,7 @@ Dec_BinaryFuncVA_NO_CTX(mpd_compare_total)
 Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag)
 
 /*[clinic input]
-_decimal.Decimal.copy_sign
-
-    other: object
-    context: object = None
+_decimal.Decimal.copy_sign = _decimal.Decimal.compare
 
 Return a copy of *self* with the sign of *other*.
 
@@ -4903,7 +5134,7 @@ exactly.
 static PyObject *
 _decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other,
                                 PyObject *context)
-/*[clinic end generated code: output=72c62177763e012e input=8410238d533a06eb]*/
+/*[clinic end generated code: output=72c62177763e012e input=51ed9e4691e2249e]*/
 {
     PyObject *a, *b;
     PyObject *result;
@@ -4932,10 +5163,7 @@ _decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other,
 }
 
 /*[clinic input]
-_decimal.Decimal.same_quantum
-
-    other: object
-    context: object = None
+_decimal.Decimal.same_quantum = _decimal.Decimal.compare
 
 Test whether self and other have the same exponent or both are NaN.
 
@@ -4948,7 +5176,7 @@ exactly.
 static PyObject *
 _decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other,
                                    PyObject *context)
-/*[clinic end generated code: output=c0a3a046c662a7e2 input=3ae45df81d6edb73]*/
+/*[clinic end generated code: output=c0a3a046c662a7e2 input=8339415fa359e7df]*/
 {
     PyObject *a, *b;
     PyObject *result;
@@ -4965,12 +5193,94 @@ _decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other,
 }
 
 /* Binary functions, optional context arg */
+
+/*[clinic input]
+_decimal.Decimal.logical_and = _decimal.Decimal.compare
+
+Return the digit-wise 'and' of the two (logical) operands.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_logical_and_impl(PyObject *self, PyObject *other,
+                                  PyObject *context)
+/*[clinic end generated code: output=1526a357f97eaf71 input=2b319baee8970929]*/
 Dec_BinaryFuncVA(mpd_qand)
+
+/*[clinic input]
+_decimal.Decimal.logical_or = _decimal.Decimal.compare
+
+Return the digit-wise 'or' of the two (logical) operands.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_logical_or_impl(PyObject *self, PyObject *other,
+                                 PyObject *context)
+/*[clinic end generated code: output=e57a72acf0982f56 input=75e0e1d4dd373b90]*/
 Dec_BinaryFuncVA(mpd_qor)
+
+/*[clinic input]
+_decimal.Decimal.logical_xor = _decimal.Decimal.compare
+
+Return the digit-wise 'xor' of the two (logical) operands.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_logical_xor_impl(PyObject *self, PyObject *other,
+                                  PyObject *context)
+/*[clinic end generated code: output=ae3a7aeddde5a1a8 input=a1ed8d6ac38c1c9e]*/
 Dec_BinaryFuncVA(mpd_qxor)
 
+/*[clinic input]
+_decimal.Decimal.rotate = _decimal.Decimal.compare
+
+Returns a rotated copy of self's digits, value-of-other times.
+
+The second operand must be an integer in the range -precision through
+precision. The absolute value of the second operand gives the number of
+places to rotate. If the second operand is positive then rotation is to
+the left; otherwise rotation is to the right.  The coefficient of the
+first operand is padded on the left with zeros to length precision if
+necessary. The sign and exponent of the first operand are unchanged.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_rotate_impl(PyObject *self, PyObject *other,
+                             PyObject *context)
+/*[clinic end generated code: output=e59e757e70a8416a input=cde7b032eac43f0b]*/
 Dec_BinaryFuncVA(mpd_qrotate)
+
+/*[clinic input]
+_decimal.Decimal.scaleb = _decimal.Decimal.compare
+
+Return the first operand with the exponent adjusted the second.
+
+Equivalently, return the first operand multiplied by 10**other. The
+second operand must be an integer.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_scaleb_impl(PyObject *self, PyObject *other,
+                             PyObject *context)
+/*[clinic end generated code: output=f01e99600eda34d7 input=7f29f83278d05f83]*/
 Dec_BinaryFuncVA(mpd_qscaleb)
+
+/*[clinic input]
+_decimal.Decimal.shift = _decimal.Decimal.compare
+
+Returns a shifted copy of self's digits, value-of-other times.
+
+The second operand must be an integer in the range -precision through
+precision. The absolute value of the second operand gives the number
+of places to shift. If the second operand is positive, then the shift
+is to the left; otherwise the shift is to the right. Digits shifted
+into the coefficient are zeros. The sign and exponent of the first
+operand are unchanged.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Decimal_shift_impl(PyObject *self, PyObject *other,
+                            PyObject *context)
+/*[clinic end generated code: output=f79ff9ce6d5b05ed input=501759c2522cb78e]*/
 Dec_BinaryFuncVA(mpd_qshift)
 
 /*[clinic input]
@@ -5357,30 +5667,30 @@ 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 },
-  { "compare_signal", _PyCFunction_CAST(dec_mpd_qcompare_signal), METH_VARARGS|METH_KEYWORDS, doc_compare_signal },
-  { "max", _PyCFunction_CAST(dec_mpd_qmax), METH_VARARGS|METH_KEYWORDS, doc_max },
-  { "max_mag", _PyCFunction_CAST(dec_mpd_qmax_mag), METH_VARARGS|METH_KEYWORDS, doc_max_mag },
-  { "min", _PyCFunction_CAST(dec_mpd_qmin), METH_VARARGS|METH_KEYWORDS, doc_min },
-  { "min_mag", _PyCFunction_CAST(dec_mpd_qmin_mag), METH_VARARGS|METH_KEYWORDS, doc_min_mag },
-  { "next_toward", _PyCFunction_CAST(dec_mpd_qnext_toward), METH_VARARGS|METH_KEYWORDS, doc_next_toward },
+  _DECIMAL_DECIMAL_COMPARE_METHODDEF
+  _DECIMAL_DECIMAL_COMPARE_SIGNAL_METHODDEF
+  _DECIMAL_DECIMAL_MAX_METHODDEF
+  _DECIMAL_DECIMAL_MAX_MAG_METHODDEF
+  _DECIMAL_DECIMAL_MIN_METHODDEF
+  _DECIMAL_DECIMAL_MIN_MAG_METHODDEF
+  _DECIMAL_DECIMAL_NEXT_TOWARD_METHODDEF
   _DECIMAL_DECIMAL_QUANTIZE_METHODDEF
-  { "remainder_near", _PyCFunction_CAST(dec_mpd_qrem_near), METH_VARARGS|METH_KEYWORDS, doc_remainder_near },
+  _DECIMAL_DECIMAL_REMAINDER_NEAR_METHODDEF
 
   /* 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 },
@@ -5393,8 +5703,8 @@ static PyMethodDef dec_methods [] =
   { "is_zero", dec_mpd_iszero, METH_NOARGS, doc_is_zero },
 
   /* Boolean functions, optional context arg */
-  { "is_normal", _PyCFunction_CAST(dec_mpd_isnormal), METH_VARARGS|METH_KEYWORDS, doc_is_normal },
-  { "is_subnormal", _PyCFunction_CAST(dec_mpd_issubnormal), METH_VARARGS|METH_KEYWORDS, doc_is_subnormal },
+  _DECIMAL_DECIMAL_IS_NORMAL_METHODDEF
+  _DECIMAL_DECIMAL_IS_SUBNORMAL_METHODDEF
 
   /* Unary functions, no context arg */
   _DECIMAL_DECIMAL_ADJUSTED_METHODDEF
@@ -5407,8 +5717,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
 
@@ -5419,12 +5729,12 @@ static PyMethodDef dec_methods [] =
   _DECIMAL_DECIMAL_SAME_QUANTUM_METHODDEF
 
   /* Binary functions, optional context arg */
-  { "logical_and", _PyCFunction_CAST(dec_mpd_qand), METH_VARARGS|METH_KEYWORDS, doc_logical_and },
-  { "logical_or", _PyCFunction_CAST(dec_mpd_qor), METH_VARARGS|METH_KEYWORDS, doc_logical_or },
-  { "logical_xor", _PyCFunction_CAST(dec_mpd_qxor), METH_VARARGS|METH_KEYWORDS, doc_logical_xor },
-  { "rotate", _PyCFunction_CAST(dec_mpd_qrotate), METH_VARARGS|METH_KEYWORDS, doc_rotate },
-  { "scaleb", _PyCFunction_CAST(dec_mpd_qscaleb), METH_VARARGS|METH_KEYWORDS, doc_scaleb },
-  { "shift", _PyCFunction_CAST(dec_mpd_qshift), METH_VARARGS|METH_KEYWORDS, doc_shift },
+  _DECIMAL_DECIMAL_LOGICAL_AND_METHODDEF
+  _DECIMAL_DECIMAL_LOGICAL_OR_METHODDEF
+  _DECIMAL_DECIMAL_LOGICAL_XOR_METHODDEF
+  _DECIMAL_DECIMAL_ROTATE_METHODDEF
+  _DECIMAL_DECIMAL_SCALEB_METHODDEF
+  _DECIMAL_DECIMAL_SHIFT_METHODDEF
 
   /* Miscellaneous */
   _DECIMAL_DECIMAL_FROM_FLOAT_METHODDEF
index 7a2bcce1e9316b06af3594f4c71c077f2312f3fa..7541a3ed79549d872500b131b55ea7a7377f29e2 100644 (file)
@@ -572,162 +572,1920 @@ _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*/ 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_normalize_impl(self, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_sqrt__doc__,
+"sqrt($self, /, context=None)\n"
+"--\n"
+"\n"
+"Return the square root of the argument to full precision.\n"
+"\n"
+"The result is correctly rounded using the ROUND_HALF_EVEN rounding mode.");
+
+#define _DECIMAL_DECIMAL_SQRT_METHODDEF    \
+    {"sqrt", _PyCFunction_CAST(_decimal_Decimal_sqrt), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_sqrt__doc__},
+
+static PyObject *
+_decimal_Decimal_sqrt_impl(PyObject *self, PyObject *context);
+
+static PyObject *
+_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 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 = "sqrt",
+        .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_sqrt_impl(self, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_compare__doc__,
+"compare($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"Compare self to other.\n"
+"\n"
+"Return a decimal value:\n"
+"\n"
+"    a or b is a NaN ==> Decimal(\'NaN\')\n"
+"    a < b           ==> Decimal(\'-1\')\n"
+"    a == b          ==> Decimal(\'0\')\n"
+"    a > b           ==> Decimal(\'1\')");
+
+#define _DECIMAL_DECIMAL_COMPARE_METHODDEF    \
+    {"compare", _PyCFunction_CAST(_decimal_Decimal_compare), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare__doc__},
+
+static PyObject *
+_decimal_Decimal_compare_impl(PyObject *self, PyObject *other,
+                              PyObject *context);
+
+static PyObject *
+_decimal_Decimal_compare(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "compare",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_compare_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_compare_signal__doc__,
+"compare_signal($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"Identical to compare, except that all NaNs signal.");
+
+#define _DECIMAL_DECIMAL_COMPARE_SIGNAL_METHODDEF    \
+    {"compare_signal", _PyCFunction_CAST(_decimal_Decimal_compare_signal), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_signal__doc__},
+
+static PyObject *
+_decimal_Decimal_compare_signal_impl(PyObject *self, PyObject *other,
+                                     PyObject *context);
+
+static PyObject *
+_decimal_Decimal_compare_signal(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "compare_signal",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_compare_signal_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_max__doc__,
+"max($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"Maximum of self and other.\n"
+"\n"
+"If one operand is a quiet NaN and the other is numeric, the numeric\n"
+"operand is returned.");
+
+#define _DECIMAL_DECIMAL_MAX_METHODDEF    \
+    {"max", _PyCFunction_CAST(_decimal_Decimal_max), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_max__doc__},
+
+static PyObject *
+_decimal_Decimal_max_impl(PyObject *self, PyObject *other, PyObject *context);
+
+static PyObject *
+_decimal_Decimal_max(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "max",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_max_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_max_mag__doc__,
+"max_mag($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"As the max() method, but compares the absolute values of the operands.");
+
+#define _DECIMAL_DECIMAL_MAX_MAG_METHODDEF    \
+    {"max_mag", _PyCFunction_CAST(_decimal_Decimal_max_mag), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_max_mag__doc__},
+
+static PyObject *
+_decimal_Decimal_max_mag_impl(PyObject *self, PyObject *other,
+                              PyObject *context);
+
+static PyObject *
+_decimal_Decimal_max_mag(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "max_mag",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_max_mag_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_min__doc__,
+"min($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"Minimum of self and other.\n"
+"\n"
+"If one operand is a quiet NaN and the other is numeric, the numeric\n"
+"operand is returned.");
+
+#define _DECIMAL_DECIMAL_MIN_METHODDEF    \
+    {"min", _PyCFunction_CAST(_decimal_Decimal_min), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_min__doc__},
+
+static PyObject *
+_decimal_Decimal_min_impl(PyObject *self, PyObject *other, PyObject *context);
+
+static PyObject *
+_decimal_Decimal_min(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "min",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_min_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_min_mag__doc__,
+"min_mag($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"As the min() method, but compares the absolute values of the operands.");
+
+#define _DECIMAL_DECIMAL_MIN_MAG_METHODDEF    \
+    {"min_mag", _PyCFunction_CAST(_decimal_Decimal_min_mag), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_min_mag__doc__},
+
+static PyObject *
+_decimal_Decimal_min_mag_impl(PyObject *self, PyObject *other,
+                              PyObject *context);
+
+static PyObject *
+_decimal_Decimal_min_mag(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "min_mag",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_min_mag_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_next_toward__doc__,
+"next_toward($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"Returns the number closest to self, in the direction towards other.\n"
+"\n"
+"If the two operands are unequal, return the number closest to the first\n"
+"operand in the direction of the second operand.  If both operands are\n"
+"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.");
+
+#define _DECIMAL_DECIMAL_NEXT_TOWARD_METHODDEF    \
+    {"next_toward", _PyCFunction_CAST(_decimal_Decimal_next_toward), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_toward__doc__},
+
+static PyObject *
+_decimal_Decimal_next_toward_impl(PyObject *self, PyObject *other,
+                                  PyObject *context);
+
+static PyObject *
+_decimal_Decimal_next_toward(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "next_toward",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_next_toward_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_remainder_near__doc__,
+"remainder_near($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"Return the remainder from dividing self by other.\n"
+"\n"
+"This differs from self % other in that the sign of the remainder is\n"
+"chosen so as to minimize its absolute value. More precisely, the return\n"
+"value is self - n * other where n is the integer nearest to the exact\n"
+"value of self / other, and if two integers are equally near then the\n"
+"even one is chosen.\n"
+"\n"
+"If the result is zero then its sign will be the sign of self.");
+
+#define _DECIMAL_DECIMAL_REMAINDER_NEAR_METHODDEF    \
+    {"remainder_near", _PyCFunction_CAST(_decimal_Decimal_remainder_near), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_remainder_near__doc__},
+
+static PyObject *
+_decimal_Decimal_remainder_near_impl(PyObject *self, PyObject *other,
+                                     PyObject *context);
+
+static PyObject *
+_decimal_Decimal_remainder_near(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "remainder_near",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_remainder_near_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_fma__doc__,
+"fma($self, /, other, third, context=None)\n"
+"--\n"
+"\n"
+"Fused multiply-add.\n"
+"\n"
+"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_FMA_METHODDEF    \
+    {"fma", _PyCFunction_CAST(_decimal_Decimal_fma), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_fma__doc__},
+
+static PyObject *
+_decimal_Decimal_fma_impl(PyObject *self, PyObject *other, PyObject *third,
+                          PyObject *context);
+
+static PyObject *
+_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 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_ID(other), &_Py_ID(third), &_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[] = {"other", "third", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "fma",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    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*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    third = args[1];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[2];
+skip_optional_pos:
+    return_value = _decimal_Decimal_fma_impl(self, other, third, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_is_normal__doc__,
+"is_normal($self, /, context=None)\n"
+"--\n"
+"\n"
+"Return True if the argument is a normal number and False otherwise.\n"
+"\n"
+"Normal number is a finite nonzero number, which is not subnormal.");
+
+#define _DECIMAL_DECIMAL_IS_NORMAL_METHODDEF    \
+    {"is_normal", _PyCFunction_CAST(_decimal_Decimal_is_normal), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_is_normal__doc__},
+
+static PyObject *
+_decimal_Decimal_is_normal_impl(PyObject *self, PyObject *context);
+
+static PyObject *
+_decimal_Decimal_is_normal(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 = "is_normal",
+        .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_is_normal_impl(self, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_is_subnormal__doc__,
+"is_subnormal($self, /, context=None)\n"
+"--\n"
+"\n"
+"Return True if the argument is subnormal, and False otherwise.\n"
+"\n"
+"A number is subnormal if it is non-zero, finite, and has an adjusted\n"
+"exponent less than Emin.");
+
+#define _DECIMAL_DECIMAL_IS_SUBNORMAL_METHODDEF    \
+    {"is_subnormal", _PyCFunction_CAST(_decimal_Decimal_is_subnormal), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_is_subnormal__doc__},
+
+static PyObject *
+_decimal_Decimal_is_subnormal_impl(PyObject *self, PyObject *context);
+
+static PyObject *
+_decimal_Decimal_is_subnormal(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 = "is_subnormal",
+        .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_is_subnormal_impl(self, context);
+
+exit:
+    return return_value;
+}
+
 PyDoc_STRVAR(_decimal_Decimal_adjusted__doc__,
 "adjusted($self, /)\n"
 "--\n"
 "\n"
-"Return the adjusted exponent (exp + digits - 1) of the number.");
+"Return the adjusted exponent (exp + digits - 1) of the number.");
+
+#define _DECIMAL_DECIMAL_ADJUSTED_METHODDEF    \
+    {"adjusted", (PyCFunction)_decimal_Decimal_adjusted, METH_NOARGS, _decimal_Decimal_adjusted__doc__},
+
+static PyObject *
+_decimal_Decimal_adjusted_impl(PyObject *self);
+
+static PyObject *
+_decimal_Decimal_adjusted(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _decimal_Decimal_adjusted_impl(self);
+}
+
+PyDoc_STRVAR(_decimal_Decimal_canonical__doc__,
+"canonical($self, /)\n"
+"--\n"
+"\n"
+"Return the canonical encoding of the argument.\n"
+"\n"
+"Currently, the encoding of a Decimal instance is always canonical,\n"
+"so this operation returns its argument unchanged.");
+
+#define _DECIMAL_DECIMAL_CANONICAL_METHODDEF    \
+    {"canonical", (PyCFunction)_decimal_Decimal_canonical, METH_NOARGS, _decimal_Decimal_canonical__doc__},
+
+static PyObject *
+_decimal_Decimal_canonical_impl(PyObject *self);
+
+static PyObject *
+_decimal_Decimal_canonical(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _decimal_Decimal_canonical_impl(self);
+}
+
+PyDoc_STRVAR(_decimal_Decimal_conjugate__doc__,
+"conjugate($self, /)\n"
+"--\n"
+"\n"
+"Return self.");
+
+#define _DECIMAL_DECIMAL_CONJUGATE_METHODDEF    \
+    {"conjugate", (PyCFunction)_decimal_Decimal_conjugate, METH_NOARGS, _decimal_Decimal_conjugate__doc__},
+
+static PyObject *
+_decimal_Decimal_conjugate_impl(PyObject *self);
+
+static PyObject *
+_decimal_Decimal_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _decimal_Decimal_conjugate_impl(self);
+}
+
+PyDoc_STRVAR(_decimal_Decimal_radix__doc__,
+"radix($self, /)\n"
+"--\n"
+"\n"
+"Return Decimal(10).\n"
+"\n"
+"This is the radix (base) in which the Decimal class does\n"
+"all its arithmetic. Included for compatibility with the specification.");
+
+#define _DECIMAL_DECIMAL_RADIX_METHODDEF    \
+    {"radix", (PyCFunction)_decimal_Decimal_radix, METH_NOARGS, _decimal_Decimal_radix__doc__},
+
+static PyObject *
+_decimal_Decimal_radix_impl(PyObject *self);
+
+static PyObject *
+_decimal_Decimal_radix(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _decimal_Decimal_radix_impl(self);
+}
+
+PyDoc_STRVAR(_decimal_Decimal_copy_abs__doc__,
+"copy_abs($self, /)\n"
+"--\n"
+"\n"
+"Return the absolute value of the argument.\n"
+"\n"
+"This operation is unaffected by context and is quiet: no flags are\n"
+"changed and no rounding is performed.");
+
+#define _DECIMAL_DECIMAL_COPY_ABS_METHODDEF    \
+    {"copy_abs", (PyCFunction)_decimal_Decimal_copy_abs, METH_NOARGS, _decimal_Decimal_copy_abs__doc__},
+
+static PyObject *
+_decimal_Decimal_copy_abs_impl(PyObject *self);
+
+static PyObject *
+_decimal_Decimal_copy_abs(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+    return _decimal_Decimal_copy_abs_impl(self);
+}
+
+PyDoc_STRVAR(_decimal_Decimal_copy_negate__doc__,
+"copy_negate($self, /)\n"
+"--\n"
+"\n"
+"Return the negation of the argument.\n"
+"\n"
+"This operation is unaffected by context and is quiet: no flags are\n"
+"changed and no rounding is performed.");
+
+#define _DECIMAL_DECIMAL_COPY_NEGATE_METHODDEF    \
+    {"copy_negate", (PyCFunction)_decimal_Decimal_copy_negate, METH_NOARGS, _decimal_Decimal_copy_negate__doc__},
+
+static PyObject *
+_decimal_Decimal_copy_negate_impl(PyObject *self);
+
+static PyObject *
+_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"
+"\n"
+"Return a string describing the class of the operand.\n"
+"\n"
+"The returned value is one of the following ten strings:\n"
+"\n"
+"    * \'-Infinity\', indicating that the operand is negative infinity.\n"
+"    * \'-Normal\', indicating that the operand is a negative normal\n"
+"      number.\n"
+"    * \'-Subnormal\', indicating that the operand is negative and\n"
+"      subnormal.\n"
+"    * \'-Zero\', indicating that the operand is a negative zero.\n"
+"    * \'+Zero\', indicating that the operand is a positive zero.\n"
+"    * \'+Subnormal\', indicating that the operand is positive and\n"
+"      subnormal.\n"
+"    * \'+Normal\', indicating that the operand is a positive normal\n"
+"      number.\n"
+"    * \'+Infinity\', indicating that the operand is positive infinity.\n"
+"    * \'NaN\', indicating that the operand is a quiet NaN (Not a Number).\n"
+"    * \'sNaN\', indicating that the operand is a signaling NaN.");
+
+#define _DECIMAL_DECIMAL_NUMBER_CLASS_METHODDEF    \
+    {"number_class", _PyCFunction_CAST(_decimal_Decimal_number_class), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_number_class__doc__},
+
+static PyObject *
+_decimal_Decimal_number_class_impl(PyObject *self, PyObject *context);
+
+static PyObject *
+_decimal_Decimal_number_class(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 = "number_class",
+        .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_number_class_impl(self, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_to_eng_string__doc__,
+"to_eng_string($self, /, context=None)\n"
+"--\n"
+"\n"
+"Convert to an engineering-type string.\n"
+"\n"
+"Engineering notation has an exponent which is a multiple of 3, so there\n"
+"are up to 3 digits left of the decimal place. For example,\n"
+"Decimal(\'123E+1\') is converted to Decimal(\'1.23E+3\').\n"
+"\n"
+"The value of context.capitals determines whether the exponent sign is\n"
+"lower or upper case. Otherwise, the context does not affect the\n"
+"operation.");
 
-#define _DECIMAL_DECIMAL_ADJUSTED_METHODDEF    \
-    {"adjusted", (PyCFunction)_decimal_Decimal_adjusted, METH_NOARGS, _decimal_Decimal_adjusted__doc__},
+#define _DECIMAL_DECIMAL_TO_ENG_STRING_METHODDEF    \
+    {"to_eng_string", _PyCFunction_CAST(_decimal_Decimal_to_eng_string), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_eng_string__doc__},
 
 static PyObject *
-_decimal_Decimal_adjusted_impl(PyObject *self);
+_decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_adjusted(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_adjusted_impl(self);
+    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 = "to_eng_string",
+        .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_to_eng_string_impl(self, context);
+
+exit:
+    return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Decimal_canonical__doc__,
-"canonical($self, /)\n"
+PyDoc_STRVAR(_decimal_Decimal_copy_sign__doc__,
+"copy_sign($self, /, other, context=None)\n"
 "--\n"
 "\n"
-"Return the canonical encoding of the argument.\n"
+"Return a copy of *self* with the sign of *other*.\n"
 "\n"
-"Currently, the encoding of a Decimal instance is always canonical,\n"
-"so this operation returns its argument unchanged.");
+"For example:\n"
+"\n"
+"    >>> Decimal(\'2.3\').copy_sign(Decimal(\'-1.5\'))\n"
+"    Decimal(\'-2.3\')\n"
+"\n"
+"This operation is unaffected by context and is quiet: no flags are\n"
+"changed and no rounding is performed. As an exception, the C version\n"
+"may raise InvalidOperation if the second operand cannot be converted\n"
+"exactly.");
 
-#define _DECIMAL_DECIMAL_CANONICAL_METHODDEF    \
-    {"canonical", (PyCFunction)_decimal_Decimal_canonical, METH_NOARGS, _decimal_Decimal_canonical__doc__},
+#define _DECIMAL_DECIMAL_COPY_SIGN_METHODDEF    \
+    {"copy_sign", _PyCFunction_CAST(_decimal_Decimal_copy_sign), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_sign__doc__},
 
 static PyObject *
-_decimal_Decimal_canonical_impl(PyObject *self);
+_decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other,
+                                PyObject *context);
+
+static PyObject *
+_decimal_Decimal_copy_sign(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "copy_sign",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_copy_sign_impl(self, other, context);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Decimal_same_quantum__doc__,
+"same_quantum($self, /, other, context=None)\n"
+"--\n"
+"\n"
+"Test whether self and other have the same exponent or both are NaN.\n"
+"\n"
+"This operation is unaffected by context and is quiet: no flags are\n"
+"changed and no rounding is performed. As an exception, the C version\n"
+"may raise InvalidOperation if the second operand cannot be converted\n"
+"exactly.");
+
+#define _DECIMAL_DECIMAL_SAME_QUANTUM_METHODDEF    \
+    {"same_quantum", _PyCFunction_CAST(_decimal_Decimal_same_quantum), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_same_quantum__doc__},
+
+static PyObject *
+_decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other,
+                                   PyObject *context);
+
+static PyObject *
+_decimal_Decimal_same_quantum(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(other), &_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[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "same_quantum",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_same_quantum_impl(self, other, context);
 
-static PyObject *
-_decimal_Decimal_canonical(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _decimal_Decimal_canonical_impl(self);
+exit:
+    return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Decimal_conjugate__doc__,
-"conjugate($self, /)\n"
+PyDoc_STRVAR(_decimal_Decimal_logical_and__doc__,
+"logical_and($self, /, other, context=None)\n"
 "--\n"
 "\n"
-"Return self.");
+"Return the digit-wise \'and\' of the two (logical) operands.");
 
-#define _DECIMAL_DECIMAL_CONJUGATE_METHODDEF    \
-    {"conjugate", (PyCFunction)_decimal_Decimal_conjugate, METH_NOARGS, _decimal_Decimal_conjugate__doc__},
+#define _DECIMAL_DECIMAL_LOGICAL_AND_METHODDEF    \
+    {"logical_and", _PyCFunction_CAST(_decimal_Decimal_logical_and), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_and__doc__},
 
 static PyObject *
-_decimal_Decimal_conjugate_impl(PyObject *self);
+_decimal_Decimal_logical_and_impl(PyObject *self, PyObject *other,
+                                  PyObject *context);
 
 static PyObject *
-_decimal_Decimal_conjugate(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_logical_and(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_conjugate_impl(self);
-}
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
 
-PyDoc_STRVAR(_decimal_Decimal_radix__doc__,
-"radix($self, /)\n"
-"--\n"
-"\n"
-"Return Decimal(10).\n"
-"\n"
-"This is the radix (base) in which the Decimal class does\n"
-"all its arithmetic. Included for compatibility with the specification.");
+    #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(other), &_Py_ID(context), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
 
-#define _DECIMAL_DECIMAL_RADIX_METHODDEF    \
-    {"radix", (PyCFunction)_decimal_Decimal_radix, METH_NOARGS, _decimal_Decimal_radix__doc__},
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
 
-static PyObject *
-_decimal_Decimal_radix_impl(PyObject *self);
+    static const char * const _keywords[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "logical_and",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
 
-static PyObject *
-_decimal_Decimal_radix(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _decimal_Decimal_radix_impl(self);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_logical_and_impl(self, other, context);
+
+exit:
+    return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Decimal_copy_abs__doc__,
-"copy_abs($self, /)\n"
+PyDoc_STRVAR(_decimal_Decimal_logical_or__doc__,
+"logical_or($self, /, other, context=None)\n"
 "--\n"
 "\n"
-"Return the absolute value of the argument.\n"
-"\n"
-"This operation is unaffected by context and is quiet: no flags are\n"
-"changed and no rounding is performed.");
+"Return the digit-wise \'or\' of the two (logical) operands.");
 
-#define _DECIMAL_DECIMAL_COPY_ABS_METHODDEF    \
-    {"copy_abs", (PyCFunction)_decimal_Decimal_copy_abs, METH_NOARGS, _decimal_Decimal_copy_abs__doc__},
+#define _DECIMAL_DECIMAL_LOGICAL_OR_METHODDEF    \
+    {"logical_or", _PyCFunction_CAST(_decimal_Decimal_logical_or), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_or__doc__},
 
 static PyObject *
-_decimal_Decimal_copy_abs_impl(PyObject *self);
+_decimal_Decimal_logical_or_impl(PyObject *self, PyObject *other,
+                                 PyObject *context);
 
 static PyObject *
-_decimal_Decimal_copy_abs(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_logical_or(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_copy_abs_impl(self);
-}
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
 
-PyDoc_STRVAR(_decimal_Decimal_copy_negate__doc__,
-"copy_negate($self, /)\n"
-"--\n"
-"\n"
-"Return the negation of the argument.\n"
-"\n"
-"This operation is unaffected by context and is quiet: no flags are\n"
-"changed and no rounding is performed.");
+    #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(other), &_Py_ID(context), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
 
-#define _DECIMAL_DECIMAL_COPY_NEGATE_METHODDEF    \
-    {"copy_negate", (PyCFunction)_decimal_Decimal_copy_negate, METH_NOARGS, _decimal_Decimal_copy_negate__doc__},
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
 
-static PyObject *
-_decimal_Decimal_copy_negate_impl(PyObject *self);
+    static const char * const _keywords[] = {"other", "context", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "logical_or",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
+    PyObject *context = Py_None;
 
-static PyObject *
-_decimal_Decimal_copy_negate(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
-    return _decimal_Decimal_copy_negate_impl(self);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    other = args[0];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    context = args[1];
+skip_optional_pos:
+    return_value = _decimal_Decimal_logical_or_impl(self, other, context);
+
+exit:
+    return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Decimal_number_class__doc__,
-"number_class($self, /, context=None)\n"
+PyDoc_STRVAR(_decimal_Decimal_logical_xor__doc__,
+"logical_xor($self, /, other, context=None)\n"
 "--\n"
 "\n"
-"Return a string describing the class of the operand.\n"
-"\n"
-"The returned value is one of the following ten strings:\n"
-"\n"
-"    * \'-Infinity\', indicating that the operand is negative infinity.\n"
-"    * \'-Normal\', indicating that the operand is a negative normal\n"
-"      number.\n"
-"    * \'-Subnormal\', indicating that the operand is negative and\n"
-"      subnormal.\n"
-"    * \'-Zero\', indicating that the operand is a negative zero.\n"
-"    * \'+Zero\', indicating that the operand is a positive zero.\n"
-"    * \'+Subnormal\', indicating that the operand is positive and\n"
-"      subnormal.\n"
-"    * \'+Normal\', indicating that the operand is a positive normal\n"
-"      number.\n"
-"    * \'+Infinity\', indicating that the operand is positive infinity.\n"
-"    * \'NaN\', indicating that the operand is a quiet NaN (Not a Number).\n"
-"    * \'sNaN\', indicating that the operand is a signaling NaN.");
+"Return the digit-wise \'xor\' of the two (logical) operands.");
 
-#define _DECIMAL_DECIMAL_NUMBER_CLASS_METHODDEF    \
-    {"number_class", _PyCFunction_CAST(_decimal_Decimal_number_class), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_number_class__doc__},
+#define _DECIMAL_DECIMAL_LOGICAL_XOR_METHODDEF    \
+    {"logical_xor", _PyCFunction_CAST(_decimal_Decimal_logical_xor), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_xor__doc__},
 
 static PyObject *
-_decimal_Decimal_number_class_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_logical_xor_impl(PyObject *self, PyObject *other,
+                                  PyObject *context);
 
 static PyObject *
-_decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_logical_xor(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
+    #define NUM_KEYWORDS 2
     static struct {
         PyGC_Head _this_is_not_used;
         PyObject_VAR_HEAD
@@ -736,7 +2494,7 @@ _decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t
     } _kwtuple = {
         .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
         .ob_hash = -1,
-        .ob_item = { &_Py_ID(context), },
+        .ob_item = { &_Py_ID(other), &_Py_ID(context), },
     };
     #undef NUM_KEYWORDS
     #define KWTUPLE (&_kwtuple.ob_base.ob_base)
@@ -745,60 +2503,62 @@ _decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t
     #  define KWTUPLE NULL
     #endif  // !Py_BUILD_CORE
 
-    static const char * const _keywords[] = {"context", NULL};
+    static const char * const _keywords[] = {"other", "context", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
-        .fname = "number_class",
+        .fname = "logical_xor",
         .kwtuple = KWTUPLE,
     };
     #undef KWTUPLE
-    PyObject *argsbuf[1];
-    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
     PyObject *context = Py_None;
 
     args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
     if (!args) {
         goto exit;
     }
+    other = args[0];
     if (!noptargs) {
         goto skip_optional_pos;
     }
-    context = args[0];
+    context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_number_class_impl(self, context);
+    return_value = _decimal_Decimal_logical_xor_impl(self, other, context);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Decimal_to_eng_string__doc__,
-"to_eng_string($self, /, context=None)\n"
+PyDoc_STRVAR(_decimal_Decimal_rotate__doc__,
+"rotate($self, /, other, context=None)\n"
 "--\n"
 "\n"
-"Convert to an engineering-type string.\n"
-"\n"
-"Engineering notation has an exponent which is a multiple of 3, so there\n"
-"are up to 3 digits left of the decimal place. For example,\n"
-"Decimal(\'123E+1\') is converted to Decimal(\'1.23E+3\').\n"
+"Returns a rotated copy of self\'s digits, value-of-other times.\n"
 "\n"
-"The value of context.capitals determines whether the exponent sign is\n"
-"lower or upper case. Otherwise, the context does not affect the\n"
-"operation.");
+"The second operand must be an integer in the range -precision through\n"
+"precision. The absolute value of the second operand gives the number of\n"
+"places to rotate. If the second operand is positive then rotation is to\n"
+"the left; otherwise rotation is to the right.  The coefficient of the\n"
+"first operand is padded on the left with zeros to length precision if\n"
+"necessary. The sign and exponent of the first operand are unchanged.");
 
-#define _DECIMAL_DECIMAL_TO_ENG_STRING_METHODDEF    \
-    {"to_eng_string", _PyCFunction_CAST(_decimal_Decimal_to_eng_string), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_eng_string__doc__},
+#define _DECIMAL_DECIMAL_ROTATE_METHODDEF    \
+    {"rotate", _PyCFunction_CAST(_decimal_Decimal_rotate), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_rotate__doc__},
 
 static PyObject *
-_decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_rotate_impl(PyObject *self, PyObject *other,
+                             PyObject *context);
 
 static PyObject *
-_decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_rotate(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
+    #define NUM_KEYWORDS 2
     static struct {
         PyGC_Head _this_is_not_used;
         PyObject_VAR_HEAD
@@ -807,7 +2567,7 @@ _decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t
     } _kwtuple = {
         .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
         .ob_hash = -1,
-        .ob_item = { &_Py_ID(context), },
+        .ob_item = { &_Py_ID(other), &_Py_ID(context), },
     };
     #undef NUM_KEYWORDS
     #define KWTUPLE (&_kwtuple.ob_base.ob_base)
@@ -816,58 +2576,53 @@ _decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t
     #  define KWTUPLE NULL
     #endif  // !Py_BUILD_CORE
 
-    static const char * const _keywords[] = {"context", NULL};
+    static const char * const _keywords[] = {"other", "context", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
-        .fname = "to_eng_string",
+        .fname = "rotate",
         .kwtuple = KWTUPLE,
     };
     #undef KWTUPLE
-    PyObject *argsbuf[1];
-    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
+    PyObject *argsbuf[2];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
+    PyObject *other;
     PyObject *context = Py_None;
 
     args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
     if (!args) {
         goto exit;
     }
+    other = args[0];
     if (!noptargs) {
         goto skip_optional_pos;
     }
-    context = args[0];
+    context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_to_eng_string_impl(self, context);
+    return_value = _decimal_Decimal_rotate_impl(self, other, context);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Decimal_copy_sign__doc__,
-"copy_sign($self, /, other, context=None)\n"
+PyDoc_STRVAR(_decimal_Decimal_scaleb__doc__,
+"scaleb($self, /, other, context=None)\n"
 "--\n"
 "\n"
-"Return a copy of *self* with the sign of *other*.\n"
-"\n"
-"For example:\n"
-"\n"
-"    >>> Decimal(\'2.3\').copy_sign(Decimal(\'-1.5\'))\n"
-"    Decimal(\'-2.3\')\n"
+"Return the first operand with the exponent adjusted the second.\n"
 "\n"
-"This operation is unaffected by context and is quiet: no flags are\n"
-"changed and no rounding is performed. As an exception, the C version\n"
-"may raise InvalidOperation if the second operand cannot be converted\n"
-"exactly.");
+"Equivalently, return the first operand multiplied by 10**other. The\n"
+"second operand must be an integer.");
 
-#define _DECIMAL_DECIMAL_COPY_SIGN_METHODDEF    \
-    {"copy_sign", _PyCFunction_CAST(_decimal_Decimal_copy_sign), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_sign__doc__},
+#define _DECIMAL_DECIMAL_SCALEB_METHODDEF    \
+    {"scaleb", _PyCFunction_CAST(_decimal_Decimal_scaleb), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_scaleb__doc__},
 
 static PyObject *
-_decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other,
-                                PyObject *context);
+_decimal_Decimal_scaleb_impl(PyObject *self, PyObject *other,
+                             PyObject *context);
 
 static PyObject *
-_decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_scaleb(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)
@@ -893,7 +2648,7 @@ _decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nar
     static const char * const _keywords[] = {"other", "context", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
-        .fname = "copy_sign",
+        .fname = "scaleb",
         .kwtuple = KWTUPLE,
     };
     #undef KWTUPLE
@@ -913,32 +2668,34 @@ _decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nar
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_copy_sign_impl(self, other, context);
+    return_value = _decimal_Decimal_scaleb_impl(self, other, context);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Decimal_same_quantum__doc__,
-"same_quantum($self, /, other, context=None)\n"
+PyDoc_STRVAR(_decimal_Decimal_shift__doc__,
+"shift($self, /, other, context=None)\n"
 "--\n"
 "\n"
-"Test whether self and other have the same exponent or both are NaN.\n"
+"Returns a shifted copy of self\'s digits, value-of-other times.\n"
 "\n"
-"This operation is unaffected by context and is quiet: no flags are\n"
-"changed and no rounding is performed. As an exception, the C version\n"
-"may raise InvalidOperation if the second operand cannot be converted\n"
-"exactly.");
+"The second operand must be an integer in the range -precision through\n"
+"precision. The absolute value of the second operand gives the number\n"
+"of places to shift. If the second operand is positive, then the shift\n"
+"is to the left; otherwise the shift is to the right. Digits shifted\n"
+"into the coefficient are zeros. The sign and exponent of the first\n"
+"operand are unchanged.");
 
-#define _DECIMAL_DECIMAL_SAME_QUANTUM_METHODDEF    \
-    {"same_quantum", _PyCFunction_CAST(_decimal_Decimal_same_quantum), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_same_quantum__doc__},
+#define _DECIMAL_DECIMAL_SHIFT_METHODDEF    \
+    {"shift", _PyCFunction_CAST(_decimal_Decimal_shift), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_shift__doc__},
 
 static PyObject *
-_decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other,
-                                   PyObject *context);
+_decimal_Decimal_shift_impl(PyObject *self, PyObject *other,
+                            PyObject *context);
 
 static PyObject *
-_decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_shift(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)
@@ -964,7 +2721,7 @@ _decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t
     static const char * const _keywords[] = {"other", "context", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
-        .fname = "same_quantum",
+        .fname = "shift",
         .kwtuple = KWTUPLE,
     };
     #undef KWTUPLE
@@ -984,7 +2741,7 @@ _decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_same_quantum_impl(self, other, context);
+    return_value = _decimal_Decimal_shift_impl(self, other, context);
 
 exit:
     return return_value;
@@ -1165,4 +2922,4 @@ skip_optional_pos:
 exit:
     return return_value;
 }
-/*[clinic end generated code: output=6bb5c926552c2760 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9bbde3e723166dd3 input=a9049054013a1b77]*/
index 3ecfd34122ab6b1f318cb7838efbc444349a12cb..3ebac0a9b1e80ab67c922b9647a13bfdad57999e 100644 (file)
@@ -31,21 +31,6 @@ context does not affect the conversion and is only passed to determine if\n\
 the InvalidOperation trap is active.\n\
 \n");
 
-PyDoc_STRVAR(doc_compare,
-"compare($self, /, other, context=None)\n--\n\n\
-Compare self to other.  Return a decimal value:\n\
-\n\
-    a or b is a NaN ==> Decimal('NaN')\n\
-    a < b           ==> Decimal('-1')\n\
-    a == b          ==> Decimal('0')\n\
-    a > b           ==> Decimal('1')\n\
-\n");
-
-PyDoc_STRVAR(doc_compare_signal,
-"compare_signal($self, /, other, context=None)\n--\n\n\
-Identical to compare, except that all NaNs signal.\n\
-\n");
-
 PyDoc_STRVAR(doc_compare_total,
 "compare_total($self, /, other, context=None)\n--\n\n\
 Compare two operands using their abstract representation rather than\n\
@@ -80,23 +65,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\
@@ -122,13 +90,6 @@ Return True if the argument is a (quiet or signaling) NaN and False\n\
 otherwise.\n\
 \n");
 
-PyDoc_STRVAR(doc_is_normal,
-"is_normal($self, /, context=None)\n--\n\n\
-Return True if the argument is a normal finite non-zero number with an\n\
-adjusted exponent greater than or equal to Emin. Return False if the\n\
-argument is zero, subnormal, infinite or a NaN.\n\
-\n");
-
 PyDoc_STRVAR(doc_is_qnan,
 "is_qnan($self, /)\n--\n\n\
 Return True if the argument is a quiet NaN, and False otherwise.\n\
@@ -145,162 +106,12 @@ PyDoc_STRVAR(doc_is_snan,
 Return True if the argument is a signaling NaN and False otherwise.\n\
 \n");
 
-PyDoc_STRVAR(doc_is_subnormal,
-"is_subnormal($self, /, context=None)\n--\n\n\
-Return True if the argument is subnormal, and False otherwise. A number is\n\
-subnormal if it is non-zero, finite, and has an adjusted exponent less\n\
-than Emin.\n\
-\n");
-
 PyDoc_STRVAR(doc_is_zero,
 "is_zero($self, /)\n--\n\n\
 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\
-\n");
-
-PyDoc_STRVAR(doc_logical_xor,
-"logical_xor($self, /, other, context=None)\n--\n\n\
-Return the digit-wise 'exclusive or' of the two (logical) operands.\n\
-\n");
-
-PyDoc_STRVAR(doc_max,
-"max($self, /, other, context=None)\n--\n\n\
-Maximum of self and other.  If one operand is a quiet NaN and the other is\n\
-numeric, the numeric operand is returned.\n\
-\n");
-
-PyDoc_STRVAR(doc_max_mag,
-"max_mag($self, /, other, context=None)\n--\n\n\
-Similar to the max() method, but the comparison is done using the absolute\n\
-values of the operands.\n\
-\n");
-
-PyDoc_STRVAR(doc_min,
-"min($self, /, other, context=None)\n--\n\n\
-Minimum of self and other. If one operand is a quiet NaN and the other is\n\
-numeric, the numeric operand is returned.\n\
-\n");
-
-PyDoc_STRVAR(doc_min_mag,
-"min_mag($self, /, other, context=None)\n--\n\n\
-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\
-operand in the direction of the second operand.  If both operands are\n\
-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\
-self % other in that the sign of the remainder is chosen so as to minimize\n\
-its absolute value. More precisely, the return value is self - n * other\n\
-where n is the integer nearest to the exact value of self / other, and\n\
-if two integers are equally near then the even one is chosen.\n\
-\n\
-If the result is zero then its sign will be the sign of self.\n\
-\n");
-
-PyDoc_STRVAR(doc_rotate,
-"rotate($self, /, other, context=None)\n--\n\n\
-Return the result of rotating the digits of the first operand by an amount\n\
-specified by the second operand.  The second operand must be an integer in\n\
-the range -precision through precision. The absolute value of the second\n\
-operand gives the number of places to rotate. If the second operand is\n\
-positive then rotation is to the left; otherwise rotation is to the right.\n\
-The coefficient of the first operand is padded on the left with zeros to\n\
-length precision if necessary. The sign and exponent of the first operand are\n\
-unchanged.\n\
-\n");
-
-PyDoc_STRVAR(doc_scaleb,
-"scaleb($self, /, other, context=None)\n--\n\n\
-Return the first operand with the exponent adjusted the second.  Equivalently,\n\
-return the first operand multiplied by 10**other. The second operand must be\n\
-an integer.\n\
-\n");
-
-PyDoc_STRVAR(doc_shift,
-"shift($self, /, other, context=None)\n--\n\n\
-Return the result of shifting the digits of the first operand by an amount\n\
-specified by the second operand.  The second operand must be an integer in\n\
-the range -precision through precision. The absolute value of the second\n\
-operand gives the number of places to shift. If the second operand is\n\
-positive, then the shift is to the left; otherwise the shift is to the\n\
-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                           */
 /******************************************************************************/