]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-73487: Convert `_decimal` to use Argument Clinic (part 7) (#138221)
authorSergey B Kirpichev <skirpichev@gmail.com>
Thu, 18 Sep 2025 14:08:27 +0000 (17:08 +0300)
committerGitHub <noreply@github.com>
Thu, 18 Sep 2025 14:08:27 +0000 (16:08 +0200)
Use "defining class" converter, where possible.

Modules/_decimal/_decimal.c
Modules/_decimal/clinic/_decimal.c.h

index 50994be2968d35b6b72ec2bdbe935fda2f9b5380..0696c150cd42fb34a6b31f29dd74ca119d2a84e1 100644 (file)
@@ -1007,16 +1007,19 @@ context_setemax(PyObject *self, PyObject *value, void *Py_UNUSED(closure))
 }
 
 #ifdef CONFIG_32
+/*[clinic input]
+_decimal.Context._unsafe_setprec
+
+    x: Py_ssize_t
+    /
+
+[clinic start generated code]*/
+
 static PyObject *
-context_unsafe_setprec(PyObject *self, PyObject *value)
+_decimal_Context__unsafe_setprec_impl(PyObject *self, Py_ssize_t x)
+/*[clinic end generated code: output=dd838edf08e12dd9 input=23a1b19ceb1569be]*/
 {
     mpd_context_t *ctx = CTX(self);
-    mpd_ssize_t x;
-
-    x = PyLong_AsSsize_t(value);
-    if (x == -1 && PyErr_Occurred()) {
-        return NULL;
-    }
 
     if (x < 1 || x > 1070000000L) {
         return value_error_ptr(
@@ -1027,16 +1030,19 @@ context_unsafe_setprec(PyObject *self, PyObject *value)
     Py_RETURN_NONE;
 }
 
+/*[clinic input]
+_decimal.Context._unsafe_setemin
+
+    x: Py_ssize_t
+    /
+
+[clinic start generated code]*/
+
 static PyObject *
-context_unsafe_setemin(PyObject *self, PyObject *value)
+_decimal_Context__unsafe_setemin_impl(PyObject *self, Py_ssize_t x)
+/*[clinic end generated code: output=0c49cafee8a65846 input=652f1ecacca7e0ce]*/
 {
     mpd_context_t *ctx = CTX(self);
-    mpd_ssize_t x;
-
-    x = PyLong_AsSsize_t(value);
-    if (x == -1 && PyErr_Occurred()) {
-        return NULL;
-    }
 
     if (x < -1070000000L || x > 0) {
         return value_error_ptr(
@@ -1047,16 +1053,19 @@ context_unsafe_setemin(PyObject *self, PyObject *value)
     Py_RETURN_NONE;
 }
 
+/*[clinic input]
+_decimal.Context._unsafe_setemax
+
+    x: Py_ssize_t
+    /
+
+[clinic start generated code]*/
+
 static PyObject *
-context_unsafe_setemax(PyObject *self, PyObject *value)
+_decimal_Context__unsafe_setemax_impl(PyObject *self, Py_ssize_t x)
+/*[clinic end generated code: output=776563e0377a00e8 input=b2a32a9a2750e7a8]*/
 {
     mpd_context_t *ctx = CTX(self);
-    mpd_ssize_t x;
-
-    x = PyLong_AsSsize_t(value);
-    if (x == -1 && PyErr_Occurred()) {
-        return NULL;
-    }
 
     if (x < 0 || x > 1070000000L) {
         return value_error_ptr(
@@ -1641,45 +1650,68 @@ error:
     return NULL;
 }
 
-/*[clinic input]
-_decimal.Context.copy
-
-Return a duplicate of the context with all flags cleared.
-[clinic start generated code]*/
-
 static PyObject *
-_decimal_Context_copy_impl(PyObject *self)
-/*[clinic end generated code: output=f99649a60a9c10f8 input=2589aa46b77cbc28]*/
+context_copy(decimal_state *state, PyObject *v)
 {
-    PyObject *copy;
+    PyObject *copy =
+        PyObject_CallObject((PyObject *)state->PyDecContext_Type, NULL);
 
-    decimal_state *state = get_module_state_from_ctx(self);
-    copy = PyObject_CallObject((PyObject *)state->PyDecContext_Type, NULL);
     if (copy == NULL) {
         return NULL;
     }
 
-    *CTX(copy) = *CTX(self);
+    *CTX(copy) = *CTX(v);
     CTX(copy)->newtrap = 0;
-    CtxCaps(copy) = CtxCaps(self);
+    CtxCaps(copy) = CtxCaps(v);
 
     return copy;
 }
 
+/*[clinic input]
+_decimal.Context.copy
+
+    cls: defining_class
+
+Return a duplicate of the context with all flags cleared.
+[clinic start generated code]*/
+
+static PyObject *
+_decimal_Context_copy_impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=31c9c8eeb0c0cf77 input=aef1c0bddabdf8f0]*/
+{
+    decimal_state *state = PyType_GetModuleState(cls);
+
+    return context_copy(state, self);
+}
+
+/*[clinic input]
+_decimal.Context.__copy__ = _decimal.Context.copy
+
+[clinic start generated code]*/
+
 static PyObject *
-context_copy(PyObject *self, PyObject *Py_UNUSED(dummy))
+_decimal_Context___copy___impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=93552486e5fb0ab4 input=4a55dd22f6d31bcc]*/
 {
-    return _decimal_Context_copy_impl(self);
+    decimal_state *state = PyType_GetModuleState(cls);
+
+    return context_copy(state, self);
 }
 
+/*[clinic input]
+_decimal.Context.__reduce__ = _decimal.Context.copy
+
+[clinic start generated code]*/
+
 static PyObject *
-context_reduce(PyObject *self, PyObject *Py_UNUSED(dummy))
+_decimal_Context___reduce___impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=4e77de55efdbb56a input=787683f13d047ce8]*/
 {
     PyObject *flags;
     PyObject *traps;
     PyObject *ret;
     mpd_context_t *ctx;
-    decimal_state *state = get_module_state_from_ctx(self);
+    decimal_state *state = PyType_GetModuleState(cls);
 
     ctx = CTX(self);
 
@@ -1782,7 +1814,7 @@ current_context_from_dict(decimal_state *modstate)
         }
 
         /* Set up a new thread local context. */
-        tl_context = context_copy(modstate->default_context_template, NULL);
+        tl_context = context_copy(modstate, modstate->default_context_template);
         if (tl_context == NULL) {
             return NULL;
         }
@@ -1858,7 +1890,7 @@ PyDec_SetCurrentContext(PyObject *self, PyObject *v)
     if (v == state->default_context_template ||
         v == state->basic_context_template ||
         v == state->extended_context_template) {
-        v = context_copy(v, NULL);
+        v = context_copy(state, v);
         if (v == NULL) {
             return NULL;
         }
@@ -1881,7 +1913,7 @@ PyDec_SetCurrentContext(PyObject *self, PyObject *v)
 static PyObject *
 init_current_context(decimal_state *state)
 {
-    PyObject *tl_context = context_copy(state->default_context_template, NULL);
+    PyObject *tl_context = context_copy(state, state->default_context_template);
     if (tl_context == NULL) {
         return NULL;
     }
@@ -1942,7 +1974,7 @@ PyDec_SetCurrentContext(PyObject *self, PyObject *v)
     if (v == state->default_context_template ||
         v == state->basic_context_template ||
         v == state->extended_context_template) {
-        v = context_copy(v, NULL);
+        v = context_copy(state, v);
         if (v == NULL) {
             return NULL;
         }
@@ -2039,7 +2071,7 @@ _decimal_localcontext_impl(PyObject *module, PyObject *local, PyObject *prec,
         return NULL;
     }
 
-    PyObject *local_copy = context_copy(local, NULL);
+    PyObject *local_copy = context_copy(state, local);
     if (local_copy == NULL) {
         return NULL;
     }
@@ -2964,6 +2996,7 @@ PyDecType_FromSequenceExact(PyTypeObject *type, PyObject *v,
 @classmethod
 _decimal.Decimal.from_float
 
+    cls: defining_class
     f as pyfloat: object
     /
 
@@ -2983,13 +3016,14 @@ Decimal.from_float(0.1) is not the same as Decimal('0.1').
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_from_float_impl(PyTypeObject *type, PyObject *pyfloat)
-/*[clinic end generated code: output=e62775271ac469e6 input=052036648342f8c8]*/
+_decimal_Decimal_from_float_impl(PyTypeObject *type, PyTypeObject *cls,
+                                 PyObject *pyfloat)
+/*[clinic end generated code: output=fcb7d55d2f9dc790 input=03bc8dbe963e52ca]*/
 {
     PyObject *context;
     PyObject *result;
 
-    decimal_state *state = get_module_state_by_def(type);
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
     result = PyDecType_FromFloatExact(state->PyDec_Type, pyfloat, context);
     if (type != state->PyDec_Type && result != NULL) {
@@ -3004,9 +3038,10 @@ _decimal_Decimal_from_float_impl(PyTypeObject *type, PyObject *pyfloat)
    an exact conversion. If the result does not meet the restrictions
    for an mpd_t, fail with InvalidOperation. */
 static PyObject *
-PyDecType_FromNumberExact(PyTypeObject *type, PyObject *v, PyObject *context)
+PyDecType_FromNumberExact(PyTypeObject *type, PyTypeObject *cls,
+                          PyObject *v, PyObject *context)
 {
-    decimal_state *state = get_module_state_by_def(type);
+    decimal_state *state = PyType_GetModuleState(cls);
     assert(v != NULL);
     if (PyDec_Check(state, v)) {
         return PyDecType_FromDecimalExact(type, v, context);
@@ -3032,6 +3067,7 @@ PyDecType_FromNumberExact(PyTypeObject *type, PyObject *v, PyObject *context)
 @classmethod
 _decimal.Decimal.from_number
 
+    cls: defining_class
     number: object
     /
 
@@ -3046,15 +3082,16 @@ Class method that converts a real number to a decimal number, exactly.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_from_number_impl(PyTypeObject *type, PyObject *number)
-/*[clinic end generated code: output=41885304e5beea0a input=c58b678e8916f66b]*/
+_decimal_Decimal_from_number_impl(PyTypeObject *type, PyTypeObject *cls,
+                                  PyObject *number)
+/*[clinic end generated code: output=4d3ec722b7acfd8b input=271cb4feb3148804]*/
 {
     PyObject *context;
     PyObject *result;
 
-    decimal_state *state = get_module_state_by_def(type);
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
-    result = PyDecType_FromNumberExact(state->PyDec_Type, number, context);
+    result = PyDecType_FromNumberExact(state->PyDec_Type, cls, number, context);
     if (type != state->PyDec_Type && result != NULL) {
         Py_SETREF(result,
             PyObject_CallFunctionObjArgs((PyObject *)type, result, NULL));
@@ -3069,6 +3106,7 @@ _decimal_Decimal_from_number_impl(PyTypeObject *type, PyObject *number)
 _decimal.Context.create_decimal_from_float
 
     self as context: self
+    cls: defining_class
     f: object
     /
 
@@ -3079,10 +3117,12 @@ the context limits.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_create_decimal_from_float(PyObject *context, PyObject *f)
-/*[clinic end generated code: output=c660c343f6f7158b input=05a8c54b7a5b457b]*/
+_decimal_Context_create_decimal_from_float_impl(PyObject *context,
+                                                PyTypeObject *cls,
+                                                PyObject *f)
+/*[clinic end generated code: output=a5548f5140fa0870 input=8c66eeb22b01ddd4]*/
 {
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     return PyDec_FromFloat(state, f, context);
 }
 
@@ -3688,6 +3728,7 @@ pydec_format(PyObject *dec, PyObject *context, PyObject *fmt, decimal_state *sta
 _decimal.Decimal.__format__
 
     self as dec: self
+    cls: defining_class
     format_spec as fmtarg: unicode
     override: object = NULL
     /
@@ -3696,9 +3737,9 @@ Formats the Decimal according to format_spec.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal___format___impl(PyObject *dec, PyObject *fmtarg,
-                                 PyObject *override)
-/*[clinic end generated code: output=4b3640b7f0c8b6a5 input=e53488e49a0fff00]*/
+_decimal_Decimal___format___impl(PyObject *dec, PyTypeObject *cls,
+                                 PyObject *fmtarg, PyObject *override)
+/*[clinic end generated code: output=6d95f91bbb28b3ed input=2dbfaa0cbe243e9e]*/
 {
     PyObject *result = NULL;
     PyObject *dot = NULL;
@@ -3711,7 +3752,7 @@ _decimal_Decimal___format___impl(PyObject *dec, PyObject *fmtarg,
     uint32_t status = 0;
     int replace_fillchar = 0;
     Py_ssize_t size;
-    decimal_state *state = get_module_state_by_def(Py_TYPE(dec));
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
     fmt = (char *)PyUnicode_AsUTF8AndSize(fmtarg, &size);
     if (fmt == NULL) {
@@ -3915,6 +3956,8 @@ dec_as_long(PyObject *dec, PyObject *context, int round)
 /*[clinic input]
 _decimal.Decimal.as_integer_ratio
 
+    cls: defining_class
+
 Return a pair of integers whose ratio is exactly equal to the original.
 
 The ratio is in lowest terms and with a positive denominator.
@@ -3922,8 +3965,8 @@ Raise OverflowError on infinities and a ValueError on NaNs.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_as_integer_ratio_impl(PyObject *self)
-/*[clinic end generated code: output=c5d88e900080c264 input=7861cb643f01525a]*/
+_decimal_Decimal_as_integer_ratio_impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=eb49c512701f844b input=07e33d8852184761]*/
 {
     PyObject *numerator = NULL;
     PyObject *denominator = NULL;
@@ -3946,7 +3989,7 @@ _decimal_Decimal_as_integer_ratio_impl(PyObject *self)
         return NULL;
     }
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
 
     tmp = dec_alloc(state);
@@ -4028,6 +4071,7 @@ error:
 /*[clinic input]
 _decimal.Decimal.to_integral_value
 
+    cls: defining_class
     rounding: object = None
     context: object = None
 
@@ -4039,15 +4083,16 @@ rounding mode of the current default context is used.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_to_integral_value_impl(PyObject *self, PyObject *rounding,
+_decimal_Decimal_to_integral_value_impl(PyObject *self, PyTypeObject *cls,
+                                        PyObject *rounding,
                                         PyObject *context)
-/*[clinic end generated code: output=7301465765f48b6b input=04e2312d5ed19f77]*/
+/*[clinic end generated code: output=23047d848ef84db1 input=85aa9499a21ea8d7]*/
 {
     PyObject *result;
     uint32_t status = 0;
     mpd_context_t workctx;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CONTEXT_CHECK_VA(state, context);
 
     workctx = *CTX(context);
@@ -4085,11 +4130,12 @@ versions.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_to_integral_impl(PyObject *self, PyObject *rounding,
-                                  PyObject *context)
-/*[clinic end generated code: output=a0c7188686ee7f5c input=709b54618ecd0d8b]*/
+_decimal_Decimal_to_integral_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *rounding, PyObject *context)
+/*[clinic end generated code: output=5dac8f54c2a3ed26 input=709b54618ecd0d8b]*/
 {
-    return _decimal_Decimal_to_integral_value_impl(self, rounding, context);
+    return _decimal_Decimal_to_integral_value_impl(self, cls, rounding,
+                                                   context);
 }
 
 /*[clinic input]
@@ -4104,15 +4150,16 @@ given, then the rounding mode of the current default context is used.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_to_integral_exact_impl(PyObject *self, PyObject *rounding,
+_decimal_Decimal_to_integral_exact_impl(PyObject *self, PyTypeObject *cls,
+                                        PyObject *rounding,
                                         PyObject *context)
-/*[clinic end generated code: output=8b004f9b45ac7746 input=fabce7a744b8087c]*/
+/*[clinic end generated code: output=543a39a02eea9917 input=fabce7a744b8087c]*/
 {
     PyObject *result;
     uint32_t status = 0;
     mpd_context_t workctx;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CONTEXT_CHECK_VA(state, context);
 
     workctx = *CTX(context);
@@ -4175,6 +4222,7 @@ PyDec_AsFloat(PyObject *dec)
 /*[clinic input]
 _decimal.Decimal.__round__
 
+    cls: defining_class
     ndigits: object = NULL
     /
 
@@ -4182,13 +4230,14 @@ Return the Integral closest to self, rounding half toward even.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal___round___impl(PyObject *self, PyObject *ndigits)
-/*[clinic end generated code: output=ca6b3570a8df0c91 input=dc72084114f59380]*/
+_decimal_Decimal___round___impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *ndigits)
+/*[clinic end generated code: output=790c2c6bd57890e6 input=d69e7178a58a66b1]*/
 {
     PyObject *result;
     uint32_t status = 0;
     PyObject *context;
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
     if (ndigits) {
         mpd_uint_t dq[1] = {1};
@@ -4227,12 +4276,14 @@ _decimal_Decimal___round___impl(PyObject *self, PyObject *ndigits)
 /*[clinic input]
 _decimal.Decimal.as_tuple
 
+    cls: defining_class
+
 Return a tuple representation of the number.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_as_tuple_impl(PyObject *self)
-/*[clinic end generated code: output=c6e8e2420c515eca input=e26f2151d78ff59d]*/
+_decimal_Decimal_as_tuple_impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=d68b967becee8ab9 input=bfa86d640224d9f5]*/
 {
     PyObject *result = NULL;
     PyObject *sign = NULL;
@@ -4312,7 +4363,7 @@ _decimal_Decimal_as_tuple_impl(PyObject *self)
         }
     }
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     result = PyObject_CallFunctionObjArgs((PyObject *)state->DecimalTuple,
                                           sign, coeff, expt, NULL);
 
@@ -4364,7 +4415,7 @@ nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
     PyObject *context;                                           \
     uint32_t status = 0;                                         \
                                                                  \
-    decimal_state *state = find_state_left_or_right(self, other);  \
+    decimal_state *state = find_state_left_or_right(self, other); \
     CURRENT_CONTEXT(state, context) ;                            \
     CONVERT_BINOP(&a, &b, self, other, context);                 \
                                                                  \
@@ -4394,25 +4445,26 @@ nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
 }
 
 /* Boolean function with an optional context arg.
-   Argument Clinic provides PyObject *self, PyObject *context
+   Argument Clinic provides PyObject *self, PyTypeObject *cls,
+                            PyObject *context
 */
 #define Dec_BoolFuncVA(MPDFUNC) \
 {                                                                         \
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));        \
+    decimal_state *state = PyType_GetModuleState(cls);                    \
     CONTEXT_CHECK_VA(state, context);                                     \
                                                                           \
     return MPDFUNC(MPD(self), CTX(context)) ? incr_true() : incr_false(); \
 }
 
 /* Unary function with an optional context arg.
-   Argument Clinic provides PyObject *self, PyObject *context
+   Argument Clinic provides PyObject *self, PyTypeObject *cls,
+                            PyObject *context
 */
 #define Dec_UnaryFuncVA(MPDFUNC) \
 {                                                              \
     PyObject *result;                                          \
     uint32_t status = 0;                                       \
-    decimal_state *state =                                     \
-        get_module_state_by_def(Py_TYPE(self));                \
+    decimal_state *state = PyType_GetModuleState(cls);         \
     CONTEXT_CHECK_VA(state, context);                          \
                                                                \
     if ((result = dec_alloc(state)) == NULL) {                 \
@@ -4429,15 +4481,15 @@ nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
 }
 
 /* Binary function with an optional context arg.
-   Argument Clinic provides PyObject *self, PyObject *other, PyObject *context
+   Argument Clinic provides PyObject *self, PyTypeObject *cls,
+                            PyObject *other, PyObject *context
 */
 #define Dec_BinaryFuncVA(MPDFUNC) \
 {                                                                \
     PyObject *a, *b;                                             \
     PyObject *result;                                            \
     uint32_t status = 0;                                         \
-    decimal_state *state =                                       \
-        get_module_state_by_def(Py_TYPE(self));                  \
+    decimal_state *state = PyType_GetModuleState(cls);           \
     CONTEXT_CHECK_VA(state, context);                            \
     CONVERT_BINOP_RAISE(&a, &b, self, other, context);           \
                                                                  \
@@ -4462,14 +4514,14 @@ nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
    NOT take a context. The context is used to record InvalidOperation
    if the second operand cannot be converted exactly.
 
-   Argument Clinic provides PyObject *self, PyObject *other, PyObject *context
+   Argument Clinic provides PyObject *self, PyTypeObject *cls,
+                            PyObject *other, PyObject *context
 */
 #define Dec_BinaryFuncVA_NO_CTX(MPDFUNC) \
 {                                                               \
     PyObject *a, *b;                                            \
     PyObject *result;                                           \
-    decimal_state *state =                                      \
-        get_module_state_by_def(Py_TYPE(self));                 \
+    decimal_state *state = PyType_GetModuleState(cls);          \
     CONTEXT_CHECK_VA(state, context);                           \
     CONVERT_BINOP_RAISE(&a, &b, self, other, context);          \
                                                                 \
@@ -4487,7 +4539,8 @@ nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
 }
 
 /* Ternary function with an optional context arg.
-   Argument Clinic provides PyObject *self, PyObject *other, PyObject *third,
+   Argument Clinic provides PyObject *self, PyTypeObject *cls,
+                            PyObject *other, PyObject *third,
                             PyObject *context
 */
 #define Dec_TernaryFuncVA(MPDFUNC) \
@@ -4495,7 +4548,7 @@ nm_##MPDFUNC(PyObject *self, PyObject *other)                    \
     PyObject *a, *b, *c;                                                 \
     PyObject *result;                                                    \
     uint32_t status = 0;                                                 \
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));       \
+    decimal_state *state = PyType_GetModuleState(cls);                   \
     CONTEXT_CHECK_VA(state, context);                                    \
     CONVERT_TERNOP_RAISE(&a, &b, &c, self, other, third, context);       \
                                                                          \
@@ -4648,6 +4701,7 @@ nm_mpd_qpow(PyObject *base, PyObject *exp, PyObject *mod)
 /*[clinic input]
 _decimal.Decimal.exp
 
+    cls: defining_class
     context: object = None
 
 Return the value of the (natural) exponential function e**x.
@@ -4657,8 +4711,9 @@ correctly rounded.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_exp_impl(PyObject *self, PyObject *context)
-/*[clinic end generated code: output=c0833b6e9b8c836f input=274784af925e60c9]*/
+_decimal_Decimal_exp_impl(PyObject *self, PyTypeObject *cls,
+                          PyObject *context)
+/*[clinic end generated code: output=40317012aedbaeac input=84919aad3dabda08]*/
 Dec_UnaryFuncVA(mpd_qexp)
 
 /*[clinic input]
@@ -4671,8 +4726,9 @@ correctly rounded.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_ln_impl(PyObject *self, PyObject *context)
-/*[clinic end generated code: output=5191f4ef739b04b0 input=d353c51ec00d1cff]*/
+_decimal_Decimal_ln_impl(PyObject *self, PyTypeObject *cls,
+                         PyObject *context)
+/*[clinic end generated code: output=e8f9e81cac38e5dc input=d353c51ec00d1cff]*/
 Dec_UnaryFuncVA(mpd_qln)
 
 /*[clinic input]
@@ -4685,8 +4741,9 @@ correctly rounded.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_log10_impl(PyObject *self, PyObject *context)
-/*[clinic end generated code: output=d5da63df75900275 input=48a6be60154c0b46]*/
+_decimal_Decimal_log10_impl(PyObject *self, PyTypeObject *cls,
+                            PyObject *context)
+/*[clinic end generated code: output=00b3255648135c95 input=48a6be60154c0b46]*/
 Dec_UnaryFuncVA(mpd_qlog10)
 
 /*[clinic input]
@@ -4696,8 +4753,9 @@ 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]*/
+_decimal_Decimal_next_minus_impl(PyObject *self, PyTypeObject *cls,
+                                 PyObject *context)
+/*[clinic end generated code: output=a187a55e6976b572 input=666b348f71e6c090]*/
 Dec_UnaryFuncVA(mpd_qnext_minus)
 
 /*[clinic input]
@@ -4707,8 +4765,9 @@ 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]*/
+_decimal_Decimal_next_plus_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *context)
+/*[clinic end generated code: output=13737d41714e320e input=04e105060ad1fa15]*/
 Dec_UnaryFuncVA(mpd_qnext_plus)
 
 /*[clinic input]
@@ -4723,8 +4782,9 @@ 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]*/
+_decimal_Decimal_normalize_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *context)
+/*[clinic end generated code: output=32c4c0d13fe33fb9 input=d5ee63acd904d4de]*/
 Dec_UnaryFuncVA(mpd_qreduce)
 
 /*[clinic input]
@@ -4736,8 +4796,9 @@ 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]*/
+_decimal_Decimal_sqrt_impl(PyObject *self, PyTypeObject *cls,
+                           PyObject *context)
+/*[clinic end generated code: output=deb1280077b5e586 input=3a76afbd39dc20b9]*/
 Dec_UnaryFuncVA(mpd_qsqrt)
 
 /* Binary arithmetic functions, optional context arg */
@@ -4745,6 +4806,7 @@ Dec_UnaryFuncVA(mpd_qsqrt)
 /*[clinic input]
 _decimal.Decimal.compare
 
+    cls: defining_class
     other: object
     context: object = None
 
@@ -4759,9 +4821,9 @@ Return a decimal value:
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_compare_impl(PyObject *self, PyObject *other,
-                              PyObject *context)
-/*[clinic end generated code: output=d6967aa3578b9d48 input=1b7b75a2a154e520]*/
+_decimal_Decimal_compare_impl(PyObject *self, PyTypeObject *cls,
+                              PyObject *other, PyObject *context)
+/*[clinic end generated code: output=a4a1d383ec192cfa input=d18a02bb8083e92a]*/
 Dec_BinaryFuncVA(mpd_qcompare)
 
 /*[clinic input]
@@ -4771,9 +4833,9 @@ 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]*/
+_decimal_Decimal_compare_signal_impl(PyObject *self, PyTypeObject *cls,
+                                     PyObject *other, PyObject *context)
+/*[clinic end generated code: output=22f757371fd4167b input=a52a39d1c6fc369d]*/
 Dec_BinaryFuncVA(mpd_qcompare_signal)
 
 /*[clinic input]
@@ -4786,8 +4848,9 @@ 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]*/
+_decimal_Decimal_max_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
+                          PyObject *context)
+/*[clinic end generated code: output=d3d12db9815869e5 input=2ae2582f551296d8]*/
 Dec_BinaryFuncVA(mpd_qmax)
 
 /*[clinic input]
@@ -4797,9 +4860,9 @@ 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]*/
+_decimal_Decimal_max_mag_impl(PyObject *self, PyTypeObject *cls,
+                              PyObject *other, PyObject *context)
+/*[clinic end generated code: output=f71f2c27d9bc7cac input=88b105e66cf138c5]*/
 Dec_BinaryFuncVA(mpd_qmax_mag)
 
 /*[clinic input]
@@ -4812,8 +4875,9 @@ 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]*/
+_decimal_Decimal_min_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
+                          PyObject *context)
+/*[clinic end generated code: output=c5620344ae5f3dd1 input=2a70f2c087c418c9]*/
 Dec_BinaryFuncVA(mpd_qmin)
 
 /*[clinic input]
@@ -4823,9 +4887,9 @@ 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]*/
+_decimal_Decimal_min_mag_impl(PyObject *self, PyTypeObject *cls,
+                              PyObject *other, PyObject *context)
+/*[clinic end generated code: output=018562ad1c22aae3 input=351fa3c0e592746a]*/
 Dec_BinaryFuncVA(mpd_qmin_mag)
 
 /*[clinic input]
@@ -4840,9 +4904,9 @@ 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]*/
+_decimal_Decimal_next_toward_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *other, PyObject *context)
+/*[clinic end generated code: output=71d879bca8bc1019 input=fdf0091ea6e9e416]*/
 Dec_BinaryFuncVA(mpd_qnext_toward)
 
 /*[clinic input]
@@ -4860,9 +4924,9 @@ 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]*/
+_decimal_Decimal_remainder_near_impl(PyObject *self, PyTypeObject *cls,
+                                     PyObject *other, PyObject *context)
+/*[clinic end generated code: output=d3fbb4985f2077fa input=eb5a8dfe3470b794]*/
 Dec_BinaryFuncVA(mpd_qrem_near)
 
 /* Ternary arithmetic functions, optional context arg */
@@ -4870,6 +4934,7 @@ Dec_BinaryFuncVA(mpd_qrem_near)
 /*[clinic input]
 _decimal.Decimal.fma
 
+    cls: defining_class
     other: object
     third: object
     context: object = None
@@ -4884,9 +4949,9 @@ self*other.
 [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]*/
+_decimal_Decimal_fma_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
+                          PyObject *third, PyObject *context)
+/*[clinic end generated code: output=db49a777e85b71e4 input=2104c001f6077c35]*/
 Dec_TernaryFuncVA(mpd_qfma)
 
 /* Boolean functions, no context arg */
@@ -4995,8 +5060,9 @@ 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]*/
+_decimal_Decimal_is_normal_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *context)
+/*[clinic end generated code: output=92a3878e293758d4 input=9afe43b9db9f4818]*/
 Dec_BoolFuncVA(mpd_isnormal)
 
 /*[clinic input]
@@ -5009,8 +5075,9 @@ 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]*/
+_decimal_Decimal_is_subnormal_impl(PyObject *self, PyTypeObject *cls,
+                                   PyObject *context)
+/*[clinic end generated code: output=1404c04d980ebc07 input=11839c122c185b8b]*/
 Dec_BoolFuncVA(mpd_issubnormal)
 
 /* Unary functions, no context arg */
@@ -5083,6 +5150,8 @@ _dec_mpd_radix(decimal_state *state)
 /*[clinic input]
 _decimal.Decimal.radix
 
+    cls: defining_class
+
 Return Decimal(10).
 
 This is the radix (base) in which the Decimal class does
@@ -5090,16 +5159,18 @@ all its arithmetic. Included for compatibility with the specification.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_radix_impl(PyObject *self)
-/*[clinic end generated code: output=6b1db4c3fcdb5ee1 input=18b72393549ca8fd]*/
+_decimal_Decimal_radix_impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=40a3bc7ec3d99228 input=b0d4cb9f870bbac1]*/
 {
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     return _dec_mpd_radix(state);
 }
 
 /*[clinic input]
 _decimal.Decimal.copy_abs
 
+    cls: defining_class
+
 Return the absolute value of the argument.
 
 This operation is unaffected by context and is quiet: no flags are
@@ -5107,13 +5178,13 @@ changed and no rounding is performed.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_copy_abs_impl(PyObject *self)
-/*[clinic end generated code: output=fff53742cca94d70 input=a263c2e71d421f1b]*/
+_decimal_Decimal_copy_abs_impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=081cb7fb4230676e input=676d7c62b1795512]*/
 {
     PyObject *result;
     uint32_t status = 0;
+    decimal_state *state = PyType_GetModuleState(cls);
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
     if ((result = dec_alloc(state)) == NULL) {
         return NULL;
     }
@@ -5129,7 +5200,7 @@ _decimal_Decimal_copy_abs_impl(PyObject *self)
 }
 
 /*[clinic input]
-_decimal.Decimal.copy_negate
+_decimal.Decimal.copy_negate = _decimal.Decimal.copy_abs
 
 Return the negation of the argument.
 
@@ -5138,13 +5209,13 @@ changed and no rounding is performed.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_copy_negate_impl(PyObject *self)
-/*[clinic end generated code: output=8551bc26dbc5d01d input=13d47ed3a5d228b1]*/
+_decimal_Decimal_copy_negate_impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=04fed82c17d4e28b input=23f41ee8899f3891]*/
 {
     PyObject *result;
     uint32_t status = 0;
+    decimal_state *state = PyType_GetModuleState(cls);
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
     if ((result = dec_alloc(state)) == NULL) {
         return NULL;
     }
@@ -5168,8 +5239,9 @@ 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]*/
+_decimal_Decimal_logical_invert_impl(PyObject *self, PyTypeObject *cls,
+                                     PyObject *context)
+/*[clinic end generated code: output=c626ed4b104a97b7 input=3531dac8b9548dad]*/
 Dec_UnaryFuncVA(mpd_qinvert)
 
 /*[clinic input]
@@ -5183,8 +5255,9 @@ 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]*/
+_decimal_Decimal_logb_impl(PyObject *self, PyTypeObject *cls,
+                           PyObject *context)
+/*[clinic end generated code: output=36b0bda09e934245 input=a8df027d1b8a2b17]*/
 Dec_UnaryFuncVA(mpd_qlogb)
 
 /*[clinic input]
@@ -5211,12 +5284,13 @@ The returned value is one of the following ten strings:
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_number_class_impl(PyObject *self, PyObject *context)
-/*[clinic end generated code: output=3044cd45966b4949 input=447095d2677fa0ca]*/
+_decimal_Decimal_number_class_impl(PyObject *self, PyTypeObject *cls,
+                                   PyObject *context)
+/*[clinic end generated code: output=1ac82412e0849c52 input=447095d2677fa0ca]*/
 {
     const char *cp;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CONTEXT_CHECK_VA(state, context);
 
     cp = mpd_class(MPD(self), CTX(context));
@@ -5238,14 +5312,15 @@ operation.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context)
-/*[clinic end generated code: output=d386194c25ffffa7 input=b2cb7e01e268e45d]*/
+_decimal_Decimal_to_eng_string_impl(PyObject *self, PyTypeObject *cls,
+                                    PyObject *context)
+/*[clinic end generated code: output=901f128d437ae5c0 input=b2cb7e01e268e45d]*/
 {
     PyObject *result;
     mpd_ssize_t size;
     char *s;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CONTEXT_CHECK_VA(state, context);
 
     size = mpd_to_eng_size(&s, MPD(self), CtxCaps(context));
@@ -5289,9 +5364,9 @@ exactly.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_compare_total_impl(PyObject *self, PyObject *other,
-                                    PyObject *context)
-/*[clinic end generated code: output=dca119b5e881a83e input=6f3111ec5fdbf3c1]*/
+_decimal_Decimal_compare_total_impl(PyObject *self, PyTypeObject *cls,
+                                    PyObject *other, PyObject *context)
+/*[clinic end generated code: output=83649010bad7815f input=6f3111ec5fdbf3c1]*/
 Dec_BinaryFuncVA_NO_CTX(mpd_compare_total)
 
 /*[clinic input]
@@ -5309,9 +5384,9 @@ exactly.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_compare_total_mag_impl(PyObject *self, PyObject *other,
-                                        PyObject *context)
-/*[clinic end generated code: output=6bf1b3419112d0dd input=eba17c4c24eb2833]*/
+_decimal_Decimal_compare_total_mag_impl(PyObject *self, PyTypeObject *cls,
+                                        PyObject *other, PyObject *context)
+/*[clinic end generated code: output=b99c924cafb5f0e3 input=eba17c4c24eb2833]*/
 Dec_BinaryFuncVA_NO_CTX(mpd_compare_total_mag)
 
 /*[clinic input]
@@ -5331,15 +5406,15 @@ exactly.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other,
-                                PyObject *context)
-/*[clinic end generated code: output=72c62177763e012e input=51ed9e4691e2249e]*/
+_decimal_Decimal_copy_sign_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *other, PyObject *context)
+/*[clinic end generated code: output=e4c8f884f4d75801 input=51ed9e4691e2249e]*/
 {
     PyObject *a, *b;
     PyObject *result;
     uint32_t status = 0;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CONTEXT_CHECK_VA(state, context);
     CONVERT_BINOP_RAISE(&a, &b, self, other, context);
 
@@ -5373,14 +5448,14 @@ exactly.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other,
-                                   PyObject *context)
-/*[clinic end generated code: output=c0a3a046c662a7e2 input=8339415fa359e7df]*/
+_decimal_Decimal_same_quantum_impl(PyObject *self, PyTypeObject *cls,
+                                   PyObject *other, PyObject *context)
+/*[clinic end generated code: output=7c757edb0c263721 input=8339415fa359e7df]*/
 {
     PyObject *a, *b;
     PyObject *result;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CONTEXT_CHECK_VA(state, context);
     CONVERT_BINOP_RAISE(&a, &b, self, other, context);
 
@@ -5400,9 +5475,9 @@ 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]*/
+_decimal_Decimal_logical_and_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *other, PyObject *context)
+/*[clinic end generated code: output=9a4cbb74c180b0bb input=2b319baee8970929]*/
 Dec_BinaryFuncVA(mpd_qand)
 
 /*[clinic input]
@@ -5412,9 +5487,9 @@ 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]*/
+_decimal_Decimal_logical_or_impl(PyObject *self, PyTypeObject *cls,
+                                 PyObject *other, PyObject *context)
+/*[clinic end generated code: output=063c4de18dc41ecb input=75e0e1d4dd373b90]*/
 Dec_BinaryFuncVA(mpd_qor)
 
 /*[clinic input]
@@ -5424,9 +5499,9 @@ 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]*/
+_decimal_Decimal_logical_xor_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *other, PyObject *context)
+/*[clinic end generated code: output=829b09cb49926ad7 input=a1ed8d6ac38c1c9e]*/
 Dec_BinaryFuncVA(mpd_qxor)
 
 /*[clinic input]
@@ -5443,9 +5518,9 @@ 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]*/
+_decimal_Decimal_rotate_impl(PyObject *self, PyTypeObject *cls,
+                             PyObject *other, PyObject *context)
+/*[clinic end generated code: output=09f2737082882b83 input=cde7b032eac43f0b]*/
 Dec_BinaryFuncVA(mpd_qrotate)
 
 /*[clinic input]
@@ -5458,9 +5533,9 @@ 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]*/
+_decimal_Decimal_scaleb_impl(PyObject *self, PyTypeObject *cls,
+                             PyObject *other, PyObject *context)
+/*[clinic end generated code: output=ae8730536c9f2d30 input=7f29f83278d05f83]*/
 Dec_BinaryFuncVA(mpd_qscaleb)
 
 /*[clinic input]
@@ -5477,14 +5552,15 @@ 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]*/
+_decimal_Decimal_shift_impl(PyObject *self, PyTypeObject *cls,
+                            PyObject *other, PyObject *context)
+/*[clinic end generated code: output=82e061a0d9ecc4f5 input=501759c2522cb78e]*/
 Dec_BinaryFuncVA(mpd_qshift)
 
 /*[clinic input]
 _decimal.Decimal.quantize
 
+    cls: defining_class
     exp as w: object
     rounding: object = None
     context: object = None
@@ -5514,16 +5590,17 @@ current thread's context is used.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal_quantize_impl(PyObject *self, PyObject *w,
-                               PyObject *rounding, PyObject *context)
-/*[clinic end generated code: output=5e84581f96dc685c input=4c7d28d36948e9aa]*/
+_decimal_Decimal_quantize_impl(PyObject *self, PyTypeObject *cls,
+                               PyObject *w, PyObject *rounding,
+                               PyObject *context)
+/*[clinic end generated code: output=fc51edf458559913 input=1166e6311e047b74]*/
 {
     PyObject *a, *b;
     PyObject *result;
     uint32_t status = 0;
     mpd_context_t workctx;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CONTEXT_CHECK_VA(state, context);
 
     workctx = *CTX(context);
@@ -5620,16 +5697,18 @@ dec_richcompare(PyObject *v, PyObject *w, int op)
 /*[clinic input]
 _decimal.Decimal.__ceil__
 
+    cls: defining_class
+
 Return the ceiling as an Integral.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal___ceil___impl(PyObject *self)
-/*[clinic end generated code: output=e755a6fb7bceac19 input=4a18ef307ac57da0]*/
+_decimal_Decimal___ceil___impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=d986ebf9aadbf9fe input=a8e0b87897706816]*/
 {
     PyObject *context;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
     return dec_as_long(self, context, MPD_ROUND_CEILING);
 }
@@ -5689,18 +5768,18 @@ _decimal_Decimal___deepcopy__(PyObject *self, PyObject *memo)
 }
 
 /*[clinic input]
-_decimal.Decimal.__floor__
+_decimal.Decimal.__floor__ = _decimal.Decimal.__ceil__
 
 Return the floor as an Integral.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal___floor___impl(PyObject *self)
-/*[clinic end generated code: output=56767050ac1a1d5a input=cabcc5618564548b]*/
+_decimal_Decimal___floor___impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=e239a2f7f6514c12 input=dcc37aeceb0efb8d]*/
 {
     PyObject *context;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
     return dec_as_long(self, context, MPD_ROUND_FLOOR);
 }
@@ -5875,18 +5954,18 @@ _decimal_Decimal___sizeof___impl(PyObject *v)
 }
 
 /*[clinic input]
-_decimal.Decimal.__trunc__
+_decimal.Decimal.__trunc__ = _decimal.Decimal.__ceil__
 
 Return the Integral closest to x between 0 and x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Decimal___trunc___impl(PyObject *self)
-/*[clinic end generated code: output=9ef59578960f80c0 input=a965a61096dcefeb]*/
+_decimal_Decimal___trunc___impl(PyObject *self, PyTypeObject *cls)
+/*[clinic end generated code: output=7b3decc4b636ce32 input=9b3a3a85f63b0515]*/
 {
     PyObject *context;
 
-    decimal_state *state = get_module_state_by_def(Py_TYPE(self));
+    decimal_state *state = PyType_GetModuleState(cls);
     CURRENT_CONTEXT(state, context);
     return dec_as_long(self, context, MPD_ROUND_DOWN);
 }
@@ -6096,7 +6175,8 @@ static PyType_Spec dec_spec = {
 }
 
 /* Unary context method.
-   Argument Clinic provides PyObject *context, PyObject *x
+   Argument Clinic provides PyObject *context,
+                            PyTypeObject *cls, PyObject *x
 */
 #define DecCtx_UnaryFunc(MPDFUNC) \
 {                                                        \
@@ -6104,8 +6184,7 @@ static PyType_Spec dec_spec = {
     uint32_t status = 0;                                 \
                                                          \
     CONVERT_OP_RAISE(&a, x, context);                    \
-    decimal_state *state =                               \
-        get_module_state_from_ctx(context);              \
+    decimal_state *state = PyType_GetModuleState(cls);   \
     if ((result = dec_alloc(state)) == NULL) {           \
         Py_DECREF(a);                                    \
         return NULL;                                     \
@@ -6122,7 +6201,8 @@ static PyType_Spec dec_spec = {
 }
 
 /* Binary context method.
-   Argument Clinic provides PyObject *context, PyObject *x, PyObject *y
+   Argument Clinic provides PyObject *context, PyTypeObject *cls,
+                            PyObject *x, PyObject *y
 */
 #define DecCtx_BinaryFunc(MPDFUNC) \
 {                                                                \
@@ -6131,8 +6211,7 @@ static PyType_Spec dec_spec = {
     uint32_t status = 0;                                         \
                                                                  \
     CONVERT_BINOP_RAISE(&a, &b, x, y, context);                  \
-    decimal_state *state =                                       \
-        get_module_state_from_ctx(context);                      \
+    decimal_state *state = PyType_GetModuleState(cls);           \
     if ((result = dec_alloc(state)) == NULL) {                   \
         Py_DECREF(a);                                            \
         Py_DECREF(b);                                            \
@@ -6153,7 +6232,8 @@ static PyType_Spec dec_spec = {
 /*
  * Binary context method. The context is only used for conversion.
  * The actual MPDFUNC does NOT take a context arg.
- * Argument Clinic provides PyObject *context, PyObject *x, PyObject *y
+ * Argument Clinic provides PyObject *context, PyTypeObject *cls,
+ *                          PyObject *x, PyObject *y
  */
 #define DecCtx_BinaryFunc_NO_CTX(MPDFUNC) \
 {                                                \
@@ -6162,7 +6242,7 @@ static PyType_Spec dec_spec = {
                                                  \
     CONVERT_BINOP_RAISE(&a, &b, x, y, context);  \
     decimal_state *state =                       \
-        get_module_state_from_ctx(context);      \
+        PyType_GetModuleState(cls);              \
     if ((result = dec_alloc(state)) == NULL) {   \
         Py_DECREF(a);                            \
         Py_DECREF(b);                            \
@@ -6177,8 +6257,8 @@ static PyType_Spec dec_spec = {
 }
 
 /* Ternary context method.
-   Argument Clinic provides PyObject *context, PyObject *x, PyObject *y,
-                            PyObject *z
+   Argument Clinic provides PyObject *context, PyTypeObject *cls,
+                            PyObject *x, PyObject *y, PyObject *z
 */
 #define DecCtx_TernaryFunc(MPDFUNC) \
 {                                                                        \
@@ -6187,7 +6267,7 @@ static PyType_Spec dec_spec = {
     uint32_t status = 0;                                                 \
                                                                          \
     CONVERT_TERNOP_RAISE(&a, &b, &c, x, y, z, context);                  \
-    decimal_state *state = get_module_state_from_ctx(context);           \
+    decimal_state *state = PyType_GetModuleState(cls);                   \
     if ((result = dec_alloc(state)) == NULL) {                           \
         Py_DECREF(a);                                                    \
         Py_DECREF(b);                                                    \
@@ -6214,6 +6294,7 @@ static PyType_Spec dec_spec = {
 _decimal.Context.abs
 
     self as context: self
+    cls: defining_class
     x: object
     /
 
@@ -6221,8 +6302,8 @@ Return the absolute value of x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_abs(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=5cafb5edf96df9e4 input=8384b327e52d6723]*/
+_decimal_Context_abs_impl(PyObject *context, PyTypeObject *cls, PyObject *x)
+/*[clinic end generated code: output=fe080467d32e229c input=00a33f9c68463bb0]*/
 DecCtx_UnaryFunc(mpd_qabs)
 
 /*[clinic input]
@@ -6232,8 +6313,8 @@ Return e ** x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_exp(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=787085815e6a9aa4 input=5b443c4ab153dd2e]*/
+_decimal_Context_exp_impl(PyObject *context, PyTypeObject *cls, PyObject *x)
+/*[clinic end generated code: output=c7477a67010ccc5f input=5b443c4ab153dd2e]*/
 DecCtx_UnaryFunc(mpd_qexp)
 
 /*[clinic input]
@@ -6243,8 +6324,8 @@ Return the natural (base e) logarithm of x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_ln(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=9ecce76097f16bbe input=cf43cd98a0fe7425]*/
+_decimal_Context_ln_impl(PyObject *context, PyTypeObject *cls, PyObject *x)
+/*[clinic end generated code: output=63e691b0680bffc7 input=cf43cd98a0fe7425]*/
 DecCtx_UnaryFunc(mpd_qln)
 
 /*[clinic input]
@@ -6254,8 +6335,9 @@ Return the base 10 logarithm of x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_log10(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=08080765645630e4 input=309e57faf42c257d]*/
+_decimal_Context_log10_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x)
+/*[clinic end generated code: output=e0d9fc928570304d input=309e57faf42c257d]*/
 DecCtx_UnaryFunc(mpd_qlog10)
 
 /*[clinic input]
@@ -6267,8 +6349,9 @@ This operation applies the context to the result.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_minus(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=49c1a0d59f4585b6 input=63be4c419d1d554b]*/
+_decimal_Context_minus_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x)
+/*[clinic end generated code: output=f06c409b6aef1aad input=63be4c419d1d554b]*/
 DecCtx_UnaryFunc(mpd_qminus)
 
 /*[clinic input]
@@ -6278,8 +6361,9 @@ Return the largest representable number smaller than x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_next_minus(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=0c11a0d5fa9103d2 input=969f4d24dfcd5e85]*/
+_decimal_Context_next_minus_impl(PyObject *context, PyTypeObject *cls,
+                                 PyObject *x)
+/*[clinic end generated code: output=8dd168f08bec9547 input=969f4d24dfcd5e85]*/
 DecCtx_UnaryFunc(mpd_qnext_minus)
 
 /*[clinic input]
@@ -6289,8 +6373,9 @@ Return the smallest representable number larger than x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_next_plus(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=fd834e8c58b76031 input=af1a85ee59b56a3c]*/
+_decimal_Context_next_plus_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x)
+/*[clinic end generated code: output=2a50586ad2f7c108 input=af1a85ee59b56a3c]*/
 DecCtx_UnaryFunc(mpd_qnext_plus)
 
 /*[clinic input]
@@ -6300,8 +6385,9 @@ Reduce x to its simplest form. Alias for reduce(x).
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_normalize(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=492c6ca375bcf020 input=a65bc39c81a654a9]*/
+_decimal_Context_normalize_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x)
+/*[clinic end generated code: output=9a9510f442ba2852 input=a65bc39c81a654a9]*/
 DecCtx_UnaryFunc(mpd_qreduce)
 
 /*[clinic input]
@@ -6313,8 +6399,8 @@ This operation applies the context to the result.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_plus(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=ee089d734941936e input=5d8a75702d20e2f9]*/
+_decimal_Context_plus_impl(PyObject *context, PyTypeObject *cls, PyObject *x)
+/*[clinic end generated code: output=c37d29f58a47f93a input=5d8a75702d20e2f9]*/
 DecCtx_UnaryFunc(mpd_qplus)
 
 /*[clinic input]
@@ -6324,8 +6410,9 @@ Round to an integer.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_to_integral_value(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=ffc6470421c1439b input=3103e147cb9de9ed]*/
+_decimal_Context_to_integral_value_impl(PyObject *context, PyTypeObject *cls,
+                                        PyObject *x)
+/*[clinic end generated code: output=e3d9ad000bc06036 input=3103e147cb9de9ed]*/
 DecCtx_UnaryFunc(mpd_qround_to_int)
 
 /*[clinic input]
@@ -6335,8 +6422,9 @@ Round to an integer. Signal if the result is rounded or inexact.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_to_integral_exact(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=7fac8eca35da9290 input=677dc4b915907b68]*/
+_decimal_Context_to_integral_exact_impl(PyObject *context, PyTypeObject *cls,
+                                        PyObject *x)
+/*[clinic end generated code: output=680b796dfae8e2ef input=677dc4b915907b68]*/
 DecCtx_UnaryFunc(mpd_qround_to_intx)
 
 /*[clinic input]
@@ -6346,8 +6434,9 @@ Identical to to_integral_value(x).
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_to_integral(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=2741701ed141df91 input=89d4a4b15495b8c9]*/
+_decimal_Context_to_integral_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x)
+/*[clinic end generated code: output=09f4823b90b2cf17 input=89d4a4b15495b8c9]*/
 DecCtx_UnaryFunc(mpd_qround_to_int)
 
 /*[clinic input]
@@ -6357,8 +6446,8 @@ Square root of a non-negative number to context precision.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_sqrt(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=5595ae901120606c input=90bd954b0b8076fb]*/
+_decimal_Context_sqrt_impl(PyObject *context, PyTypeObject *cls, PyObject *x)
+/*[clinic end generated code: output=2b9c16c6f5ceead0 input=90bd954b0b8076fb]*/
 DecCtx_UnaryFunc(mpd_qsqrt)
 
 /* Binary arithmetic functions */
@@ -6367,6 +6456,7 @@ DecCtx_UnaryFunc(mpd_qsqrt)
 _decimal.Context.add
 
     self as context: self
+    cls: defining_class
     x: object
     y: object
     /
@@ -6375,8 +6465,9 @@ Return the sum of x and y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_add_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=9957850af48fe295 input=8b8eac286bdf6cb4]*/
+_decimal_Context_add_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y)
+/*[clinic end generated code: output=ab4f0fb841e6a867 input=f2c74f6a845f62e9]*/
 DecCtx_BinaryFunc(mpd_qadd)
 
 /*[clinic input]
@@ -6386,8 +6477,9 @@ Compare x and y numerically.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_compare_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=646ab96420b9aad7 input=f701cb179c966ec1]*/
+_decimal_Context_compare_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x, PyObject *y)
+/*[clinic end generated code: output=56efd1faf653f1d7 input=f701cb179c966ec1]*/
 DecCtx_BinaryFunc(mpd_qcompare)
 
 /*[clinic input]
@@ -6397,9 +6489,9 @@ Compare x and y numerically.  All NaNs signal.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_compare_signal_impl(PyObject *context, PyObject *x,
-                                     PyObject *y)
-/*[clinic end generated code: output=dd56e9e6c3d12216 input=32a1bcef7bbc5179]*/
+_decimal_Context_compare_signal_impl(PyObject *context, PyTypeObject *cls,
+                                     PyObject *x, PyObject *y)
+/*[clinic end generated code: output=7c1a9a9f6ae4e5cd input=32a1bcef7bbc5179]*/
 DecCtx_BinaryFunc(mpd_qcompare_signal)
 
 /*[clinic input]
@@ -6409,8 +6501,9 @@ Return x divided by y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_divide_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=0a07a5e718fe4a2c input=00cd9bc2ba2a1786]*/
+_decimal_Context_divide_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x, PyObject *y)
+/*[clinic end generated code: output=1a7924b20e24a528 input=00cd9bc2ba2a1786]*/
 DecCtx_BinaryFunc(mpd_qdiv)
 
 /*[clinic input]
@@ -6420,8 +6513,9 @@ Return x divided by y, truncated to an integer.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_divide_int_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=8c2d505d4339f4ef input=e80ada2f50d9719d]*/
+_decimal_Context_divide_int_impl(PyObject *context, PyTypeObject *cls,
+                                 PyObject *x, PyObject *y)
+/*[clinic end generated code: output=7a1d8948625105f0 input=e80ada2f50d9719d]*/
 DecCtx_BinaryFunc(mpd_qdivint)
 
 /*[clinic input]
@@ -6431,8 +6525,9 @@ Compare the values numerically and return the maximum.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_max_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=c8545b7718414761 input=22008ab898c86a8b]*/
+_decimal_Context_max_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y)
+/*[clinic end generated code: output=cd54af10a51c11fc input=22008ab898c86a8b]*/
 DecCtx_BinaryFunc(mpd_qmax)
 
 /*[clinic input]
@@ -6442,8 +6537,9 @@ Compare the values numerically with their sign ignored.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_max_mag_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=3cd67457cbc4d961 input=f7ce42ef82a7c52e]*/
+_decimal_Context_max_mag_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x, PyObject *y)
+/*[clinic end generated code: output=1c812e73bcb7827f input=f7ce42ef82a7c52e]*/
 DecCtx_BinaryFunc(mpd_qmax_mag)
 
 /*[clinic input]
@@ -6453,8 +6549,9 @@ Compare the values numerically and return the minimum.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_min_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=c1bc3852a7c09707 input=2aeec1167638c5ef]*/
+_decimal_Context_min_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y)
+/*[clinic end generated code: output=aa494e95b88107b3 input=2aeec1167638c5ef]*/
 DecCtx_BinaryFunc(mpd_qmin)
 
 /*[clinic input]
@@ -6464,8 +6561,9 @@ Compare the values numerically with their sign ignored.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_min_mag_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=f662c9d1b49abfd2 input=19d158c29e4fc140]*/
+_decimal_Context_min_mag_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x, PyObject *y)
+/*[clinic end generated code: output=ee0b69c1d9a14185 input=19d158c29e4fc140]*/
 DecCtx_BinaryFunc(mpd_qmin_mag)
 
 /*[clinic input]
@@ -6475,8 +6573,9 @@ Return the product of x and y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_multiply_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=970be645784d70ad input=2fdd01acdbeef8ba]*/
+_decimal_Context_multiply_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x, PyObject *y)
+/*[clinic end generated code: output=45f33b805afa01a8 input=2fdd01acdbeef8ba]*/
 DecCtx_BinaryFunc(mpd_qmul)
 
 /*[clinic input]
@@ -6486,9 +6585,9 @@ Return the number closest to x, in the direction towards y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_next_toward_impl(PyObject *context, PyObject *x,
-                                  PyObject *y)
-/*[clinic end generated code: output=938f2b4034e83618 input=aac775298e02b68c]*/
+_decimal_Context_next_toward_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x, PyObject *y)
+/*[clinic end generated code: output=436afff6f43edec2 input=aac775298e02b68c]*/
 DecCtx_BinaryFunc(mpd_qnext_toward)
 
 /*[clinic input]
@@ -6498,8 +6597,9 @@ Return a value equal to x (rounded), having the exponent of y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_quantize_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=38ae7ac037d093d0 input=43d67a696ab6d895]*/
+_decimal_Context_quantize_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x, PyObject *y)
+/*[clinic end generated code: output=fcf8cd32b7d628c9 input=43d67a696ab6d895]*/
 DecCtx_BinaryFunc(mpd_qquantize)
 
 /*[clinic input]
@@ -6512,8 +6612,9 @@ original dividend.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_remainder_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=eb158964831b5ca4 input=36d0eb2b392c1215]*/
+_decimal_Context_remainder_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x, PyObject *y)
+/*[clinic end generated code: output=e0f96c834abbfbd2 input=36d0eb2b392c1215]*/
 DecCtx_BinaryFunc(mpd_qrem)
 
 /*[clinic input]
@@ -6526,9 +6627,9 @@ is 0 then its sign will be the sign of x).
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_remainder_near_impl(PyObject *context, PyObject *x,
-                                     PyObject *y)
-/*[clinic end generated code: output=2bcbd9bb031d0d13 input=bafb6327bb314c5c]*/
+_decimal_Context_remainder_near_impl(PyObject *context, PyTypeObject *cls,
+                                     PyObject *x, PyObject *y)
+/*[clinic end generated code: output=7f18c535a12cf8ac input=bafb6327bb314c5c]*/
 DecCtx_BinaryFunc(mpd_qrem_near)
 
 /*[clinic input]
@@ -6538,8 +6639,9 @@ Return the difference between x and y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_subtract_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=fa8847e07b7c2bcc input=6767683ec68f7a1a]*/
+_decimal_Context_subtract_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x, PyObject *y)
+/*[clinic end generated code: output=3d764a8a87e79401 input=6767683ec68f7a1a]*/
 DecCtx_BinaryFunc(mpd_qsub)
 
 /*[clinic input]
@@ -6599,6 +6701,7 @@ _decimal_Context_divmod_impl(PyObject *context, PyObject *x, PyObject *y)
 _decimal.Context.power
 
     self as context: self
+    cls: defining_class
     a as base: object
     b as exp: object
     modulo as mod: object = None
@@ -6621,9 +6724,9 @@ restrictions hold:
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_power_impl(PyObject *context, PyObject *base, PyObject *exp,
-                            PyObject *mod)
-/*[clinic end generated code: output=d2e68694ec545245 input=e9aef844813de243]*/
+_decimal_Context_power_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *base, PyObject *exp, PyObject *mod)
+/*[clinic end generated code: output=d06d40c37cdd69dc input=2a70edd03317c666]*/
 {
     PyObject *a, *b, *c = NULL;
     PyObject *result;
@@ -6639,7 +6742,7 @@ _decimal_Context_power_impl(PyObject *context, PyObject *base, PyObject *exp,
         }
     }
 
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     result = dec_alloc(state);
     if (result == NULL) {
         Py_DECREF(a);
@@ -6673,6 +6776,7 @@ _decimal_Context_power_impl(PyObject *context, PyObject *base, PyObject *exp,
 _decimal.Context.fma
 
     self as context: self
+    cls: defining_class
     x: object
     y: object
     z: object
@@ -6682,9 +6786,9 @@ Return x multiplied by y, plus z.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_fma_impl(PyObject *context, PyObject *x, PyObject *y,
-                          PyObject *z)
-/*[clinic end generated code: output=2d6174716faaf4e1 input=80479612da3333d1]*/
+_decimal_Context_fma_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y, PyObject *z)
+/*[clinic end generated code: output=08ec3cefc59d71a9 input=da3963b1a1da83b9]*/
 DecCtx_TernaryFunc(mpd_qfma)
 
 /* No argument */
@@ -6693,15 +6797,16 @@ DecCtx_TernaryFunc(mpd_qfma)
 _decimal.Context.radix
 
     self as context: self
+    cls: defining_class
 
 Return 10.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_radix_impl(PyObject *context)
-/*[clinic end generated code: output=9218fa309e0fcaa1 input=faeaa5b71f838c38]*/
+_decimal_Context_radix_impl(PyObject *context, PyTypeObject *cls)
+/*[clinic end generated code: output=674b88b7cd0c264d input=e1e4f8c0abf86825]*/
 {
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     return _dec_mpd_radix(state);
 }
 
@@ -6711,6 +6816,7 @@ _decimal_Context_radix_impl(PyObject *context)
 _decimal.Context.is_normal
 
     self as context: self
+    cls: defining_class
     x: object
     /
 
@@ -6718,8 +6824,9 @@ Return True if x is a normal number, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_normal(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=fed613aed8b286de input=1e7ff3f560842b8d]*/
+_decimal_Context_is_normal_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x)
+/*[clinic end generated code: output=089c5609db60bf57 input=7c90b825a517ef7e]*/
 DecCtx_BoolFunc(mpd_isnormal)
 
 /*[clinic input]
@@ -6729,8 +6836,9 @@ Return True if x is subnormal, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_subnormal(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=834450c602d58759 input=73f1bd9367b913a4]*/
+_decimal_Context_is_subnormal_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x)
+/*[clinic end generated code: output=f58c45a288aadeda input=73f1bd9367b913a4]*/
 DecCtx_BoolFunc(mpd_issubnormal)
 
 /*[clinic input]
@@ -6740,8 +6848,9 @@ Return True if x is finite, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_finite(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=45606d2f56874fef input=abff92a8a6bb85e6]*/
+_decimal_Context_is_finite_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x)
+/*[clinic end generated code: output=dfb00f1b5589b9f0 input=abff92a8a6bb85e6]*/
 DecCtx_BoolFunc_NO_CTX(mpd_isfinite)
 
 /*[clinic input]
@@ -6751,8 +6860,9 @@ Return True if x is infinite, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_infinite(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=35c480cd0a2c3cf9 input=591242ae9a1e60e6]*/
+_decimal_Context_is_infinite_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x)
+/*[clinic end generated code: output=1c28517500811d01 input=591242ae9a1e60e6]*/
 DecCtx_BoolFunc_NO_CTX(mpd_isinfinite)
 
 /*[clinic input]
@@ -6762,8 +6872,9 @@ Return True if x is a qNaN or sNaN, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_nan(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=cb529f55bf3106b3 input=520218376d5eec5e]*/
+_decimal_Context_is_nan_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x)
+/*[clinic end generated code: output=9dc15463ee19864a input=520218376d5eec5e]*/
 DecCtx_BoolFunc_NO_CTX(mpd_isnan)
 
 /*[clinic input]
@@ -6773,8 +6884,9 @@ Return True if x is a quiet NaN, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_qnan(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=3e2e750eb643db1d input=97d06a14ab3360d1]*/
+_decimal_Context_is_qnan_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x)
+/*[clinic end generated code: output=4caa672e03703b6d input=97d06a14ab3360d1]*/
 DecCtx_BoolFunc_NO_CTX(mpd_isqnan)
 
 /*[clinic input]
@@ -6784,8 +6896,9 @@ Return True if x is a signaling NaN, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_snan(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=a7ead03a2dfa15e4 input=0059fe4e9c3b25a8]*/
+_decimal_Context_is_snan_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x)
+/*[clinic end generated code: output=a8caa929d9f82ecd input=0059fe4e9c3b25a8]*/
 DecCtx_BoolFunc_NO_CTX(mpd_issnan)
 
 /*[clinic input]
@@ -6795,8 +6908,9 @@ Return True if x is negative, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_signed(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=c85cc15479d5ed47 input=b950cd697721ab8b]*/
+_decimal_Context_is_signed_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x)
+/*[clinic end generated code: output=42c450c99d4fe7db input=b950cd697721ab8b]*/
 DecCtx_BoolFunc_NO_CTX(mpd_issigned)
 
 /*[clinic input]
@@ -6806,8 +6920,9 @@ Return True if x is a zero, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_zero(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=24150f3c2422ebf8 input=bf08197d142a8027]*/
+_decimal_Context_is_zero_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x)
+/*[clinic end generated code: output=e6c55359b7241d9e input=bf08197d142a8027]*/
 DecCtx_BoolFunc_NO_CTX(mpd_iszero)
 
 /*[clinic input]
@@ -6817,10 +6932,11 @@ Return True if x is canonical, False otherwise.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_is_canonical(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=b5b522b930a41186 input=1bf2129808e55eb9]*/
+_decimal_Context_is_canonical_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x)
+/*[clinic end generated code: output=18ee249d9aec957c input=1bf2129808e55eb9]*/
 {
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     if (!PyDec_Check(state, x)) {
         PyErr_SetString(PyExc_TypeError,
             "argument must be a Decimal");
@@ -6838,8 +6954,9 @@ Apply self to Decimal x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context__apply(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=8db39d294602492e input=12b34468ca4a4c30]*/
+_decimal_Context__apply_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x)
+/*[clinic end generated code: output=c6b542f4e8114b97 input=12b34468ca4a4c30]*/
 {
     PyObject *result, *a;
 
@@ -6858,8 +6975,9 @@ Apply self to Decimal x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_apply(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=4d39653645a6df44 input=388e66ca82733516]*/
+_decimal_Context_apply_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x)
+/*[clinic end generated code: output=f8a7142d47ad4ff3 input=388e66ca82733516]*/
 {
     return _decimal_Context__apply(context, v);
 }
@@ -6872,10 +6990,11 @@ Return a new instance of x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_canonical(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=28fa845499e5d485 input=025ecb106ac15bff]*/
+_decimal_Context_canonical_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x)
+/*[clinic end generated code: output=f213e433e2032e5e input=025ecb106ac15bff]*/
 {
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     if (!PyDec_Check(state, x)) {
         PyErr_SetString(PyExc_TypeError,
             "argument must be a Decimal");
@@ -6892,14 +7011,15 @@ Return a copy of x with the sign set to 0.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_copy_abs(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=a9035e6606261b30 input=4aa2f612625f0f73]*/
+_decimal_Context_copy_abs_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x)
+/*[clinic end generated code: output=a141ad4b9afe2deb input=4aa2f612625f0f73]*/
 {
     PyObject *result, *a;
     uint32_t status = 0;
 
     CONVERT_OP_RAISE(&a, x, context);
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     result = dec_alloc(state);
     if (result == NULL) {
         Py_DECREF(a);
@@ -6923,8 +7043,9 @@ Return a copy of Decimal x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_copy_decimal(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=b9ec251a2a568a14 input=4db4f942f45fb7c9]*/
+_decimal_Context_copy_decimal_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x)
+/*[clinic end generated code: output=639a82e1193d31f6 input=4db4f942f45fb7c9]*/
 {
     PyObject *result;
 
@@ -6939,14 +7060,15 @@ Return a copy of x with the sign inverted.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_copy_negate(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=5fe136d7bac13391 input=2e6e213e2ed0efda]*/
+_decimal_Context_copy_negate_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x)
+/*[clinic end generated code: output=e49d013489dc252b input=2e6e213e2ed0efda]*/
 {
     PyObject *result, *a;
     uint32_t status = 0;
 
     CONVERT_OP_RAISE(&a, x, context);
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     result = dec_alloc(state);
     if (result == NULL) {
         Py_DECREF(a);
@@ -6970,8 +7092,8 @@ Return the exponent of the magnitude of the operand's MSD.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_logb(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=d2d8469f828daa41 input=28d1cd1a8a906b9a]*/
+_decimal_Context_logb_impl(PyObject *context, PyTypeObject *cls, PyObject *x)
+/*[clinic end generated code: output=9b9697e1eb68093f input=28d1cd1a8a906b9a]*/
 DecCtx_UnaryFunc(mpd_qlogb)
 
 /*[clinic input]
@@ -6981,8 +7103,9 @@ Invert all digits of x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_logical_invert(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=b863a5cdb986f684 input=1fa8dcc59c557fcc]*/
+_decimal_Context_logical_invert_impl(PyObject *context, PyTypeObject *cls,
+                                     PyObject *x)
+/*[clinic end generated code: output=97760277a958e2b0 input=1fa8dcc59c557fcc]*/
 DecCtx_UnaryFunc(mpd_qinvert)
 
 /*[clinic input]
@@ -6992,8 +7115,9 @@ Return an indication of the class of x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_number_class(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=2b39fa98dd723c6f input=1ead8462f1800e4e]*/
+_decimal_Context_number_class_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x)
+/*[clinic end generated code: output=c1592a23e25ba5ee input=1ead8462f1800e4e]*/
 {
     PyObject *a;
     const char *cp;
@@ -7013,8 +7137,9 @@ Convert a number to a string using scientific notation.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_to_sci_string(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=7d461d24824c6f15 input=ed442677c66d342d]*/
+_decimal_Context_to_sci_string_impl(PyObject *context, PyTypeObject *cls,
+                                    PyObject *x)
+/*[clinic end generated code: output=092dcdef999d72da input=ed442677c66d342d]*/
 {
     PyObject *result;
     PyObject *a;
@@ -7043,8 +7168,9 @@ Convert a number to a string, using engineering notation.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_to_eng_string(PyObject *context, PyObject *x)
-/*[clinic end generated code: output=3a54b9de0b01708f input=a574385e2e3e3bc0]*/
+_decimal_Context_to_eng_string_impl(PyObject *context, PyTypeObject *cls,
+                                    PyObject *x)
+/*[clinic end generated code: output=7fc53216c208f487 input=a574385e2e3e3bc0]*/
 {
     PyObject *result;
     PyObject *a;
@@ -7072,6 +7198,7 @@ _decimal_Context_to_eng_string(PyObject *context, PyObject *x)
 _decimal.Context.compare_total
 
     self as context: self
+    cls: defining_class
     x: object
     y: object
     /
@@ -7080,9 +7207,9 @@ Compare x and y using their abstract representation.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_compare_total_impl(PyObject *context, PyObject *x,
-                                    PyObject *y)
-/*[clinic end generated code: output=a9299ef125fb2245 input=020b30c9bc2ea2c6]*/
+_decimal_Context_compare_total_impl(PyObject *context, PyTypeObject *cls,
+                                    PyObject *x, PyObject *y)
+/*[clinic end generated code: output=f79177b27fe930e3 input=2bfc677a841e297a]*/
 DecCtx_BinaryFunc_NO_CTX(mpd_compare_total)
 
 /*[clinic input]
@@ -7092,9 +7219,9 @@ Compare x and y using their abstract representation, ignoring sign.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_compare_total_mag_impl(PyObject *context, PyObject *x,
-                                        PyObject *y)
-/*[clinic end generated code: output=7c376de9f94feeaf input=2b982e69f932dcb2]*/
+_decimal_Context_compare_total_mag_impl(PyObject *context, PyTypeObject *cls,
+                                        PyObject *x, PyObject *y)
+/*[clinic end generated code: output=2528c669ccd6d6ff input=2b982e69f932dcb2]*/
 DecCtx_BinaryFunc_NO_CTX(mpd_compare_total_mag)
 
 /*[clinic input]
@@ -7104,15 +7231,16 @@ Copy the sign from y to x.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_copy_sign_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=fff3c5c474acf78e input=c0682aeaffc7cfdf]*/
+_decimal_Context_copy_sign_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x, PyObject *y)
+/*[clinic end generated code: output=77d23b6f4e42120c input=c0682aeaffc7cfdf]*/
 {
     PyObject *a, *b;
     PyObject *result;
     uint32_t status = 0;
 
     CONVERT_BINOP_RAISE(&a, &b, x, y, context);
-    decimal_state *state = get_module_state_from_ctx(context);
+    decimal_state *state = PyType_GetModuleState(cls);
     result = dec_alloc(state);
     if (result == NULL) {
         Py_DECREF(a);
@@ -7138,9 +7266,9 @@ Digit-wise and of x and y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_logical_and_impl(PyObject *context, PyObject *x,
-                                  PyObject *y)
-/*[clinic end generated code: output=f1e9bf7844a395fc input=30ee33b5b365fd80]*/
+_decimal_Context_logical_and_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x, PyObject *y)
+/*[clinic end generated code: output=009dfa08ecaa2ac8 input=30ee33b5b365fd80]*/
 DecCtx_BinaryFunc(mpd_qand)
 
 /*[clinic input]
@@ -7150,8 +7278,9 @@ Digit-wise or of x and y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_logical_or_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=28f7ecd1af3262f0 input=3b1a6725d0262fb9]*/
+_decimal_Context_logical_or_impl(PyObject *context, PyTypeObject *cls,
+                                 PyObject *x, PyObject *y)
+/*[clinic end generated code: output=eb38617e8d31bf12 input=3b1a6725d0262fb9]*/
 DecCtx_BinaryFunc(mpd_qor)
 
 /*[clinic input]
@@ -7161,9 +7290,9 @@ Digit-wise xor of x and y.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_logical_xor_impl(PyObject *context, PyObject *x,
-                                  PyObject *y)
-/*[clinic end generated code: output=7d8461ace42d1871 input=5ebbbe8bb35da380]*/
+_decimal_Context_logical_xor_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x, PyObject *y)
+/*[clinic end generated code: output=23cd81fdcd865d5a input=5ebbbe8bb35da380]*/
 DecCtx_BinaryFunc(mpd_qxor)
 
 /*[clinic input]
@@ -7173,8 +7302,9 @@ Return a copy of x, rotated by y places.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_rotate_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=6d8b718f218712a2 input=7ad91845c909eb0a]*/
+_decimal_Context_rotate_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x, PyObject *y)
+/*[clinic end generated code: output=3d5b3cfcb4659432 input=7ad91845c909eb0a]*/
 DecCtx_BinaryFunc(mpd_qrotate)
 
 /*[clinic input]
@@ -7184,8 +7314,9 @@ Return the first operand after adding the second value to its exp.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_scaleb_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=3c9cb117027c7722 input=c5d2ee7a57f65f8c]*/
+_decimal_Context_scaleb_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x, PyObject *y)
+/*[clinic end generated code: output=795ac61bcbe61c67 input=c5d2ee7a57f65f8c]*/
 DecCtx_BinaryFunc(mpd_qscaleb)
 
 /*[clinic input]
@@ -7195,8 +7326,9 @@ Return a copy of x, shifted by y places.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_shift_impl(PyObject *context, PyObject *x, PyObject *y)
-/*[clinic end generated code: output=78625878a264b3e5 input=1ab44ff0854420ce]*/
+_decimal_Context_shift_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x, PyObject *y)
+/*[clinic end generated code: output=43d69615f0271c81 input=1ab44ff0854420ce]*/
 DecCtx_BinaryFunc(mpd_qshift)
 
 /*[clinic input]
@@ -7206,9 +7338,9 @@ Return True if the two operands have the same exponent.
 [clinic start generated code]*/
 
 static PyObject *
-_decimal_Context_same_quantum_impl(PyObject *context, PyObject *x,
-                                   PyObject *y)
-/*[clinic end generated code: output=137acab27ece605c input=194cd156e398eaf9]*/
+_decimal_Context_same_quantum_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x, PyObject *y)
+/*[clinic end generated code: output=91a4d8325f98d9e9 input=194cd156e398eaf9]*/
 {
     PyObject *a, *b;
     PyObject *result;
@@ -7310,16 +7442,14 @@ static PyMethodDef context_methods [] =
   _DECIMAL_CONTEXT_CLEAR_FLAGS_METHODDEF
   _DECIMAL_CONTEXT_CLEAR_TRAPS_METHODDEF
 
-#ifdef CONFIG_32
   /* Unsafe set functions with relaxed range checks */
-  { "_unsafe_setprec", context_unsafe_setprec, METH_O, NULL },
-  { "_unsafe_setemin", context_unsafe_setemin, METH_O, NULL },
-  { "_unsafe_setemax", context_unsafe_setemax, METH_O, NULL },
-#endif
+  _DECIMAL_CONTEXT__UNSAFE_SETPREC_METHODDEF
+  _DECIMAL_CONTEXT__UNSAFE_SETEMIN_METHODDEF
+  _DECIMAL_CONTEXT__UNSAFE_SETEMAX_METHODDEF
 
   /* Miscellaneous */
-  { "__copy__", context_copy, METH_NOARGS, NULL },
-  { "__reduce__", context_reduce, METH_NOARGS, NULL },
+  _DECIMAL_CONTEXT___COPY___METHODDEF
+  _DECIMAL_CONTEXT___REDUCE___METHODDEF
   _DECIMAL_CONTEXT_COPY_METHODDEF
   _DECIMAL_CONTEXT_CREATE_DECIMAL_METHODDEF
   _DECIMAL_CONTEXT_CREATE_DECIMAL_FROM_FLOAT_METHODDEF
index 0f7a7f78cd73e531665fb508402d96bd263a3621..ccfbf63a7cead55f11243ad2b33c91b34d38fcbf 100644 (file)
@@ -51,6 +51,123 @@ _decimal_Context_Etop(PyObject *self, PyObject *Py_UNUSED(ignored))
     return _decimal_Context_Etop_impl(self);
 }
 
+#if defined(CONFIG_32)
+
+PyDoc_STRVAR(_decimal_Context__unsafe_setprec__doc__,
+"_unsafe_setprec($self, x, /)\n"
+"--\n"
+"\n");
+
+#define _DECIMAL_CONTEXT__UNSAFE_SETPREC_METHODDEF    \
+    {"_unsafe_setprec", (PyCFunction)_decimal_Context__unsafe_setprec, METH_O, _decimal_Context__unsafe_setprec__doc__},
+
+static PyObject *
+_decimal_Context__unsafe_setprec_impl(PyObject *self, Py_ssize_t x);
+
+static PyObject *
+_decimal_Context__unsafe_setprec(PyObject *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t x;
+
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(arg);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        x = ival;
+    }
+    return_value = _decimal_Context__unsafe_setprec_impl(self, x);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(CONFIG_32) */
+
+#if defined(CONFIG_32)
+
+PyDoc_STRVAR(_decimal_Context__unsafe_setemin__doc__,
+"_unsafe_setemin($self, x, /)\n"
+"--\n"
+"\n");
+
+#define _DECIMAL_CONTEXT__UNSAFE_SETEMIN_METHODDEF    \
+    {"_unsafe_setemin", (PyCFunction)_decimal_Context__unsafe_setemin, METH_O, _decimal_Context__unsafe_setemin__doc__},
+
+static PyObject *
+_decimal_Context__unsafe_setemin_impl(PyObject *self, Py_ssize_t x);
+
+static PyObject *
+_decimal_Context__unsafe_setemin(PyObject *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t x;
+
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(arg);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        x = ival;
+    }
+    return_value = _decimal_Context__unsafe_setemin_impl(self, x);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(CONFIG_32) */
+
+#if defined(CONFIG_32)
+
+PyDoc_STRVAR(_decimal_Context__unsafe_setemax__doc__,
+"_unsafe_setemax($self, x, /)\n"
+"--\n"
+"\n");
+
+#define _DECIMAL_CONTEXT__UNSAFE_SETEMAX_METHODDEF    \
+    {"_unsafe_setemax", (PyCFunction)_decimal_Context__unsafe_setemax, METH_O, _decimal_Context__unsafe_setemax__doc__},
+
+static PyObject *
+_decimal_Context__unsafe_setemax_impl(PyObject *self, Py_ssize_t x);
+
+static PyObject *
+_decimal_Context__unsafe_setemax(PyObject *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    Py_ssize_t x;
+
+    {
+        Py_ssize_t ival = -1;
+        PyObject *iobj = _PyNumber_Index(arg);
+        if (iobj != NULL) {
+            ival = PyLong_AsSsize_t(iobj);
+            Py_DECREF(iobj);
+        }
+        if (ival == -1 && PyErr_Occurred()) {
+            goto exit;
+        }
+        x = ival;
+    }
+    return_value = _decimal_Context__unsafe_setemax_impl(self, x);
+
+exit:
+    return return_value;
+}
+
+#endif /* defined(CONFIG_32) */
+
 PyDoc_STRVAR(_decimal_Context_clear_traps__doc__,
 "clear_traps($self, /)\n"
 "--\n"
@@ -257,15 +374,61 @@ PyDoc_STRVAR(_decimal_Context_copy__doc__,
 "Return a duplicate of the context with all flags cleared.");
 
 #define _DECIMAL_CONTEXT_COPY_METHODDEF    \
-    {"copy", (PyCFunction)_decimal_Context_copy, METH_NOARGS, _decimal_Context_copy__doc__},
+    {"copy", _PyCFunction_CAST(_decimal_Context_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_copy__doc__},
+
+static PyObject *
+_decimal_Context_copy_impl(PyObject *self, PyTypeObject *cls);
+
+static PyObject *
+_decimal_Context_copy(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "copy() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Context_copy_impl(self, cls);
+}
+
+PyDoc_STRVAR(_decimal_Context___copy____doc__,
+"__copy__($self, /)\n"
+"--\n"
+"\n");
+
+#define _DECIMAL_CONTEXT___COPY___METHODDEF    \
+    {"__copy__", _PyCFunction_CAST(_decimal_Context___copy__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context___copy____doc__},
 
 static PyObject *
-_decimal_Context_copy_impl(PyObject *self);
+_decimal_Context___copy___impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Context_copy(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Context___copy__(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Context_copy_impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "__copy__() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Context___copy___impl(self, cls);
+}
+
+PyDoc_STRVAR(_decimal_Context___reduce____doc__,
+"__reduce__($self, /)\n"
+"--\n"
+"\n");
+
+#define _DECIMAL_CONTEXT___REDUCE___METHODDEF    \
+    {"__reduce__", _PyCFunction_CAST(_decimal_Context___reduce__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context___reduce____doc__},
+
+static PyObject *
+_decimal_Context___reduce___impl(PyObject *self, PyTypeObject *cls);
+
+static PyObject *
+_decimal_Context___reduce__(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "__reduce__() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Context___reduce___impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_getcontext__doc__,
@@ -445,18 +608,41 @@ PyDoc_STRVAR(_decimal_Decimal_from_float__doc__,
 "    Decimal(\'-Infinity\')");
 
 #define _DECIMAL_DECIMAL_FROM_FLOAT_METHODDEF    \
-    {"from_float", (PyCFunction)_decimal_Decimal_from_float, METH_O|METH_CLASS, _decimal_Decimal_from_float__doc__},
+    {"from_float", _PyCFunction_CAST(_decimal_Decimal_from_float), METH_METHOD|METH_FASTCALL|METH_KEYWORDS|METH_CLASS, _decimal_Decimal_from_float__doc__},
 
 static PyObject *
-_decimal_Decimal_from_float_impl(PyTypeObject *type, PyObject *pyfloat);
+_decimal_Decimal_from_float_impl(PyTypeObject *type, PyTypeObject *cls,
+                                 PyObject *pyfloat);
 
 static PyObject *
-_decimal_Decimal_from_float(PyObject *type, PyObject *pyfloat)
+_decimal_Decimal_from_float(PyObject *type, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "from_float",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *pyfloat;
 
-    return_value = _decimal_Decimal_from_float_impl((PyTypeObject *)type, pyfloat);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    pyfloat = args[0];
+    return_value = _decimal_Decimal_from_float_impl((PyTypeObject *)type, cls, pyfloat);
 
+exit:
     return return_value;
 }
 
@@ -474,18 +660,41 @@ PyDoc_STRVAR(_decimal_Decimal_from_number__doc__,
 "    Decimal(\'3.14\')");
 
 #define _DECIMAL_DECIMAL_FROM_NUMBER_METHODDEF    \
-    {"from_number", (PyCFunction)_decimal_Decimal_from_number, METH_O|METH_CLASS, _decimal_Decimal_from_number__doc__},
+    {"from_number", _PyCFunction_CAST(_decimal_Decimal_from_number), METH_METHOD|METH_FASTCALL|METH_KEYWORDS|METH_CLASS, _decimal_Decimal_from_number__doc__},
 
 static PyObject *
-_decimal_Decimal_from_number_impl(PyTypeObject *type, PyObject *number);
+_decimal_Decimal_from_number_impl(PyTypeObject *type, PyTypeObject *cls,
+                                  PyObject *number);
 
 static PyObject *
-_decimal_Decimal_from_number(PyObject *type, PyObject *number)
+_decimal_Decimal_from_number(PyObject *type, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "from_number",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *number;
 
-    return_value = _decimal_Decimal_from_number_impl((PyTypeObject *)type, number);
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    number = args[0];
+    return_value = _decimal_Decimal_from_number_impl((PyTypeObject *)type, cls, number);
 
+exit:
     return return_value;
 }
 
@@ -499,7 +708,44 @@ PyDoc_STRVAR(_decimal_Context_create_decimal_from_float__doc__,
 "the context limits.");
 
 #define _DECIMAL_CONTEXT_CREATE_DECIMAL_FROM_FLOAT_METHODDEF    \
-    {"create_decimal_from_float", (PyCFunction)_decimal_Context_create_decimal_from_float, METH_O, _decimal_Context_create_decimal_from_float__doc__},
+    {"create_decimal_from_float", _PyCFunction_CAST(_decimal_Context_create_decimal_from_float), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_create_decimal_from_float__doc__},
+
+static PyObject *
+_decimal_Context_create_decimal_from_float_impl(PyObject *context,
+                                                PyTypeObject *cls,
+                                                PyObject *f);
+
+static PyObject *
+_decimal_Context_create_decimal_from_float(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "create_decimal_from_float",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *f;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    f = args[0];
+    return_value = _decimal_Context_create_decimal_from_float_impl(context, cls, f);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(dec_new__doc__,
 "Decimal(value=\'0\', context=None)\n"
@@ -617,20 +863,36 @@ PyDoc_STRVAR(_decimal_Decimal___format____doc__,
 "Formats the Decimal according to format_spec.");
 
 #define _DECIMAL_DECIMAL___FORMAT___METHODDEF    \
-    {"__format__", _PyCFunction_CAST(_decimal_Decimal___format__), METH_FASTCALL, _decimal_Decimal___format____doc__},
+    {"__format__", _PyCFunction_CAST(_decimal_Decimal___format__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal___format____doc__},
 
 static PyObject *
-_decimal_Decimal___format___impl(PyObject *dec, PyObject *fmtarg,
-                                 PyObject *override);
+_decimal_Decimal___format___impl(PyObject *dec, PyTypeObject *cls,
+                                 PyObject *fmtarg, PyObject *override);
 
 static PyObject *
-_decimal_Decimal___format__(PyObject *dec, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Decimal___format__(PyObject *dec, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "__format__",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *fmtarg;
     PyObject *override = NULL;
 
-    if (!_PyArg_CheckPositional("__format__", nargs, 1, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     if (!PyUnicode_Check(args[0])) {
@@ -639,11 +901,11 @@ _decimal_Decimal___format__(PyObject *dec, PyObject *const *args, Py_ssize_t nar
     }
     fmtarg = args[0];
     if (nargs < 2) {
-        goto skip_optional;
+        goto skip_optional_posonly;
     }
     override = args[1];
-skip_optional:
-    return_value = _decimal_Decimal___format___impl(dec, fmtarg, override);
+skip_optional_posonly:
+    return_value = _decimal_Decimal___format___impl(dec, cls, fmtarg, override);
 
 exit:
     return return_value;
@@ -659,15 +921,19 @@ PyDoc_STRVAR(_decimal_Decimal_as_integer_ratio__doc__,
 "Raise OverflowError on infinities and a ValueError on NaNs.");
 
 #define _DECIMAL_DECIMAL_AS_INTEGER_RATIO_METHODDEF    \
-    {"as_integer_ratio", (PyCFunction)_decimal_Decimal_as_integer_ratio, METH_NOARGS, _decimal_Decimal_as_integer_ratio__doc__},
+    {"as_integer_ratio", _PyCFunction_CAST(_decimal_Decimal_as_integer_ratio), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_as_integer_ratio__doc__},
 
 static PyObject *
-_decimal_Decimal_as_integer_ratio_impl(PyObject *self);
+_decimal_Decimal_as_integer_ratio_impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal_as_integer_ratio(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_as_integer_ratio(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_as_integer_ratio_impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "as_integer_ratio() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal_as_integer_ratio_impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Decimal_to_integral_value__doc__,
@@ -681,14 +947,15 @@ PyDoc_STRVAR(_decimal_Decimal_to_integral_value__doc__,
 "rounding mode of the current default context is used.");
 
 #define _DECIMAL_DECIMAL_TO_INTEGRAL_VALUE_METHODDEF    \
-    {"to_integral_value", _PyCFunction_CAST(_decimal_Decimal_to_integral_value), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral_value__doc__},
+    {"to_integral_value", _PyCFunction_CAST(_decimal_Decimal_to_integral_value), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral_value__doc__},
 
 static PyObject *
-_decimal_Decimal_to_integral_value_impl(PyObject *self, PyObject *rounding,
+_decimal_Decimal_to_integral_value_impl(PyObject *self, PyTypeObject *cls,
+                                        PyObject *rounding,
                                         PyObject *context);
 
 static PyObject *
-_decimal_Decimal_to_integral_value(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_to_integral_value(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -739,7 +1006,7 @@ _decimal_Decimal_to_integral_value(PyObject *self, PyObject *const *args, Py_ssi
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_to_integral_value_impl(self, rounding, context);
+    return_value = _decimal_Decimal_to_integral_value_impl(self, cls, rounding, context);
 
 exit:
     return return_value;
@@ -755,14 +1022,14 @@ PyDoc_STRVAR(_decimal_Decimal_to_integral__doc__,
 "versions.");
 
 #define _DECIMAL_DECIMAL_TO_INTEGRAL_METHODDEF    \
-    {"to_integral", _PyCFunction_CAST(_decimal_Decimal_to_integral), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral__doc__},
+    {"to_integral", _PyCFunction_CAST(_decimal_Decimal_to_integral), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral__doc__},
 
 static PyObject *
-_decimal_Decimal_to_integral_impl(PyObject *self, PyObject *rounding,
-                                  PyObject *context);
+_decimal_Decimal_to_integral_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *rounding, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_to_integral(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_to_integral(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -813,7 +1080,7 @@ _decimal_Decimal_to_integral(PyObject *self, PyObject *const *args, Py_ssize_t n
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_to_integral_impl(self, rounding, context);
+    return_value = _decimal_Decimal_to_integral_impl(self, cls, rounding, context);
 
 exit:
     return return_value;
@@ -831,14 +1098,15 @@ PyDoc_STRVAR(_decimal_Decimal_to_integral_exact__doc__,
 "given, then the rounding mode of the current default context is used.");
 
 #define _DECIMAL_DECIMAL_TO_INTEGRAL_EXACT_METHODDEF    \
-    {"to_integral_exact", _PyCFunction_CAST(_decimal_Decimal_to_integral_exact), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral_exact__doc__},
+    {"to_integral_exact", _PyCFunction_CAST(_decimal_Decimal_to_integral_exact), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_integral_exact__doc__},
 
 static PyObject *
-_decimal_Decimal_to_integral_exact_impl(PyObject *self, PyObject *rounding,
+_decimal_Decimal_to_integral_exact_impl(PyObject *self, PyTypeObject *cls,
+                                        PyObject *rounding,
                                         PyObject *context);
 
 static PyObject *
-_decimal_Decimal_to_integral_exact(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_to_integral_exact(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -889,7 +1157,7 @@ _decimal_Decimal_to_integral_exact(PyObject *self, PyObject *const *args, Py_ssi
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_to_integral_exact_impl(self, rounding, context);
+    return_value = _decimal_Decimal_to_integral_exact_impl(self, cls, rounding, context);
 
 exit:
     return return_value;
@@ -902,26 +1170,43 @@ PyDoc_STRVAR(_decimal_Decimal___round____doc__,
 "Return the Integral closest to self, rounding half toward even.");
 
 #define _DECIMAL_DECIMAL___ROUND___METHODDEF    \
-    {"__round__", _PyCFunction_CAST(_decimal_Decimal___round__), METH_FASTCALL, _decimal_Decimal___round____doc__},
+    {"__round__", _PyCFunction_CAST(_decimal_Decimal___round__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal___round____doc__},
 
 static PyObject *
-_decimal_Decimal___round___impl(PyObject *self, PyObject *ndigits);
+_decimal_Decimal___round___impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *ndigits);
 
 static PyObject *
-_decimal_Decimal___round__(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Decimal___round__(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "__round__",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *ndigits = NULL;
 
-    if (!_PyArg_CheckPositional("__round__", nargs, 0, 1)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 0, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     if (nargs < 1) {
-        goto skip_optional;
+        goto skip_optional_posonly;
     }
     ndigits = args[0];
-skip_optional:
-    return_value = _decimal_Decimal___round___impl(self, ndigits);
+skip_optional_posonly:
+    return_value = _decimal_Decimal___round___impl(self, cls, ndigits);
 
 exit:
     return return_value;
@@ -934,15 +1219,19 @@ PyDoc_STRVAR(_decimal_Decimal_as_tuple__doc__,
 "Return a tuple representation of the number.");
 
 #define _DECIMAL_DECIMAL_AS_TUPLE_METHODDEF    \
-    {"as_tuple", (PyCFunction)_decimal_Decimal_as_tuple, METH_NOARGS, _decimal_Decimal_as_tuple__doc__},
+    {"as_tuple", _PyCFunction_CAST(_decimal_Decimal_as_tuple), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_as_tuple__doc__},
 
 static PyObject *
-_decimal_Decimal_as_tuple_impl(PyObject *self);
+_decimal_Decimal_as_tuple_impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal_as_tuple(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_as_tuple(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_as_tuple_impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "as_tuple() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal_as_tuple_impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Decimal_exp__doc__,
@@ -955,13 +1244,14 @@ PyDoc_STRVAR(_decimal_Decimal_exp__doc__,
 "correctly rounded.");
 
 #define _DECIMAL_DECIMAL_EXP_METHODDEF    \
-    {"exp", _PyCFunction_CAST(_decimal_Decimal_exp), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_exp__doc__},
+    {"exp", _PyCFunction_CAST(_decimal_Decimal_exp), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_exp__doc__},
 
 static PyObject *
-_decimal_Decimal_exp_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_exp_impl(PyObject *self, PyTypeObject *cls,
+                          PyObject *context);
 
 static PyObject *
-_decimal_Decimal_exp(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_exp(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1005,7 +1295,7 @@ _decimal_Decimal_exp(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_exp_impl(self, context);
+    return_value = _decimal_Decimal_exp_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -1021,13 +1311,14 @@ PyDoc_STRVAR(_decimal_Decimal_ln__doc__,
 "correctly rounded.");
 
 #define _DECIMAL_DECIMAL_LN_METHODDEF    \
-    {"ln", _PyCFunction_CAST(_decimal_Decimal_ln), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_ln__doc__},
+    {"ln", _PyCFunction_CAST(_decimal_Decimal_ln), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_ln__doc__},
 
 static PyObject *
-_decimal_Decimal_ln_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_ln_impl(PyObject *self, PyTypeObject *cls,
+                         PyObject *context);
 
 static PyObject *
-_decimal_Decimal_ln(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_ln(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1071,7 +1362,7 @@ _decimal_Decimal_ln(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyO
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_ln_impl(self, context);
+    return_value = _decimal_Decimal_ln_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -1087,13 +1378,14 @@ PyDoc_STRVAR(_decimal_Decimal_log10__doc__,
 "correctly rounded.");
 
 #define _DECIMAL_DECIMAL_LOG10_METHODDEF    \
-    {"log10", _PyCFunction_CAST(_decimal_Decimal_log10), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_log10__doc__},
+    {"log10", _PyCFunction_CAST(_decimal_Decimal_log10), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_log10__doc__},
 
 static PyObject *
-_decimal_Decimal_log10_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_log10_impl(PyObject *self, PyTypeObject *cls,
+                            PyObject *context);
 
 static PyObject *
-_decimal_Decimal_log10(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_log10(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1137,7 +1429,7 @@ _decimal_Decimal_log10(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_log10_impl(self, context);
+    return_value = _decimal_Decimal_log10_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -1150,13 +1442,14 @@ PyDoc_STRVAR(_decimal_Decimal_next_minus__doc__,
 "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__},
+    {"next_minus", _PyCFunction_CAST(_decimal_Decimal_next_minus), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_minus__doc__},
 
 static PyObject *
-_decimal_Decimal_next_minus_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_next_minus_impl(PyObject *self, PyTypeObject *cls,
+                                 PyObject *context);
 
 static PyObject *
-_decimal_Decimal_next_minus(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_next_minus(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1200,7 +1493,7 @@ _decimal_Decimal_next_minus(PyObject *self, PyObject *const *args, Py_ssize_t na
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_next_minus_impl(self, context);
+    return_value = _decimal_Decimal_next_minus_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -1213,13 +1506,14 @@ PyDoc_STRVAR(_decimal_Decimal_next_plus__doc__,
 "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__},
+    {"next_plus", _PyCFunction_CAST(_decimal_Decimal_next_plus), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_plus__doc__},
 
 static PyObject *
-_decimal_Decimal_next_plus_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_next_plus_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *context);
 
 static PyObject *
-_decimal_Decimal_next_plus(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_next_plus(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1263,7 +1557,7 @@ _decimal_Decimal_next_plus(PyObject *self, PyObject *const *args, Py_ssize_t nar
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_next_plus_impl(self, context);
+    return_value = _decimal_Decimal_next_plus_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -1281,13 +1575,14 @@ PyDoc_STRVAR(_decimal_Decimal_normalize__doc__,
 "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__},
+    {"normalize", _PyCFunction_CAST(_decimal_Decimal_normalize), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_normalize__doc__},
 
 static PyObject *
-_decimal_Decimal_normalize_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_normalize_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *context);
 
 static PyObject *
-_decimal_Decimal_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_normalize(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1331,7 +1626,7 @@ _decimal_Decimal_normalize(PyObject *self, PyObject *const *args, Py_ssize_t nar
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_normalize_impl(self, context);
+    return_value = _decimal_Decimal_normalize_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -1346,13 +1641,14 @@ PyDoc_STRVAR(_decimal_Decimal_sqrt__doc__,
 "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__},
+    {"sqrt", _PyCFunction_CAST(_decimal_Decimal_sqrt), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_sqrt__doc__},
 
 static PyObject *
-_decimal_Decimal_sqrt_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_sqrt_impl(PyObject *self, PyTypeObject *cls,
+                           PyObject *context);
 
 static PyObject *
-_decimal_Decimal_sqrt(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_sqrt(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1396,7 +1692,7 @@ _decimal_Decimal_sqrt(PyObject *self, PyObject *const *args, Py_ssize_t nargs, P
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_sqrt_impl(self, context);
+    return_value = _decimal_Decimal_sqrt_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -1416,14 +1712,14 @@ PyDoc_STRVAR(_decimal_Decimal_compare__doc__,
 "    a > b           ==> Decimal(\'1\')");
 
 #define _DECIMAL_DECIMAL_COMPARE_METHODDEF    \
-    {"compare", _PyCFunction_CAST(_decimal_Decimal_compare), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare__doc__},
+    {"compare", _PyCFunction_CAST(_decimal_Decimal_compare), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare__doc__},
 
 static PyObject *
-_decimal_Decimal_compare_impl(PyObject *self, PyObject *other,
-                              PyObject *context);
+_decimal_Decimal_compare_impl(PyObject *self, PyTypeObject *cls,
+                              PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_compare(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_compare(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1469,7 +1765,7 @@ _decimal_Decimal_compare(PyObject *self, PyObject *const *args, Py_ssize_t nargs
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_compare_impl(self, other, context);
+    return_value = _decimal_Decimal_compare_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1482,14 +1778,14 @@ PyDoc_STRVAR(_decimal_Decimal_compare_signal__doc__,
 "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__},
+    {"compare_signal", _PyCFunction_CAST(_decimal_Decimal_compare_signal), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_signal__doc__},
 
 static PyObject *
-_decimal_Decimal_compare_signal_impl(PyObject *self, PyObject *other,
-                                     PyObject *context);
+_decimal_Decimal_compare_signal_impl(PyObject *self, PyTypeObject *cls,
+                                     PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_compare_signal(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_compare_signal(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1535,7 +1831,7 @@ _decimal_Decimal_compare_signal(PyObject *self, PyObject *const *args, Py_ssize_
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_compare_signal_impl(self, other, context);
+    return_value = _decimal_Decimal_compare_signal_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1551,13 +1847,14 @@ PyDoc_STRVAR(_decimal_Decimal_max__doc__,
 "operand is returned.");
 
 #define _DECIMAL_DECIMAL_MAX_METHODDEF    \
-    {"max", _PyCFunction_CAST(_decimal_Decimal_max), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_max__doc__},
+    {"max", _PyCFunction_CAST(_decimal_Decimal_max), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_max__doc__},
 
 static PyObject *
-_decimal_Decimal_max_impl(PyObject *self, PyObject *other, PyObject *context);
+_decimal_Decimal_max_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
+                          PyObject *context);
 
 static PyObject *
-_decimal_Decimal_max(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_max(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1603,7 +1900,7 @@ _decimal_Decimal_max(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_max_impl(self, other, context);
+    return_value = _decimal_Decimal_max_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1616,14 +1913,14 @@ PyDoc_STRVAR(_decimal_Decimal_max_mag__doc__,
 "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__},
+    {"max_mag", _PyCFunction_CAST(_decimal_Decimal_max_mag), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_max_mag__doc__},
 
 static PyObject *
-_decimal_Decimal_max_mag_impl(PyObject *self, PyObject *other,
-                              PyObject *context);
+_decimal_Decimal_max_mag_impl(PyObject *self, PyTypeObject *cls,
+                              PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_max_mag(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_max_mag(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1669,7 +1966,7 @@ _decimal_Decimal_max_mag(PyObject *self, PyObject *const *args, Py_ssize_t nargs
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_max_mag_impl(self, other, context);
+    return_value = _decimal_Decimal_max_mag_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1685,13 +1982,14 @@ PyDoc_STRVAR(_decimal_Decimal_min__doc__,
 "operand is returned.");
 
 #define _DECIMAL_DECIMAL_MIN_METHODDEF    \
-    {"min", _PyCFunction_CAST(_decimal_Decimal_min), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_min__doc__},
+    {"min", _PyCFunction_CAST(_decimal_Decimal_min), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_min__doc__},
 
 static PyObject *
-_decimal_Decimal_min_impl(PyObject *self, PyObject *other, PyObject *context);
+_decimal_Decimal_min_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
+                          PyObject *context);
 
 static PyObject *
-_decimal_Decimal_min(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_min(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1737,7 +2035,7 @@ _decimal_Decimal_min(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_min_impl(self, other, context);
+    return_value = _decimal_Decimal_min_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1750,14 +2048,14 @@ PyDoc_STRVAR(_decimal_Decimal_min_mag__doc__,
 "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__},
+    {"min_mag", _PyCFunction_CAST(_decimal_Decimal_min_mag), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_min_mag__doc__},
 
 static PyObject *
-_decimal_Decimal_min_mag_impl(PyObject *self, PyObject *other,
-                              PyObject *context);
+_decimal_Decimal_min_mag_impl(PyObject *self, PyTypeObject *cls,
+                              PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_min_mag(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_min_mag(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1803,7 +2101,7 @@ _decimal_Decimal_min_mag(PyObject *self, PyObject *const *args, Py_ssize_t nargs
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_min_mag_impl(self, other, context);
+    return_value = _decimal_Decimal_min_mag_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1821,14 +2119,14 @@ PyDoc_STRVAR(_decimal_Decimal_next_toward__doc__,
 "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__},
+    {"next_toward", _PyCFunction_CAST(_decimal_Decimal_next_toward), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_next_toward__doc__},
 
 static PyObject *
-_decimal_Decimal_next_toward_impl(PyObject *self, PyObject *other,
-                                  PyObject *context);
+_decimal_Decimal_next_toward_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_next_toward(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_next_toward(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1874,7 +2172,7 @@ _decimal_Decimal_next_toward(PyObject *self, PyObject *const *args, Py_ssize_t n
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_next_toward_impl(self, other, context);
+    return_value = _decimal_Decimal_next_toward_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1895,14 +2193,14 @@ PyDoc_STRVAR(_decimal_Decimal_remainder_near__doc__,
 "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__},
+    {"remainder_near", _PyCFunction_CAST(_decimal_Decimal_remainder_near), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_remainder_near__doc__},
 
 static PyObject *
-_decimal_Decimal_remainder_near_impl(PyObject *self, PyObject *other,
-                                     PyObject *context);
+_decimal_Decimal_remainder_near_impl(PyObject *self, PyTypeObject *cls,
+                                     PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_remainder_near(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_remainder_near(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -1948,7 +2246,7 @@ _decimal_Decimal_remainder_near(PyObject *self, PyObject *const *args, Py_ssize_
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_remainder_near_impl(self, other, context);
+    return_value = _decimal_Decimal_remainder_near_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -1967,14 +2265,14 @@ PyDoc_STRVAR(_decimal_Decimal_fma__doc__,
 "    Decimal(\'11\')");
 
 #define _DECIMAL_DECIMAL_FMA_METHODDEF    \
-    {"fma", _PyCFunction_CAST(_decimal_Decimal_fma), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_fma__doc__},
+    {"fma", _PyCFunction_CAST(_decimal_Decimal_fma), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_fma__doc__},
 
 static PyObject *
-_decimal_Decimal_fma_impl(PyObject *self, PyObject *other, PyObject *third,
-                          PyObject *context);
+_decimal_Decimal_fma_impl(PyObject *self, PyTypeObject *cls, PyObject *other,
+                          PyObject *third, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_fma(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_fma(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2022,7 +2320,7 @@ _decimal_Decimal_fma(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py
     }
     context = args[2];
 skip_optional_pos:
-    return_value = _decimal_Decimal_fma_impl(self, other, third, context);
+    return_value = _decimal_Decimal_fma_impl(self, cls, other, third, context);
 
 exit:
     return return_value;
@@ -2186,13 +2484,14 @@ PyDoc_STRVAR(_decimal_Decimal_is_normal__doc__,
 "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__},
+    {"is_normal", _PyCFunction_CAST(_decimal_Decimal_is_normal), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_is_normal__doc__},
 
 static PyObject *
-_decimal_Decimal_is_normal_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_is_normal_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *context);
 
 static PyObject *
-_decimal_Decimal_is_normal(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_is_normal(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2236,7 +2535,7 @@ _decimal_Decimal_is_normal(PyObject *self, PyObject *const *args, Py_ssize_t nar
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_is_normal_impl(self, context);
+    return_value = _decimal_Decimal_is_normal_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -2252,13 +2551,14 @@ PyDoc_STRVAR(_decimal_Decimal_is_subnormal__doc__,
 "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__},
+    {"is_subnormal", _PyCFunction_CAST(_decimal_Decimal_is_subnormal), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_is_subnormal__doc__},
 
 static PyObject *
-_decimal_Decimal_is_subnormal_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_is_subnormal_impl(PyObject *self, PyTypeObject *cls,
+                                   PyObject *context);
 
 static PyObject *
-_decimal_Decimal_is_subnormal(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_is_subnormal(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2302,7 +2602,7 @@ _decimal_Decimal_is_subnormal(PyObject *self, PyObject *const *args, Py_ssize_t
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_is_subnormal_impl(self, context);
+    return_value = _decimal_Decimal_is_subnormal_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -2375,15 +2675,19 @@ PyDoc_STRVAR(_decimal_Decimal_radix__doc__,
 "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__},
+    {"radix", _PyCFunction_CAST(_decimal_Decimal_radix), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_radix__doc__},
 
 static PyObject *
-_decimal_Decimal_radix_impl(PyObject *self);
+_decimal_Decimal_radix_impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal_radix(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_radix(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_radix_impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "radix() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal_radix_impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Decimal_copy_abs__doc__,
@@ -2396,15 +2700,19 @@ PyDoc_STRVAR(_decimal_Decimal_copy_abs__doc__,
 "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__},
+    {"copy_abs", _PyCFunction_CAST(_decimal_Decimal_copy_abs), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_abs__doc__},
 
 static PyObject *
-_decimal_Decimal_copy_abs_impl(PyObject *self);
+_decimal_Decimal_copy_abs_impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal_copy_abs(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_copy_abs(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_copy_abs_impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "copy_abs() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal_copy_abs_impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Decimal_copy_negate__doc__,
@@ -2417,15 +2725,19 @@ PyDoc_STRVAR(_decimal_Decimal_copy_negate__doc__,
 "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__},
+    {"copy_negate", _PyCFunction_CAST(_decimal_Decimal_copy_negate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_negate__doc__},
 
 static PyObject *
-_decimal_Decimal_copy_negate_impl(PyObject *self);
+_decimal_Decimal_copy_negate_impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal_copy_negate(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal_copy_negate(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal_copy_negate_impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "copy_negate() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal_copy_negate_impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Decimal_logical_invert__doc__,
@@ -2435,13 +2747,14 @@ PyDoc_STRVAR(_decimal_Decimal_logical_invert__doc__,
 "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__},
+    {"logical_invert", _PyCFunction_CAST(_decimal_Decimal_logical_invert), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_invert__doc__},
 
 static PyObject *
-_decimal_Decimal_logical_invert_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_logical_invert_impl(PyObject *self, PyTypeObject *cls,
+                                     PyObject *context);
 
 static PyObject *
-_decimal_Decimal_logical_invert(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_logical_invert(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2485,7 +2798,7 @@ _decimal_Decimal_logical_invert(PyObject *self, PyObject *const *args, Py_ssize_
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_logical_invert_impl(self, context);
+    return_value = _decimal_Decimal_logical_invert_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -2502,13 +2815,14 @@ PyDoc_STRVAR(_decimal_Decimal_logb__doc__,
 "Decimal(\'Infinity\') is returned.");
 
 #define _DECIMAL_DECIMAL_LOGB_METHODDEF    \
-    {"logb", _PyCFunction_CAST(_decimal_Decimal_logb), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logb__doc__},
+    {"logb", _PyCFunction_CAST(_decimal_Decimal_logb), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logb__doc__},
 
 static PyObject *
-_decimal_Decimal_logb_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_logb_impl(PyObject *self, PyTypeObject *cls,
+                           PyObject *context);
 
 static PyObject *
-_decimal_Decimal_logb(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_logb(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2552,7 +2866,7 @@ _decimal_Decimal_logb(PyObject *self, PyObject *const *args, Py_ssize_t nargs, P
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_logb_impl(self, context);
+    return_value = _decimal_Decimal_logb_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -2582,13 +2896,14 @@ PyDoc_STRVAR(_decimal_Decimal_number_class__doc__,
 "    * \'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__},
+    {"number_class", _PyCFunction_CAST(_decimal_Decimal_number_class), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_number_class__doc__},
 
 static PyObject *
-_decimal_Decimal_number_class_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_number_class_impl(PyObject *self, PyTypeObject *cls,
+                                   PyObject *context);
 
 static PyObject *
-_decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_number_class(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2632,7 +2947,7 @@ _decimal_Decimal_number_class(PyObject *self, PyObject *const *args, Py_ssize_t
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_number_class_impl(self, context);
+    return_value = _decimal_Decimal_number_class_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -2653,13 +2968,14 @@ PyDoc_STRVAR(_decimal_Decimal_to_eng_string__doc__,
 "operation.");
 
 #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__},
+    {"to_eng_string", _PyCFunction_CAST(_decimal_Decimal_to_eng_string), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_to_eng_string__doc__},
 
 static PyObject *
-_decimal_Decimal_to_eng_string_impl(PyObject *self, PyObject *context);
+_decimal_Decimal_to_eng_string_impl(PyObject *self, PyTypeObject *cls,
+                                    PyObject *context);
 
 static PyObject *
-_decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_to_eng_string(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2703,7 +3019,7 @@ _decimal_Decimal_to_eng_string(PyObject *self, PyObject *const *args, Py_ssize_t
     }
     context = args[0];
 skip_optional_pos:
-    return_value = _decimal_Decimal_to_eng_string_impl(self, context);
+    return_value = _decimal_Decimal_to_eng_string_impl(self, cls, context);
 
 exit:
     return return_value;
@@ -2736,14 +3052,14 @@ PyDoc_STRVAR(_decimal_Decimal_compare_total__doc__,
 "exactly.");
 
 #define _DECIMAL_DECIMAL_COMPARE_TOTAL_METHODDEF    \
-    {"compare_total", _PyCFunction_CAST(_decimal_Decimal_compare_total), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_total__doc__},
+    {"compare_total", _PyCFunction_CAST(_decimal_Decimal_compare_total), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_total__doc__},
 
 static PyObject *
-_decimal_Decimal_compare_total_impl(PyObject *self, PyObject *other,
-                                    PyObject *context);
+_decimal_Decimal_compare_total_impl(PyObject *self, PyTypeObject *cls,
+                                    PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_compare_total(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_compare_total(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2789,7 +3105,7 @@ _decimal_Decimal_compare_total(PyObject *self, PyObject *const *args, Py_ssize_t
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_compare_total_impl(self, other, context);
+    return_value = _decimal_Decimal_compare_total_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -2810,14 +3126,14 @@ PyDoc_STRVAR(_decimal_Decimal_compare_total_mag__doc__,
 "exactly.");
 
 #define _DECIMAL_DECIMAL_COMPARE_TOTAL_MAG_METHODDEF    \
-    {"compare_total_mag", _PyCFunction_CAST(_decimal_Decimal_compare_total_mag), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_total_mag__doc__},
+    {"compare_total_mag", _PyCFunction_CAST(_decimal_Decimal_compare_total_mag), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_compare_total_mag__doc__},
 
 static PyObject *
-_decimal_Decimal_compare_total_mag_impl(PyObject *self, PyObject *other,
-                                        PyObject *context);
+_decimal_Decimal_compare_total_mag_impl(PyObject *self, PyTypeObject *cls,
+                                        PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_compare_total_mag(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_compare_total_mag(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2863,7 +3179,7 @@ _decimal_Decimal_compare_total_mag(PyObject *self, PyObject *const *args, Py_ssi
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_compare_total_mag_impl(self, other, context);
+    return_value = _decimal_Decimal_compare_total_mag_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -2886,14 +3202,14 @@ PyDoc_STRVAR(_decimal_Decimal_copy_sign__doc__,
 "exactly.");
 
 #define _DECIMAL_DECIMAL_COPY_SIGN_METHODDEF    \
-    {"copy_sign", _PyCFunction_CAST(_decimal_Decimal_copy_sign), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_sign__doc__},
+    {"copy_sign", _PyCFunction_CAST(_decimal_Decimal_copy_sign), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_copy_sign__doc__},
 
 static PyObject *
-_decimal_Decimal_copy_sign_impl(PyObject *self, PyObject *other,
-                                PyObject *context);
+_decimal_Decimal_copy_sign_impl(PyObject *self, PyTypeObject *cls,
+                                PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_copy_sign(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_copy_sign(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -2939,7 +3255,7 @@ _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_copy_sign_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -2957,14 +3273,14 @@ PyDoc_STRVAR(_decimal_Decimal_same_quantum__doc__,
 "exactly.");
 
 #define _DECIMAL_DECIMAL_SAME_QUANTUM_METHODDEF    \
-    {"same_quantum", _PyCFunction_CAST(_decimal_Decimal_same_quantum), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_same_quantum__doc__},
+    {"same_quantum", _PyCFunction_CAST(_decimal_Decimal_same_quantum), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_same_quantum__doc__},
 
 static PyObject *
-_decimal_Decimal_same_quantum_impl(PyObject *self, PyObject *other,
-                                   PyObject *context);
+_decimal_Decimal_same_quantum_impl(PyObject *self, PyTypeObject *cls,
+                                   PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_same_quantum(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_same_quantum(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3010,7 +3326,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_same_quantum_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -3023,14 +3339,14 @@ PyDoc_STRVAR(_decimal_Decimal_logical_and__doc__,
 "Return the digit-wise \'and\' of the two (logical) operands.");
 
 #define _DECIMAL_DECIMAL_LOGICAL_AND_METHODDEF    \
-    {"logical_and", _PyCFunction_CAST(_decimal_Decimal_logical_and), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_and__doc__},
+    {"logical_and", _PyCFunction_CAST(_decimal_Decimal_logical_and), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_and__doc__},
 
 static PyObject *
-_decimal_Decimal_logical_and_impl(PyObject *self, PyObject *other,
-                                  PyObject *context);
+_decimal_Decimal_logical_and_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_logical_and(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_logical_and(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3076,7 +3392,7 @@ _decimal_Decimal_logical_and(PyObject *self, PyObject *const *args, Py_ssize_t n
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_logical_and_impl(self, other, context);
+    return_value = _decimal_Decimal_logical_and_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -3089,14 +3405,14 @@ PyDoc_STRVAR(_decimal_Decimal_logical_or__doc__,
 "Return the digit-wise \'or\' of the two (logical) operands.");
 
 #define _DECIMAL_DECIMAL_LOGICAL_OR_METHODDEF    \
-    {"logical_or", _PyCFunction_CAST(_decimal_Decimal_logical_or), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_or__doc__},
+    {"logical_or", _PyCFunction_CAST(_decimal_Decimal_logical_or), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_or__doc__},
 
 static PyObject *
-_decimal_Decimal_logical_or_impl(PyObject *self, PyObject *other,
-                                 PyObject *context);
+_decimal_Decimal_logical_or_impl(PyObject *self, PyTypeObject *cls,
+                                 PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_logical_or(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_logical_or(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3142,7 +3458,7 @@ _decimal_Decimal_logical_or(PyObject *self, PyObject *const *args, Py_ssize_t na
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_logical_or_impl(self, other, context);
+    return_value = _decimal_Decimal_logical_or_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -3155,14 +3471,14 @@ PyDoc_STRVAR(_decimal_Decimal_logical_xor__doc__,
 "Return the digit-wise \'xor\' of the two (logical) operands.");
 
 #define _DECIMAL_DECIMAL_LOGICAL_XOR_METHODDEF    \
-    {"logical_xor", _PyCFunction_CAST(_decimal_Decimal_logical_xor), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_xor__doc__},
+    {"logical_xor", _PyCFunction_CAST(_decimal_Decimal_logical_xor), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_logical_xor__doc__},
 
 static PyObject *
-_decimal_Decimal_logical_xor_impl(PyObject *self, PyObject *other,
-                                  PyObject *context);
+_decimal_Decimal_logical_xor_impl(PyObject *self, PyTypeObject *cls,
+                                  PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_logical_xor(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_logical_xor(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3208,7 +3524,7 @@ _decimal_Decimal_logical_xor(PyObject *self, PyObject *const *args, Py_ssize_t n
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_logical_xor_impl(self, other, context);
+    return_value = _decimal_Decimal_logical_xor_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -3228,14 +3544,14 @@ PyDoc_STRVAR(_decimal_Decimal_rotate__doc__,
 "necessary. The sign and exponent of the first operand are unchanged.");
 
 #define _DECIMAL_DECIMAL_ROTATE_METHODDEF    \
-    {"rotate", _PyCFunction_CAST(_decimal_Decimal_rotate), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_rotate__doc__},
+    {"rotate", _PyCFunction_CAST(_decimal_Decimal_rotate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_rotate__doc__},
 
 static PyObject *
-_decimal_Decimal_rotate_impl(PyObject *self, PyObject *other,
-                             PyObject *context);
+_decimal_Decimal_rotate_impl(PyObject *self, PyTypeObject *cls,
+                             PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_rotate(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_rotate(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3281,7 +3597,7 @@ _decimal_Decimal_rotate(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_rotate_impl(self, other, context);
+    return_value = _decimal_Decimal_rotate_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -3297,14 +3613,14 @@ PyDoc_STRVAR(_decimal_Decimal_scaleb__doc__,
 "second operand must be an integer.");
 
 #define _DECIMAL_DECIMAL_SCALEB_METHODDEF    \
-    {"scaleb", _PyCFunction_CAST(_decimal_Decimal_scaleb), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_scaleb__doc__},
+    {"scaleb", _PyCFunction_CAST(_decimal_Decimal_scaleb), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_scaleb__doc__},
 
 static PyObject *
-_decimal_Decimal_scaleb_impl(PyObject *self, PyObject *other,
-                             PyObject *context);
+_decimal_Decimal_scaleb_impl(PyObject *self, PyTypeObject *cls,
+                             PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_scaleb(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_scaleb(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3350,7 +3666,7 @@ _decimal_Decimal_scaleb(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_scaleb_impl(self, other, context);
+    return_value = _decimal_Decimal_scaleb_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -3370,14 +3686,14 @@ PyDoc_STRVAR(_decimal_Decimal_shift__doc__,
 "operand are unchanged.");
 
 #define _DECIMAL_DECIMAL_SHIFT_METHODDEF    \
-    {"shift", _PyCFunction_CAST(_decimal_Decimal_shift), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_shift__doc__},
+    {"shift", _PyCFunction_CAST(_decimal_Decimal_shift), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_shift__doc__},
 
 static PyObject *
-_decimal_Decimal_shift_impl(PyObject *self, PyObject *other,
-                            PyObject *context);
+_decimal_Decimal_shift_impl(PyObject *self, PyTypeObject *cls,
+                            PyObject *other, PyObject *context);
 
 static PyObject *
-_decimal_Decimal_shift(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_shift(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3423,7 +3739,7 @@ _decimal_Decimal_shift(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
     }
     context = args[1];
 skip_optional_pos:
-    return_value = _decimal_Decimal_shift_impl(self, other, context);
+    return_value = _decimal_Decimal_shift_impl(self, cls, other, context);
 
 exit:
     return return_value;
@@ -3457,14 +3773,15 @@ PyDoc_STRVAR(_decimal_Decimal_quantize__doc__,
 "current thread\'s context is used.");
 
 #define _DECIMAL_DECIMAL_QUANTIZE_METHODDEF    \
-    {"quantize", _PyCFunction_CAST(_decimal_Decimal_quantize), METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_quantize__doc__},
+    {"quantize", _PyCFunction_CAST(_decimal_Decimal_quantize), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal_quantize__doc__},
 
 static PyObject *
-_decimal_Decimal_quantize_impl(PyObject *self, PyObject *w,
-                               PyObject *rounding, PyObject *context);
+_decimal_Decimal_quantize_impl(PyObject *self, PyTypeObject *cls,
+                               PyObject *w, PyObject *rounding,
+                               PyObject *context);
 
 static PyObject *
-_decimal_Decimal_quantize(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Decimal_quantize(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
@@ -3517,7 +3834,7 @@ _decimal_Decimal_quantize(PyObject *self, PyObject *const *args, Py_ssize_t narg
     }
     context = args[2];
 skip_optional_pos:
-    return_value = _decimal_Decimal_quantize_impl(self, w, rounding, context);
+    return_value = _decimal_Decimal_quantize_impl(self, cls, w, rounding, context);
 
 exit:
     return return_value;
@@ -3530,15 +3847,19 @@ PyDoc_STRVAR(_decimal_Decimal___ceil____doc__,
 "Return the ceiling as an Integral.");
 
 #define _DECIMAL_DECIMAL___CEIL___METHODDEF    \
-    {"__ceil__", (PyCFunction)_decimal_Decimal___ceil__, METH_NOARGS, _decimal_Decimal___ceil____doc__},
+    {"__ceil__", _PyCFunction_CAST(_decimal_Decimal___ceil__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal___ceil____doc__},
 
 static PyObject *
-_decimal_Decimal___ceil___impl(PyObject *self);
+_decimal_Decimal___ceil___impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal___ceil__(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal___ceil__(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal___ceil___impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "__ceil__() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal___ceil___impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Decimal___complex____doc__,
@@ -3591,15 +3912,19 @@ PyDoc_STRVAR(_decimal_Decimal___floor____doc__,
 "Return the floor as an Integral.");
 
 #define _DECIMAL_DECIMAL___FLOOR___METHODDEF    \
-    {"__floor__", (PyCFunction)_decimal_Decimal___floor__, METH_NOARGS, _decimal_Decimal___floor____doc__},
+    {"__floor__", _PyCFunction_CAST(_decimal_Decimal___floor__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal___floor____doc__},
 
 static PyObject *
-_decimal_Decimal___floor___impl(PyObject *self);
+_decimal_Decimal___floor___impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal___floor__(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal___floor__(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal___floor___impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "__floor__() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal___floor___impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Decimal___reduce____doc__,
@@ -3645,15 +3970,19 @@ PyDoc_STRVAR(_decimal_Decimal___trunc____doc__,
 "Return the Integral closest to x between 0 and x.");
 
 #define _DECIMAL_DECIMAL___TRUNC___METHODDEF    \
-    {"__trunc__", (PyCFunction)_decimal_Decimal___trunc__, METH_NOARGS, _decimal_Decimal___trunc____doc__},
+    {"__trunc__", _PyCFunction_CAST(_decimal_Decimal___trunc__), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Decimal___trunc____doc__},
 
 static PyObject *
-_decimal_Decimal___trunc___impl(PyObject *self);
+_decimal_Decimal___trunc___impl(PyObject *self, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Decimal___trunc__(PyObject *self, PyObject *Py_UNUSED(ignored))
+_decimal_Decimal___trunc__(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Decimal___trunc___impl(self);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "__trunc__() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Decimal___trunc___impl(self, cls);
 }
 
 PyDoc_STRVAR(_decimal_Context_abs__doc__,
@@ -3663,7 +3992,42 @@ PyDoc_STRVAR(_decimal_Context_abs__doc__,
 "Return the absolute value of x.");
 
 #define _DECIMAL_CONTEXT_ABS_METHODDEF    \
-    {"abs", (PyCFunction)_decimal_Context_abs, METH_O, _decimal_Context_abs__doc__},
+    {"abs", _PyCFunction_CAST(_decimal_Context_abs), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_abs__doc__},
+
+static PyObject *
+_decimal_Context_abs_impl(PyObject *context, PyTypeObject *cls, PyObject *x);
+
+static PyObject *
+_decimal_Context_abs(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "abs",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_abs_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_exp__doc__,
 "exp($self, x, /)\n"
@@ -3672,710 +4036,1406 @@ PyDoc_STRVAR(_decimal_Context_exp__doc__,
 "Return e ** x.");
 
 #define _DECIMAL_CONTEXT_EXP_METHODDEF    \
-    {"exp", (PyCFunction)_decimal_Context_exp, METH_O, _decimal_Context_exp__doc__},
+    {"exp", _PyCFunction_CAST(_decimal_Context_exp), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_exp__doc__},
 
-PyDoc_STRVAR(_decimal_Context_ln__doc__,
-"ln($self, x, /)\n"
-"--\n"
-"\n"
-"Return the natural (base e) logarithm of x.");
+static PyObject *
+_decimal_Context_exp_impl(PyObject *context, PyTypeObject *cls, PyObject *x);
 
-#define _DECIMAL_CONTEXT_LN_METHODDEF    \
-    {"ln", (PyCFunction)_decimal_Context_ln, METH_O, _decimal_Context_ln__doc__},
+static PyObject *
+_decimal_Context_exp(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
 
-PyDoc_STRVAR(_decimal_Context_log10__doc__,
-"log10($self, x, /)\n"
-"--\n"
-"\n"
-"Return the base 10 logarithm of x.");
-
-#define _DECIMAL_CONTEXT_LOG10_METHODDEF    \
-    {"log10", (PyCFunction)_decimal_Context_log10, METH_O, _decimal_Context_log10__doc__},
-
-PyDoc_STRVAR(_decimal_Context_minus__doc__,
-"minus($self, x, /)\n"
-"--\n"
-"\n"
-"Minus corresponds to unary prefix minus in Python.\n"
-"\n"
-"This operation applies the context to the result.");
-
-#define _DECIMAL_CONTEXT_MINUS_METHODDEF    \
-    {"minus", (PyCFunction)_decimal_Context_minus, METH_O, _decimal_Context_minus__doc__},
-
-PyDoc_STRVAR(_decimal_Context_next_minus__doc__,
-"next_minus($self, x, /)\n"
-"--\n"
-"\n"
-"Return the largest representable number smaller than x.");
-
-#define _DECIMAL_CONTEXT_NEXT_MINUS_METHODDEF    \
-    {"next_minus", (PyCFunction)_decimal_Context_next_minus, METH_O, _decimal_Context_next_minus__doc__},
-
-PyDoc_STRVAR(_decimal_Context_next_plus__doc__,
-"next_plus($self, x, /)\n"
-"--\n"
-"\n"
-"Return the smallest representable number larger than x.");
-
-#define _DECIMAL_CONTEXT_NEXT_PLUS_METHODDEF    \
-    {"next_plus", (PyCFunction)_decimal_Context_next_plus, METH_O, _decimal_Context_next_plus__doc__},
-
-PyDoc_STRVAR(_decimal_Context_normalize__doc__,
-"normalize($self, x, /)\n"
-"--\n"
-"\n"
-"Reduce x to its simplest form. Alias for reduce(x).");
-
-#define _DECIMAL_CONTEXT_NORMALIZE_METHODDEF    \
-    {"normalize", (PyCFunction)_decimal_Context_normalize, METH_O, _decimal_Context_normalize__doc__},
-
-PyDoc_STRVAR(_decimal_Context_plus__doc__,
-"plus($self, x, /)\n"
-"--\n"
-"\n"
-"Plus corresponds to the unary prefix plus operator in Python.\n"
-"\n"
-"This operation applies the context to the result.");
-
-#define _DECIMAL_CONTEXT_PLUS_METHODDEF    \
-    {"plus", (PyCFunction)_decimal_Context_plus, METH_O, _decimal_Context_plus__doc__},
-
-PyDoc_STRVAR(_decimal_Context_to_integral_value__doc__,
-"to_integral_value($self, x, /)\n"
-"--\n"
-"\n"
-"Round to an integer.");
-
-#define _DECIMAL_CONTEXT_TO_INTEGRAL_VALUE_METHODDEF    \
-    {"to_integral_value", (PyCFunction)_decimal_Context_to_integral_value, METH_O, _decimal_Context_to_integral_value__doc__},
-
-PyDoc_STRVAR(_decimal_Context_to_integral_exact__doc__,
-"to_integral_exact($self, x, /)\n"
-"--\n"
-"\n"
-"Round to an integer. Signal if the result is rounded or inexact.");
-
-#define _DECIMAL_CONTEXT_TO_INTEGRAL_EXACT_METHODDEF    \
-    {"to_integral_exact", (PyCFunction)_decimal_Context_to_integral_exact, METH_O, _decimal_Context_to_integral_exact__doc__},
-
-PyDoc_STRVAR(_decimal_Context_to_integral__doc__,
-"to_integral($self, x, /)\n"
-"--\n"
-"\n"
-"Identical to to_integral_value(x).");
-
-#define _DECIMAL_CONTEXT_TO_INTEGRAL_METHODDEF    \
-    {"to_integral", (PyCFunction)_decimal_Context_to_integral, METH_O, _decimal_Context_to_integral__doc__},
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "exp",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
 
-PyDoc_STRVAR(_decimal_Context_sqrt__doc__,
-"sqrt($self, x, /)\n"
-"--\n"
-"\n"
-"Square root of a non-negative number to context precision.");
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_exp_impl(context, cls, x);
 
-#define _DECIMAL_CONTEXT_SQRT_METHODDEF    \
-    {"sqrt", (PyCFunction)_decimal_Context_sqrt, METH_O, _decimal_Context_sqrt__doc__},
+exit:
+    return return_value;
+}
 
-PyDoc_STRVAR(_decimal_Context_add__doc__,
-"add($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_ln__doc__,
+"ln($self, x, /)\n"
 "--\n"
 "\n"
-"Return the sum of x and y.");
+"Return the natural (base e) logarithm of x.");
 
-#define _DECIMAL_CONTEXT_ADD_METHODDEF    \
-    {"add", _PyCFunction_CAST(_decimal_Context_add), METH_FASTCALL, _decimal_Context_add__doc__},
+#define _DECIMAL_CONTEXT_LN_METHODDEF    \
+    {"ln", _PyCFunction_CAST(_decimal_Context_ln), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_ln__doc__},
 
 static PyObject *
-_decimal_Context_add_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_ln_impl(PyObject *context, PyTypeObject *cls, PyObject *x);
 
 static PyObject *
-_decimal_Context_add(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_ln(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "ln",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("add", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_add_impl(context, x, y);
+    return_value = _decimal_Context_ln_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_compare__doc__,
-"compare($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_log10__doc__,
+"log10($self, x, /)\n"
 "--\n"
 "\n"
-"Compare x and y numerically.");
+"Return the base 10 logarithm of x.");
 
-#define _DECIMAL_CONTEXT_COMPARE_METHODDEF    \
-    {"compare", _PyCFunction_CAST(_decimal_Context_compare), METH_FASTCALL, _decimal_Context_compare__doc__},
+#define _DECIMAL_CONTEXT_LOG10_METHODDEF    \
+    {"log10", _PyCFunction_CAST(_decimal_Context_log10), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_log10__doc__},
 
 static PyObject *
-_decimal_Context_compare_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_log10_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x);
 
 static PyObject *
-_decimal_Context_compare(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_log10(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "log10",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("compare", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_compare_impl(context, x, y);
+    return_value = _decimal_Context_log10_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_compare_signal__doc__,
-"compare_signal($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_minus__doc__,
+"minus($self, x, /)\n"
 "--\n"
 "\n"
-"Compare x and y numerically.  All NaNs signal.");
+"Minus corresponds to unary prefix minus in Python.\n"
+"\n"
+"This operation applies the context to the result.");
 
-#define _DECIMAL_CONTEXT_COMPARE_SIGNAL_METHODDEF    \
-    {"compare_signal", _PyCFunction_CAST(_decimal_Context_compare_signal), METH_FASTCALL, _decimal_Context_compare_signal__doc__},
+#define _DECIMAL_CONTEXT_MINUS_METHODDEF    \
+    {"minus", _PyCFunction_CAST(_decimal_Context_minus), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_minus__doc__},
 
 static PyObject *
-_decimal_Context_compare_signal_impl(PyObject *context, PyObject *x,
-                                     PyObject *y);
+_decimal_Context_minus_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x);
 
 static PyObject *
-_decimal_Context_compare_signal(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_minus(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "minus",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("compare_signal", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_compare_signal_impl(context, x, y);
+    return_value = _decimal_Context_minus_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_divide__doc__,
-"divide($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_next_minus__doc__,
+"next_minus($self, x, /)\n"
 "--\n"
 "\n"
-"Return x divided by y.");
+"Return the largest representable number smaller than x.");
 
-#define _DECIMAL_CONTEXT_DIVIDE_METHODDEF    \
-    {"divide", _PyCFunction_CAST(_decimal_Context_divide), METH_FASTCALL, _decimal_Context_divide__doc__},
+#define _DECIMAL_CONTEXT_NEXT_MINUS_METHODDEF    \
+    {"next_minus", _PyCFunction_CAST(_decimal_Context_next_minus), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_next_minus__doc__},
 
 static PyObject *
-_decimal_Context_divide_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_next_minus_impl(PyObject *context, PyTypeObject *cls,
+                                 PyObject *x);
 
 static PyObject *
-_decimal_Context_divide(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_next_minus(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "next_minus",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("divide", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_divide_impl(context, x, y);
+    return_value = _decimal_Context_next_minus_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_divide_int__doc__,
-"divide_int($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_next_plus__doc__,
+"next_plus($self, x, /)\n"
 "--\n"
 "\n"
-"Return x divided by y, truncated to an integer.");
+"Return the smallest representable number larger than x.");
 
-#define _DECIMAL_CONTEXT_DIVIDE_INT_METHODDEF    \
-    {"divide_int", _PyCFunction_CAST(_decimal_Context_divide_int), METH_FASTCALL, _decimal_Context_divide_int__doc__},
+#define _DECIMAL_CONTEXT_NEXT_PLUS_METHODDEF    \
+    {"next_plus", _PyCFunction_CAST(_decimal_Context_next_plus), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_next_plus__doc__},
 
 static PyObject *
-_decimal_Context_divide_int_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_next_plus_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x);
 
 static PyObject *
-_decimal_Context_divide_int(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_next_plus(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "next_plus",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("divide_int", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_divide_int_impl(context, x, y);
+    return_value = _decimal_Context_next_plus_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_max__doc__,
-"max($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_normalize__doc__,
+"normalize($self, x, /)\n"
 "--\n"
 "\n"
-"Compare the values numerically and return the maximum.");
+"Reduce x to its simplest form. Alias for reduce(x).");
 
-#define _DECIMAL_CONTEXT_MAX_METHODDEF    \
-    {"max", _PyCFunction_CAST(_decimal_Context_max), METH_FASTCALL, _decimal_Context_max__doc__},
+#define _DECIMAL_CONTEXT_NORMALIZE_METHODDEF    \
+    {"normalize", _PyCFunction_CAST(_decimal_Context_normalize), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_normalize__doc__},
 
 static PyObject *
-_decimal_Context_max_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_normalize_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x);
 
 static PyObject *
-_decimal_Context_max(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_normalize(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "normalize",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("max", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_max_impl(context, x, y);
+    return_value = _decimal_Context_normalize_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_max_mag__doc__,
-"max_mag($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_plus__doc__,
+"plus($self, x, /)\n"
 "--\n"
 "\n"
-"Compare the values numerically with their sign ignored.");
+"Plus corresponds to the unary prefix plus operator in Python.\n"
+"\n"
+"This operation applies the context to the result.");
 
-#define _DECIMAL_CONTEXT_MAX_MAG_METHODDEF    \
-    {"max_mag", _PyCFunction_CAST(_decimal_Context_max_mag), METH_FASTCALL, _decimal_Context_max_mag__doc__},
+#define _DECIMAL_CONTEXT_PLUS_METHODDEF    \
+    {"plus", _PyCFunction_CAST(_decimal_Context_plus), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_plus__doc__},
 
 static PyObject *
-_decimal_Context_max_mag_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_plus_impl(PyObject *context, PyTypeObject *cls, PyObject *x);
 
 static PyObject *
-_decimal_Context_max_mag(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_plus(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "plus",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("max_mag", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_max_mag_impl(context, x, y);
+    return_value = _decimal_Context_plus_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_min__doc__,
-"min($self, x, y, /)\n"
-"--\n"
+PyDoc_STRVAR(_decimal_Context_to_integral_value__doc__,
+"to_integral_value($self, x, /)\n"
+"--\n"
 "\n"
-"Compare the values numerically and return the minimum.");
+"Round to an integer.");
 
-#define _DECIMAL_CONTEXT_MIN_METHODDEF    \
-    {"min", _PyCFunction_CAST(_decimal_Context_min), METH_FASTCALL, _decimal_Context_min__doc__},
+#define _DECIMAL_CONTEXT_TO_INTEGRAL_VALUE_METHODDEF    \
+    {"to_integral_value", _PyCFunction_CAST(_decimal_Context_to_integral_value), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_to_integral_value__doc__},
 
 static PyObject *
-_decimal_Context_min_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_to_integral_value_impl(PyObject *context, PyTypeObject *cls,
+                                        PyObject *x);
 
 static PyObject *
-_decimal_Context_min(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_to_integral_value(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "to_integral_value",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("min", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_min_impl(context, x, y);
+    return_value = _decimal_Context_to_integral_value_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_min_mag__doc__,
-"min_mag($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_to_integral_exact__doc__,
+"to_integral_exact($self, x, /)\n"
 "--\n"
 "\n"
-"Compare the values numerically with their sign ignored.");
+"Round to an integer. Signal if the result is rounded or inexact.");
 
-#define _DECIMAL_CONTEXT_MIN_MAG_METHODDEF    \
-    {"min_mag", _PyCFunction_CAST(_decimal_Context_min_mag), METH_FASTCALL, _decimal_Context_min_mag__doc__},
+#define _DECIMAL_CONTEXT_TO_INTEGRAL_EXACT_METHODDEF    \
+    {"to_integral_exact", _PyCFunction_CAST(_decimal_Context_to_integral_exact), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_to_integral_exact__doc__},
 
 static PyObject *
-_decimal_Context_min_mag_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_to_integral_exact_impl(PyObject *context, PyTypeObject *cls,
+                                        PyObject *x);
 
 static PyObject *
-_decimal_Context_min_mag(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_to_integral_exact(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "to_integral_exact",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("min_mag", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_min_mag_impl(context, x, y);
+    return_value = _decimal_Context_to_integral_exact_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_multiply__doc__,
-"multiply($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_to_integral__doc__,
+"to_integral($self, x, /)\n"
 "--\n"
 "\n"
-"Return the product of x and y.");
+"Identical to to_integral_value(x).");
 
-#define _DECIMAL_CONTEXT_MULTIPLY_METHODDEF    \
-    {"multiply", _PyCFunction_CAST(_decimal_Context_multiply), METH_FASTCALL, _decimal_Context_multiply__doc__},
+#define _DECIMAL_CONTEXT_TO_INTEGRAL_METHODDEF    \
+    {"to_integral", _PyCFunction_CAST(_decimal_Context_to_integral), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_to_integral__doc__},
 
 static PyObject *
-_decimal_Context_multiply_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_to_integral_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x);
 
 static PyObject *
-_decimal_Context_multiply(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_to_integral(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "to_integral",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("multiply", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_multiply_impl(context, x, y);
+    return_value = _decimal_Context_to_integral_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_next_toward__doc__,
-"next_toward($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_sqrt__doc__,
+"sqrt($self, x, /)\n"
 "--\n"
 "\n"
-"Return the number closest to x, in the direction towards y.");
+"Square root of a non-negative number to context precision.");
 
-#define _DECIMAL_CONTEXT_NEXT_TOWARD_METHODDEF    \
-    {"next_toward", _PyCFunction_CAST(_decimal_Context_next_toward), METH_FASTCALL, _decimal_Context_next_toward__doc__},
+#define _DECIMAL_CONTEXT_SQRT_METHODDEF    \
+    {"sqrt", _PyCFunction_CAST(_decimal_Context_sqrt), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_sqrt__doc__},
 
 static PyObject *
-_decimal_Context_next_toward_impl(PyObject *context, PyObject *x,
-                                  PyObject *y);
+_decimal_Context_sqrt_impl(PyObject *context, PyTypeObject *cls, PyObject *x);
 
 static PyObject *
-_decimal_Context_next_toward(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_sqrt(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "sqrt",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
     PyObject *x;
-    PyObject *y;
 
-    if (!_PyArg_CheckPositional("next_toward", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
-    y = args[1];
-    return_value = _decimal_Context_next_toward_impl(context, x, y);
+    return_value = _decimal_Context_sqrt_impl(context, cls, x);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_quantize__doc__,
-"quantize($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_add__doc__,
+"add($self, x, y, /)\n"
 "--\n"
 "\n"
-"Return a value equal to x (rounded), having the exponent of y.");
+"Return the sum of x and y.");
 
-#define _DECIMAL_CONTEXT_QUANTIZE_METHODDEF    \
-    {"quantize", _PyCFunction_CAST(_decimal_Context_quantize), METH_FASTCALL, _decimal_Context_quantize__doc__},
+#define _DECIMAL_CONTEXT_ADD_METHODDEF    \
+    {"add", _PyCFunction_CAST(_decimal_Context_add), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_add__doc__},
 
 static PyObject *
-_decimal_Context_quantize_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_add_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y);
 
 static PyObject *
-_decimal_Context_quantize(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_add(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "add",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("quantize", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_quantize_impl(context, x, y);
+    return_value = _decimal_Context_add_impl(context, cls, x, y);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_remainder__doc__,
-"remainder($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_compare__doc__,
+"compare($self, x, y, /)\n"
 "--\n"
 "\n"
-"Return the remainder from integer division.\n"
-"\n"
-"The sign of the result, if non-zero, is the same as that of the\n"
-"original dividend.");
+"Compare x and y numerically.");
 
-#define _DECIMAL_CONTEXT_REMAINDER_METHODDEF    \
-    {"remainder", _PyCFunction_CAST(_decimal_Context_remainder), METH_FASTCALL, _decimal_Context_remainder__doc__},
+#define _DECIMAL_CONTEXT_COMPARE_METHODDEF    \
+    {"compare", _PyCFunction_CAST(_decimal_Context_compare), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_compare__doc__},
 
 static PyObject *
-_decimal_Context_remainder_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_compare_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_remainder(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_compare(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "compare",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("remainder", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_remainder_impl(context, x, y);
+    return_value = _decimal_Context_compare_impl(context, cls, x, y);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_remainder_near__doc__,
-"remainder_near($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_compare_signal__doc__,
+"compare_signal($self, x, y, /)\n"
 "--\n"
 "\n"
-"Return x - y * n.\n"
-"\n"
-"Here n is the integer nearest the exact value of x / y (if the result\n"
-"is 0 then its sign will be the sign of x).");
+"Compare x and y numerically.  All NaNs signal.");
 
-#define _DECIMAL_CONTEXT_REMAINDER_NEAR_METHODDEF    \
-    {"remainder_near", _PyCFunction_CAST(_decimal_Context_remainder_near), METH_FASTCALL, _decimal_Context_remainder_near__doc__},
+#define _DECIMAL_CONTEXT_COMPARE_SIGNAL_METHODDEF    \
+    {"compare_signal", _PyCFunction_CAST(_decimal_Context_compare_signal), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_compare_signal__doc__},
 
 static PyObject *
-_decimal_Context_remainder_near_impl(PyObject *context, PyObject *x,
-                                     PyObject *y);
+_decimal_Context_compare_signal_impl(PyObject *context, PyTypeObject *cls,
+                                     PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_remainder_near(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_compare_signal(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "compare_signal",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("remainder_near", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_remainder_near_impl(context, x, y);
+    return_value = _decimal_Context_compare_signal_impl(context, cls, x, y);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_subtract__doc__,
-"subtract($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_divide__doc__,
+"divide($self, x, y, /)\n"
 "--\n"
 "\n"
-"Return the difference between x and y.");
+"Return x divided by y.");
 
-#define _DECIMAL_CONTEXT_SUBTRACT_METHODDEF    \
-    {"subtract", _PyCFunction_CAST(_decimal_Context_subtract), METH_FASTCALL, _decimal_Context_subtract__doc__},
+#define _DECIMAL_CONTEXT_DIVIDE_METHODDEF    \
+    {"divide", _PyCFunction_CAST(_decimal_Context_divide), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_divide__doc__},
 
 static PyObject *
-_decimal_Context_subtract_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_divide_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_subtract(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_divide(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "divide",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("subtract", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_subtract_impl(context, x, y);
+    return_value = _decimal_Context_divide_impl(context, cls, x, y);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_divmod__doc__,
-"divmod($self, x, y, /)\n"
+PyDoc_STRVAR(_decimal_Context_divide_int__doc__,
+"divide_int($self, x, y, /)\n"
 "--\n"
 "\n"
-"Return quotient and remainder of the division x / y.");
+"Return x divided by y, truncated to an integer.");
 
-#define _DECIMAL_CONTEXT_DIVMOD_METHODDEF    \
-    {"divmod", _PyCFunction_CAST(_decimal_Context_divmod), METH_FASTCALL, _decimal_Context_divmod__doc__},
+#define _DECIMAL_CONTEXT_DIVIDE_INT_METHODDEF    \
+    {"divide_int", _PyCFunction_CAST(_decimal_Context_divide_int), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_divide_int__doc__},
 
 static PyObject *
-_decimal_Context_divmod_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_divide_int_impl(PyObject *context, PyTypeObject *cls,
+                                 PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_divmod(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_divide_int(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "divide_int",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("divmod", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_divmod_impl(context, x, y);
+    return_value = _decimal_Context_divide_int_impl(context, cls, x, y);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_power__doc__,
-"power($self, /, a, b, modulo=None)\n"
+PyDoc_STRVAR(_decimal_Context_max__doc__,
+"max($self, x, y, /)\n"
 "--\n"
 "\n"
-"Compute a**b.\n"
-"\n"
-"If \'a\' is negative, then \'b\' must be integral. The result will be\n"
-"inexact unless \'a\' is integral and the result is finite and can be\n"
-"expressed exactly in \'precision\' digits.  In the Python version the\n"
-"result is always correctly rounded, in the C version the result is\n"
-"almost always correctly rounded.\n"
-"\n"
-"If modulo is given, compute (a**b) % modulo. The following\n"
-"restrictions hold:\n"
-"\n"
-"    * all three arguments must be integral\n"
-"    * \'b\' must be nonnegative\n"
-"    * at least one of \'a\' or \'b\' must be nonzero\n"
-"    * modulo must be nonzero and less than 10**prec in absolute value");
+"Compare the values numerically and return the maximum.");
 
-#define _DECIMAL_CONTEXT_POWER_METHODDEF    \
-    {"power", _PyCFunction_CAST(_decimal_Context_power), METH_FASTCALL|METH_KEYWORDS, _decimal_Context_power__doc__},
+#define _DECIMAL_CONTEXT_MAX_METHODDEF    \
+    {"max", _PyCFunction_CAST(_decimal_Context_max), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_max__doc__},
 
 static PyObject *
-_decimal_Context_power_impl(PyObject *context, PyObject *base, PyObject *exp,
-                            PyObject *mod);
+_decimal_Context_max_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y);
 
 static PyObject *
-_decimal_Context_power(PyObject *context, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+_decimal_Context_max(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
     #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
-
-    #define NUM_KEYWORDS 3
-    static struct {
-        PyGC_Head _this_is_not_used;
-        PyObject_VAR_HEAD
-        Py_hash_t ob_hash;
-        PyObject *ob_item[NUM_KEYWORDS];
-    } _kwtuple = {
-        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
-        .ob_hash = -1,
-        .ob_item = { _Py_LATIN1_CHR('a'), _Py_LATIN1_CHR('b'), &_Py_ID(modulo), },
-    };
-    #undef NUM_KEYWORDS
-    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
-
-    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
     #  define KWTUPLE NULL
-    #endif  // !Py_BUILD_CORE
+    #endif
 
-    static const char * const _keywords[] = {"a", "b", "modulo", NULL};
+    static const char * const _keywords[] = {"", "", NULL};
     static _PyArg_Parser _parser = {
         .keywords = _keywords,
-        .fname = "power",
+        .fname = "max",
         .kwtuple = KWTUPLE,
     };
     #undef KWTUPLE
-    PyObject *argsbuf[3];
-    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
-    PyObject *base;
-    PyObject *exp;
-    PyObject *mod = Py_None;
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
 
     args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
     if (!args) {
         goto exit;
     }
-    base = args[0];
-    exp = args[1];
-    if (!noptargs) {
-        goto skip_optional_pos;
-    }
-    mod = args[2];
-skip_optional_pos:
-    return_value = _decimal_Context_power_impl(context, base, exp, mod);
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_max_impl(context, cls, x, y);
 
 exit:
     return return_value;
 }
 
-PyDoc_STRVAR(_decimal_Context_fma__doc__,
+PyDoc_STRVAR(_decimal_Context_max_mag__doc__,
+"max_mag($self, x, y, /)\n"
+"--\n"
+"\n"
+"Compare the values numerically with their sign ignored.");
+
+#define _DECIMAL_CONTEXT_MAX_MAG_METHODDEF    \
+    {"max_mag", _PyCFunction_CAST(_decimal_Context_max_mag), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_max_mag__doc__},
+
+static PyObject *
+_decimal_Context_max_mag_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_max_mag(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "max_mag",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_max_mag_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_min__doc__,
+"min($self, x, y, /)\n"
+"--\n"
+"\n"
+"Compare the values numerically and return the minimum.");
+
+#define _DECIMAL_CONTEXT_MIN_METHODDEF    \
+    {"min", _PyCFunction_CAST(_decimal_Context_min), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_min__doc__},
+
+static PyObject *
+_decimal_Context_min_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y);
+
+static PyObject *
+_decimal_Context_min(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "min",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_min_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_min_mag__doc__,
+"min_mag($self, x, y, /)\n"
+"--\n"
+"\n"
+"Compare the values numerically with their sign ignored.");
+
+#define _DECIMAL_CONTEXT_MIN_MAG_METHODDEF    \
+    {"min_mag", _PyCFunction_CAST(_decimal_Context_min_mag), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_min_mag__doc__},
+
+static PyObject *
+_decimal_Context_min_mag_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_min_mag(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "min_mag",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_min_mag_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_multiply__doc__,
+"multiply($self, x, y, /)\n"
+"--\n"
+"\n"
+"Return the product of x and y.");
+
+#define _DECIMAL_CONTEXT_MULTIPLY_METHODDEF    \
+    {"multiply", _PyCFunction_CAST(_decimal_Context_multiply), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_multiply__doc__},
+
+static PyObject *
+_decimal_Context_multiply_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_multiply(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "multiply",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_multiply_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_next_toward__doc__,
+"next_toward($self, x, y, /)\n"
+"--\n"
+"\n"
+"Return the number closest to x, in the direction towards y.");
+
+#define _DECIMAL_CONTEXT_NEXT_TOWARD_METHODDEF    \
+    {"next_toward", _PyCFunction_CAST(_decimal_Context_next_toward), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_next_toward__doc__},
+
+static PyObject *
+_decimal_Context_next_toward_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_next_toward(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "next_toward",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_next_toward_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_quantize__doc__,
+"quantize($self, x, y, /)\n"
+"--\n"
+"\n"
+"Return a value equal to x (rounded), having the exponent of y.");
+
+#define _DECIMAL_CONTEXT_QUANTIZE_METHODDEF    \
+    {"quantize", _PyCFunction_CAST(_decimal_Context_quantize), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_quantize__doc__},
+
+static PyObject *
+_decimal_Context_quantize_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_quantize(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "quantize",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_quantize_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_remainder__doc__,
+"remainder($self, x, y, /)\n"
+"--\n"
+"\n"
+"Return the remainder from integer division.\n"
+"\n"
+"The sign of the result, if non-zero, is the same as that of the\n"
+"original dividend.");
+
+#define _DECIMAL_CONTEXT_REMAINDER_METHODDEF    \
+    {"remainder", _PyCFunction_CAST(_decimal_Context_remainder), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_remainder__doc__},
+
+static PyObject *
+_decimal_Context_remainder_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_remainder(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "remainder",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_remainder_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_remainder_near__doc__,
+"remainder_near($self, x, y, /)\n"
+"--\n"
+"\n"
+"Return x - y * n.\n"
+"\n"
+"Here n is the integer nearest the exact value of x / y (if the result\n"
+"is 0 then its sign will be the sign of x).");
+
+#define _DECIMAL_CONTEXT_REMAINDER_NEAR_METHODDEF    \
+    {"remainder_near", _PyCFunction_CAST(_decimal_Context_remainder_near), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_remainder_near__doc__},
+
+static PyObject *
+_decimal_Context_remainder_near_impl(PyObject *context, PyTypeObject *cls,
+                                     PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_remainder_near(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "remainder_near",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_remainder_near_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_subtract__doc__,
+"subtract($self, x, y, /)\n"
+"--\n"
+"\n"
+"Return the difference between x and y.");
+
+#define _DECIMAL_CONTEXT_SUBTRACT_METHODDEF    \
+    {"subtract", _PyCFunction_CAST(_decimal_Context_subtract), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_subtract__doc__},
+
+static PyObject *
+_decimal_Context_subtract_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_subtract(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "subtract",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *x;
+    PyObject *y;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_subtract_impl(context, cls, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_divmod__doc__,
+"divmod($self, x, y, /)\n"
+"--\n"
+"\n"
+"Return quotient and remainder of the division x / y.");
+
+#define _DECIMAL_CONTEXT_DIVMOD_METHODDEF    \
+    {"divmod", _PyCFunction_CAST(_decimal_Context_divmod), METH_FASTCALL, _decimal_Context_divmod__doc__},
+
+static PyObject *
+_decimal_Context_divmod_impl(PyObject *context, PyObject *x, PyObject *y);
+
+static PyObject *
+_decimal_Context_divmod(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *x;
+    PyObject *y;
+
+    if (!_PyArg_CheckPositional("divmod", nargs, 2, 2)) {
+        goto exit;
+    }
+    x = args[0];
+    y = args[1];
+    return_value = _decimal_Context_divmod_impl(context, x, y);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_power__doc__,
+"power($self, /, a, b, modulo=None)\n"
+"--\n"
+"\n"
+"Compute a**b.\n"
+"\n"
+"If \'a\' is negative, then \'b\' must be integral. The result will be\n"
+"inexact unless \'a\' is integral and the result is finite and can be\n"
+"expressed exactly in \'precision\' digits.  In the Python version the\n"
+"result is always correctly rounded, in the C version the result is\n"
+"almost always correctly rounded.\n"
+"\n"
+"If modulo is given, compute (a**b) % modulo. The following\n"
+"restrictions hold:\n"
+"\n"
+"    * all three arguments must be integral\n"
+"    * \'b\' must be nonnegative\n"
+"    * at least one of \'a\' or \'b\' must be nonzero\n"
+"    * modulo must be nonzero and less than 10**prec in absolute value");
+
+#define _DECIMAL_CONTEXT_POWER_METHODDEF    \
+    {"power", _PyCFunction_CAST(_decimal_Context_power), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_power__doc__},
+
+static PyObject *
+_decimal_Context_power_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *base, PyObject *exp, PyObject *mod);
+
+static PyObject *
+_decimal_Context_power(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 3
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        Py_hash_t ob_hash;
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_hash = -1,
+        .ob_item = { _Py_LATIN1_CHR('a'), _Py_LATIN1_CHR('b'), &_Py_ID(modulo), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"a", "b", "modulo", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "power",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[3];
+    Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
+    PyObject *base;
+    PyObject *exp;
+    PyObject *mod = Py_None;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    base = args[0];
+    exp = args[1];
+    if (!noptargs) {
+        goto skip_optional_pos;
+    }
+    mod = args[2];
+skip_optional_pos:
+    return_value = _decimal_Context_power_impl(context, cls, base, exp, mod);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_fma__doc__,
 "fma($self, x, y, z, /)\n"
 "--\n"
 "\n"
 "Return x multiplied by y, plus z.");
 
 #define _DECIMAL_CONTEXT_FMA_METHODDEF    \
-    {"fma", _PyCFunction_CAST(_decimal_Context_fma), METH_FASTCALL, _decimal_Context_fma__doc__},
+    {"fma", _PyCFunction_CAST(_decimal_Context_fma), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_fma__doc__},
 
 static PyObject *
-_decimal_Context_fma_impl(PyObject *context, PyObject *x, PyObject *y,
-                          PyObject *z);
+_decimal_Context_fma_impl(PyObject *context, PyTypeObject *cls, PyObject *x,
+                          PyObject *y, PyObject *z);
 
 static PyObject *
-_decimal_Context_fma(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_fma(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "fma",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[3];
     PyObject *x;
     PyObject *y;
     PyObject *z;
 
-    if (!_PyArg_CheckPositional("fma", nargs, 3, 3)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 3, /*maxpos*/ 3, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
     z = args[2];
-    return_value = _decimal_Context_fma_impl(context, x, y, z);
+    return_value = _decimal_Context_fma_impl(context, cls, x, y, z);
 
 exit:
     return return_value;
@@ -4388,15 +5448,19 @@ PyDoc_STRVAR(_decimal_Context_radix__doc__,
 "Return 10.");
 
 #define _DECIMAL_CONTEXT_RADIX_METHODDEF    \
-    {"radix", (PyCFunction)_decimal_Context_radix, METH_NOARGS, _decimal_Context_radix__doc__},
+    {"radix", _PyCFunction_CAST(_decimal_Context_radix), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_radix__doc__},
 
 static PyObject *
-_decimal_Context_radix_impl(PyObject *context);
+_decimal_Context_radix_impl(PyObject *context, PyTypeObject *cls);
 
 static PyObject *
-_decimal_Context_radix(PyObject *context, PyObject *Py_UNUSED(ignored))
+_decimal_Context_radix(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
-    return _decimal_Context_radix_impl(context);
+    if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) {
+        PyErr_SetString(PyExc_TypeError, "radix() takes no arguments");
+        return NULL;
+    }
+    return _decimal_Context_radix_impl(context, cls);
 }
 
 PyDoc_STRVAR(_decimal_Context_is_normal__doc__,
@@ -4406,7 +5470,43 @@ PyDoc_STRVAR(_decimal_Context_is_normal__doc__,
 "Return True if x is a normal number, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_NORMAL_METHODDEF    \
-    {"is_normal", (PyCFunction)_decimal_Context_is_normal, METH_O, _decimal_Context_is_normal__doc__},
+    {"is_normal", _PyCFunction_CAST(_decimal_Context_is_normal), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_normal__doc__},
+
+static PyObject *
+_decimal_Context_is_normal_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x);
+
+static PyObject *
+_decimal_Context_is_normal(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_normal",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_normal_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_subnormal__doc__,
 "is_subnormal($self, x, /)\n"
@@ -4415,7 +5515,43 @@ PyDoc_STRVAR(_decimal_Context_is_subnormal__doc__,
 "Return True if x is subnormal, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_SUBNORMAL_METHODDEF    \
-    {"is_subnormal", (PyCFunction)_decimal_Context_is_subnormal, METH_O, _decimal_Context_is_subnormal__doc__},
+    {"is_subnormal", _PyCFunction_CAST(_decimal_Context_is_subnormal), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_subnormal__doc__},
+
+static PyObject *
+_decimal_Context_is_subnormal_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x);
+
+static PyObject *
+_decimal_Context_is_subnormal(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_subnormal",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_subnormal_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_finite__doc__,
 "is_finite($self, x, /)\n"
@@ -4424,7 +5560,43 @@ PyDoc_STRVAR(_decimal_Context_is_finite__doc__,
 "Return True if x is finite, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_FINITE_METHODDEF    \
-    {"is_finite", (PyCFunction)_decimal_Context_is_finite, METH_O, _decimal_Context_is_finite__doc__},
+    {"is_finite", _PyCFunction_CAST(_decimal_Context_is_finite), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_finite__doc__},
+
+static PyObject *
+_decimal_Context_is_finite_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x);
+
+static PyObject *
+_decimal_Context_is_finite(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_finite",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_finite_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_infinite__doc__,
 "is_infinite($self, x, /)\n"
@@ -4433,7 +5605,43 @@ PyDoc_STRVAR(_decimal_Context_is_infinite__doc__,
 "Return True if x is infinite, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_INFINITE_METHODDEF    \
-    {"is_infinite", (PyCFunction)_decimal_Context_is_infinite, METH_O, _decimal_Context_is_infinite__doc__},
+    {"is_infinite", _PyCFunction_CAST(_decimal_Context_is_infinite), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_infinite__doc__},
+
+static PyObject *
+_decimal_Context_is_infinite_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x);
+
+static PyObject *
+_decimal_Context_is_infinite(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_infinite",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_infinite_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_nan__doc__,
 "is_nan($self, x, /)\n"
@@ -4442,7 +5650,43 @@ PyDoc_STRVAR(_decimal_Context_is_nan__doc__,
 "Return True if x is a qNaN or sNaN, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_NAN_METHODDEF    \
-    {"is_nan", (PyCFunction)_decimal_Context_is_nan, METH_O, _decimal_Context_is_nan__doc__},
+    {"is_nan", _PyCFunction_CAST(_decimal_Context_is_nan), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_nan__doc__},
+
+static PyObject *
+_decimal_Context_is_nan_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x);
+
+static PyObject *
+_decimal_Context_is_nan(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_nan",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_nan_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_qnan__doc__,
 "is_qnan($self, x, /)\n"
@@ -4451,7 +5695,43 @@ PyDoc_STRVAR(_decimal_Context_is_qnan__doc__,
 "Return True if x is a quiet NaN, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_QNAN_METHODDEF    \
-    {"is_qnan", (PyCFunction)_decimal_Context_is_qnan, METH_O, _decimal_Context_is_qnan__doc__},
+    {"is_qnan", _PyCFunction_CAST(_decimal_Context_is_qnan), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_qnan__doc__},
+
+static PyObject *
+_decimal_Context_is_qnan_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x);
+
+static PyObject *
+_decimal_Context_is_qnan(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_qnan",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_qnan_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_snan__doc__,
 "is_snan($self, x, /)\n"
@@ -4459,8 +5739,44 @@ PyDoc_STRVAR(_decimal_Context_is_snan__doc__,
 "\n"
 "Return True if x is a signaling NaN, False otherwise.");
 
-#define _DECIMAL_CONTEXT_IS_SNAN_METHODDEF    \
-    {"is_snan", (PyCFunction)_decimal_Context_is_snan, METH_O, _decimal_Context_is_snan__doc__},
+#define _DECIMAL_CONTEXT_IS_SNAN_METHODDEF    \
+    {"is_snan", _PyCFunction_CAST(_decimal_Context_is_snan), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_snan__doc__},
+
+static PyObject *
+_decimal_Context_is_snan_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x);
+
+static PyObject *
+_decimal_Context_is_snan(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_snan",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_snan_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_signed__doc__,
 "is_signed($self, x, /)\n"
@@ -4469,7 +5785,43 @@ PyDoc_STRVAR(_decimal_Context_is_signed__doc__,
 "Return True if x is negative, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_SIGNED_METHODDEF    \
-    {"is_signed", (PyCFunction)_decimal_Context_is_signed, METH_O, _decimal_Context_is_signed__doc__},
+    {"is_signed", _PyCFunction_CAST(_decimal_Context_is_signed), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_signed__doc__},
+
+static PyObject *
+_decimal_Context_is_signed_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x);
+
+static PyObject *
+_decimal_Context_is_signed(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_signed",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_signed_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_zero__doc__,
 "is_zero($self, x, /)\n"
@@ -4478,7 +5830,43 @@ PyDoc_STRVAR(_decimal_Context_is_zero__doc__,
 "Return True if x is a zero, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_ZERO_METHODDEF    \
-    {"is_zero", (PyCFunction)_decimal_Context_is_zero, METH_O, _decimal_Context_is_zero__doc__},
+    {"is_zero", _PyCFunction_CAST(_decimal_Context_is_zero), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_zero__doc__},
+
+static PyObject *
+_decimal_Context_is_zero_impl(PyObject *context, PyTypeObject *cls,
+                              PyObject *x);
+
+static PyObject *
+_decimal_Context_is_zero(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_zero",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_zero_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_is_canonical__doc__,
 "is_canonical($self, x, /)\n"
@@ -4487,7 +5875,43 @@ PyDoc_STRVAR(_decimal_Context_is_canonical__doc__,
 "Return True if x is canonical, False otherwise.");
 
 #define _DECIMAL_CONTEXT_IS_CANONICAL_METHODDEF    \
-    {"is_canonical", (PyCFunction)_decimal_Context_is_canonical, METH_O, _decimal_Context_is_canonical__doc__},
+    {"is_canonical", _PyCFunction_CAST(_decimal_Context_is_canonical), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_is_canonical__doc__},
+
+static PyObject *
+_decimal_Context_is_canonical_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x);
+
+static PyObject *
+_decimal_Context_is_canonical(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "is_canonical",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_is_canonical_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context__apply__doc__,
 "_apply($self, x, /)\n"
@@ -4496,7 +5920,43 @@ PyDoc_STRVAR(_decimal_Context__apply__doc__,
 "Apply self to Decimal x.");
 
 #define _DECIMAL_CONTEXT__APPLY_METHODDEF    \
-    {"_apply", (PyCFunction)_decimal_Context__apply, METH_O, _decimal_Context__apply__doc__},
+    {"_apply", _PyCFunction_CAST(_decimal_Context__apply), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context__apply__doc__},
+
+static PyObject *
+_decimal_Context__apply_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x);
+
+static PyObject *
+_decimal_Context__apply(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "_apply",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context__apply_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 #if defined(EXTRA_FUNCTIONALITY)
 
@@ -4507,7 +5967,43 @@ PyDoc_STRVAR(_decimal_Context_apply__doc__,
 "Apply self to Decimal x.");
 
 #define _DECIMAL_CONTEXT_APPLY_METHODDEF    \
-    {"apply", (PyCFunction)_decimal_Context_apply, METH_O, _decimal_Context_apply__doc__},
+    {"apply", _PyCFunction_CAST(_decimal_Context_apply), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_apply__doc__},
+
+static PyObject *
+_decimal_Context_apply_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x);
+
+static PyObject *
+_decimal_Context_apply(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "apply",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_apply_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 #endif /* defined(EXTRA_FUNCTIONALITY) */
 
@@ -4518,7 +6014,43 @@ PyDoc_STRVAR(_decimal_Context_canonical__doc__,
 "Return a new instance of x.");
 
 #define _DECIMAL_CONTEXT_CANONICAL_METHODDEF    \
-    {"canonical", (PyCFunction)_decimal_Context_canonical, METH_O, _decimal_Context_canonical__doc__},
+    {"canonical", _PyCFunction_CAST(_decimal_Context_canonical), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_canonical__doc__},
+
+static PyObject *
+_decimal_Context_canonical_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x);
+
+static PyObject *
+_decimal_Context_canonical(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "canonical",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_canonical_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_copy_abs__doc__,
 "copy_abs($self, x, /)\n"
@@ -4527,7 +6059,43 @@ PyDoc_STRVAR(_decimal_Context_copy_abs__doc__,
 "Return a copy of x with the sign set to 0.");
 
 #define _DECIMAL_CONTEXT_COPY_ABS_METHODDEF    \
-    {"copy_abs", (PyCFunction)_decimal_Context_copy_abs, METH_O, _decimal_Context_copy_abs__doc__},
+    {"copy_abs", _PyCFunction_CAST(_decimal_Context_copy_abs), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_copy_abs__doc__},
+
+static PyObject *
+_decimal_Context_copy_abs_impl(PyObject *context, PyTypeObject *cls,
+                               PyObject *x);
+
+static PyObject *
+_decimal_Context_copy_abs(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "copy_abs",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_copy_abs_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_copy_decimal__doc__,
 "copy_decimal($self, x, /)\n"
@@ -4536,7 +6104,43 @@ PyDoc_STRVAR(_decimal_Context_copy_decimal__doc__,
 "Return a copy of Decimal x.");
 
 #define _DECIMAL_CONTEXT_COPY_DECIMAL_METHODDEF    \
-    {"copy_decimal", (PyCFunction)_decimal_Context_copy_decimal, METH_O, _decimal_Context_copy_decimal__doc__},
+    {"copy_decimal", _PyCFunction_CAST(_decimal_Context_copy_decimal), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_copy_decimal__doc__},
+
+static PyObject *
+_decimal_Context_copy_decimal_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x);
+
+static PyObject *
+_decimal_Context_copy_decimal(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "copy_decimal",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_copy_decimal_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_copy_negate__doc__,
 "copy_negate($self, x, /)\n"
@@ -4544,17 +6148,88 @@ PyDoc_STRVAR(_decimal_Context_copy_negate__doc__,
 "\n"
 "Return a copy of x with the sign inverted.");
 
-#define _DECIMAL_CONTEXT_COPY_NEGATE_METHODDEF    \
-    {"copy_negate", (PyCFunction)_decimal_Context_copy_negate, METH_O, _decimal_Context_copy_negate__doc__},
+#define _DECIMAL_CONTEXT_COPY_NEGATE_METHODDEF    \
+    {"copy_negate", _PyCFunction_CAST(_decimal_Context_copy_negate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_copy_negate__doc__},
+
+static PyObject *
+_decimal_Context_copy_negate_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x);
+
+static PyObject *
+_decimal_Context_copy_negate(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "copy_negate",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_copy_negate_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(_decimal_Context_logb__doc__,
+"logb($self, x, /)\n"
+"--\n"
+"\n"
+"Return the exponent of the magnitude of the operand\'s MSD.");
+
+#define _DECIMAL_CONTEXT_LOGB_METHODDEF    \
+    {"logb", _PyCFunction_CAST(_decimal_Context_logb), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_logb__doc__},
+
+static PyObject *
+_decimal_Context_logb_impl(PyObject *context, PyTypeObject *cls, PyObject *x);
+
+static PyObject *
+_decimal_Context_logb(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "logb",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
 
-PyDoc_STRVAR(_decimal_Context_logb__doc__,
-"logb($self, x, /)\n"
-"--\n"
-"\n"
-"Return the exponent of the magnitude of the operand\'s MSD.");
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_logb_impl(context, cls, x);
 
-#define _DECIMAL_CONTEXT_LOGB_METHODDEF    \
-    {"logb", (PyCFunction)_decimal_Context_logb, METH_O, _decimal_Context_logb__doc__},
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_logical_invert__doc__,
 "logical_invert($self, x, /)\n"
@@ -4563,7 +6238,43 @@ PyDoc_STRVAR(_decimal_Context_logical_invert__doc__,
 "Invert all digits of x.");
 
 #define _DECIMAL_CONTEXT_LOGICAL_INVERT_METHODDEF    \
-    {"logical_invert", (PyCFunction)_decimal_Context_logical_invert, METH_O, _decimal_Context_logical_invert__doc__},
+    {"logical_invert", _PyCFunction_CAST(_decimal_Context_logical_invert), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_logical_invert__doc__},
+
+static PyObject *
+_decimal_Context_logical_invert_impl(PyObject *context, PyTypeObject *cls,
+                                     PyObject *x);
+
+static PyObject *
+_decimal_Context_logical_invert(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "logical_invert",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_logical_invert_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_number_class__doc__,
 "number_class($self, x, /)\n"
@@ -4572,7 +6283,43 @@ PyDoc_STRVAR(_decimal_Context_number_class__doc__,
 "Return an indication of the class of x.");
 
 #define _DECIMAL_CONTEXT_NUMBER_CLASS_METHODDEF    \
-    {"number_class", (PyCFunction)_decimal_Context_number_class, METH_O, _decimal_Context_number_class__doc__},
+    {"number_class", _PyCFunction_CAST(_decimal_Context_number_class), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_number_class__doc__},
+
+static PyObject *
+_decimal_Context_number_class_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x);
+
+static PyObject *
+_decimal_Context_number_class(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "number_class",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_number_class_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_to_sci_string__doc__,
 "to_sci_string($self, x, /)\n"
@@ -4581,7 +6328,43 @@ PyDoc_STRVAR(_decimal_Context_to_sci_string__doc__,
 "Convert a number to a string using scientific notation.");
 
 #define _DECIMAL_CONTEXT_TO_SCI_STRING_METHODDEF    \
-    {"to_sci_string", (PyCFunction)_decimal_Context_to_sci_string, METH_O, _decimal_Context_to_sci_string__doc__},
+    {"to_sci_string", _PyCFunction_CAST(_decimal_Context_to_sci_string), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_to_sci_string__doc__},
+
+static PyObject *
+_decimal_Context_to_sci_string_impl(PyObject *context, PyTypeObject *cls,
+                                    PyObject *x);
+
+static PyObject *
+_decimal_Context_to_sci_string(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "to_sci_string",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_to_sci_string_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_to_eng_string__doc__,
 "to_eng_string($self, x, /)\n"
@@ -4590,7 +6373,43 @@ PyDoc_STRVAR(_decimal_Context_to_eng_string__doc__,
 "Convert a number to a string, using engineering notation.");
 
 #define _DECIMAL_CONTEXT_TO_ENG_STRING_METHODDEF    \
-    {"to_eng_string", (PyCFunction)_decimal_Context_to_eng_string, METH_O, _decimal_Context_to_eng_string__doc__},
+    {"to_eng_string", _PyCFunction_CAST(_decimal_Context_to_eng_string), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_to_eng_string__doc__},
+
+static PyObject *
+_decimal_Context_to_eng_string_impl(PyObject *context, PyTypeObject *cls,
+                                    PyObject *x);
+
+static PyObject *
+_decimal_Context_to_eng_string(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "to_eng_string",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *x;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    x = args[0];
+    return_value = _decimal_Context_to_eng_string_impl(context, cls, x);
+
+exit:
+    return return_value;
+}
 
 PyDoc_STRVAR(_decimal_Context_compare_total__doc__,
 "compare_total($self, x, y, /)\n"
@@ -4599,25 +6418,41 @@ PyDoc_STRVAR(_decimal_Context_compare_total__doc__,
 "Compare x and y using their abstract representation.");
 
 #define _DECIMAL_CONTEXT_COMPARE_TOTAL_METHODDEF    \
-    {"compare_total", _PyCFunction_CAST(_decimal_Context_compare_total), METH_FASTCALL, _decimal_Context_compare_total__doc__},
+    {"compare_total", _PyCFunction_CAST(_decimal_Context_compare_total), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_compare_total__doc__},
 
 static PyObject *
-_decimal_Context_compare_total_impl(PyObject *context, PyObject *x,
-                                    PyObject *y);
+_decimal_Context_compare_total_impl(PyObject *context, PyTypeObject *cls,
+                                    PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_compare_total(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_compare_total(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "compare_total",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("compare_total", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_compare_total_impl(context, x, y);
+    return_value = _decimal_Context_compare_total_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4630,25 +6465,41 @@ PyDoc_STRVAR(_decimal_Context_compare_total_mag__doc__,
 "Compare x and y using their abstract representation, ignoring sign.");
 
 #define _DECIMAL_CONTEXT_COMPARE_TOTAL_MAG_METHODDEF    \
-    {"compare_total_mag", _PyCFunction_CAST(_decimal_Context_compare_total_mag), METH_FASTCALL, _decimal_Context_compare_total_mag__doc__},
+    {"compare_total_mag", _PyCFunction_CAST(_decimal_Context_compare_total_mag), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_compare_total_mag__doc__},
 
 static PyObject *
-_decimal_Context_compare_total_mag_impl(PyObject *context, PyObject *x,
-                                        PyObject *y);
+_decimal_Context_compare_total_mag_impl(PyObject *context, PyTypeObject *cls,
+                                        PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_compare_total_mag(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_compare_total_mag(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "compare_total_mag",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("compare_total_mag", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_compare_total_mag_impl(context, x, y);
+    return_value = _decimal_Context_compare_total_mag_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4661,24 +6512,41 @@ PyDoc_STRVAR(_decimal_Context_copy_sign__doc__,
 "Copy the sign from y to x.");
 
 #define _DECIMAL_CONTEXT_COPY_SIGN_METHODDEF    \
-    {"copy_sign", _PyCFunction_CAST(_decimal_Context_copy_sign), METH_FASTCALL, _decimal_Context_copy_sign__doc__},
+    {"copy_sign", _PyCFunction_CAST(_decimal_Context_copy_sign), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_copy_sign__doc__},
 
 static PyObject *
-_decimal_Context_copy_sign_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_copy_sign_impl(PyObject *context, PyTypeObject *cls,
+                                PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_copy_sign(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_copy_sign(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "copy_sign",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("copy_sign", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_copy_sign_impl(context, x, y);
+    return_value = _decimal_Context_copy_sign_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4691,25 +6559,41 @@ PyDoc_STRVAR(_decimal_Context_logical_and__doc__,
 "Digit-wise and of x and y.");
 
 #define _DECIMAL_CONTEXT_LOGICAL_AND_METHODDEF    \
-    {"logical_and", _PyCFunction_CAST(_decimal_Context_logical_and), METH_FASTCALL, _decimal_Context_logical_and__doc__},
+    {"logical_and", _PyCFunction_CAST(_decimal_Context_logical_and), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_logical_and__doc__},
 
 static PyObject *
-_decimal_Context_logical_and_impl(PyObject *context, PyObject *x,
-                                  PyObject *y);
+_decimal_Context_logical_and_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_logical_and(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_logical_and(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "logical_and",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("logical_and", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_logical_and_impl(context, x, y);
+    return_value = _decimal_Context_logical_and_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4722,24 +6606,41 @@ PyDoc_STRVAR(_decimal_Context_logical_or__doc__,
 "Digit-wise or of x and y.");
 
 #define _DECIMAL_CONTEXT_LOGICAL_OR_METHODDEF    \
-    {"logical_or", _PyCFunction_CAST(_decimal_Context_logical_or), METH_FASTCALL, _decimal_Context_logical_or__doc__},
+    {"logical_or", _PyCFunction_CAST(_decimal_Context_logical_or), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_logical_or__doc__},
 
 static PyObject *
-_decimal_Context_logical_or_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_logical_or_impl(PyObject *context, PyTypeObject *cls,
+                                 PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_logical_or(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_logical_or(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "logical_or",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("logical_or", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_logical_or_impl(context, x, y);
+    return_value = _decimal_Context_logical_or_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4752,25 +6653,41 @@ PyDoc_STRVAR(_decimal_Context_logical_xor__doc__,
 "Digit-wise xor of x and y.");
 
 #define _DECIMAL_CONTEXT_LOGICAL_XOR_METHODDEF    \
-    {"logical_xor", _PyCFunction_CAST(_decimal_Context_logical_xor), METH_FASTCALL, _decimal_Context_logical_xor__doc__},
+    {"logical_xor", _PyCFunction_CAST(_decimal_Context_logical_xor), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_logical_xor__doc__},
 
 static PyObject *
-_decimal_Context_logical_xor_impl(PyObject *context, PyObject *x,
-                                  PyObject *y);
+_decimal_Context_logical_xor_impl(PyObject *context, PyTypeObject *cls,
+                                  PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_logical_xor(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_logical_xor(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "logical_xor",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("logical_xor", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_logical_xor_impl(context, x, y);
+    return_value = _decimal_Context_logical_xor_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4783,24 +6700,41 @@ PyDoc_STRVAR(_decimal_Context_rotate__doc__,
 "Return a copy of x, rotated by y places.");
 
 #define _DECIMAL_CONTEXT_ROTATE_METHODDEF    \
-    {"rotate", _PyCFunction_CAST(_decimal_Context_rotate), METH_FASTCALL, _decimal_Context_rotate__doc__},
+    {"rotate", _PyCFunction_CAST(_decimal_Context_rotate), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_rotate__doc__},
 
 static PyObject *
-_decimal_Context_rotate_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_rotate_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_rotate(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_rotate(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "rotate",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("rotate", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_rotate_impl(context, x, y);
+    return_value = _decimal_Context_rotate_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4813,24 +6747,41 @@ PyDoc_STRVAR(_decimal_Context_scaleb__doc__,
 "Return the first operand after adding the second value to its exp.");
 
 #define _DECIMAL_CONTEXT_SCALEB_METHODDEF    \
-    {"scaleb", _PyCFunction_CAST(_decimal_Context_scaleb), METH_FASTCALL, _decimal_Context_scaleb__doc__},
+    {"scaleb", _PyCFunction_CAST(_decimal_Context_scaleb), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_scaleb__doc__},
 
 static PyObject *
-_decimal_Context_scaleb_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_scaleb_impl(PyObject *context, PyTypeObject *cls,
+                             PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_scaleb(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_scaleb(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "scaleb",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("scaleb", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_scaleb_impl(context, x, y);
+    return_value = _decimal_Context_scaleb_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4843,24 +6794,41 @@ PyDoc_STRVAR(_decimal_Context_shift__doc__,
 "Return a copy of x, shifted by y places.");
 
 #define _DECIMAL_CONTEXT_SHIFT_METHODDEF    \
-    {"shift", _PyCFunction_CAST(_decimal_Context_shift), METH_FASTCALL, _decimal_Context_shift__doc__},
+    {"shift", _PyCFunction_CAST(_decimal_Context_shift), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_shift__doc__},
 
 static PyObject *
-_decimal_Context_shift_impl(PyObject *context, PyObject *x, PyObject *y);
+_decimal_Context_shift_impl(PyObject *context, PyTypeObject *cls,
+                            PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_shift(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_shift(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "shift",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("shift", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_shift_impl(context, x, y);
+    return_value = _decimal_Context_shift_impl(context, cls, x, y);
 
 exit:
     return return_value;
@@ -4873,31 +6841,59 @@ PyDoc_STRVAR(_decimal_Context_same_quantum__doc__,
 "Return True if the two operands have the same exponent.");
 
 #define _DECIMAL_CONTEXT_SAME_QUANTUM_METHODDEF    \
-    {"same_quantum", _PyCFunction_CAST(_decimal_Context_same_quantum), METH_FASTCALL, _decimal_Context_same_quantum__doc__},
+    {"same_quantum", _PyCFunction_CAST(_decimal_Context_same_quantum), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _decimal_Context_same_quantum__doc__},
 
 static PyObject *
-_decimal_Context_same_quantum_impl(PyObject *context, PyObject *x,
-                                   PyObject *y);
+_decimal_Context_same_quantum_impl(PyObject *context, PyTypeObject *cls,
+                                   PyObject *x, PyObject *y);
 
 static PyObject *
-_decimal_Context_same_quantum(PyObject *context, PyObject *const *args, Py_ssize_t nargs)
+_decimal_Context_same_quantum(PyObject *context, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
 {
     PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+    #  define KWTUPLE (PyObject *)&_Py_SINGLETON(tuple_empty)
+    #else
+    #  define KWTUPLE NULL
+    #endif
+
+    static const char * const _keywords[] = {"", "", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "same_quantum",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
     PyObject *x;
     PyObject *y;
 
-    if (!_PyArg_CheckPositional("same_quantum", nargs, 2, 2)) {
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
+            /*minpos*/ 2, /*maxpos*/ 2, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
+    if (!args) {
         goto exit;
     }
     x = args[0];
     y = args[1];
-    return_value = _decimal_Context_same_quantum_impl(context, x, y);
+    return_value = _decimal_Context_same_quantum_impl(context, cls, x, y);
 
 exit:
     return return_value;
 }
 
+#ifndef _DECIMAL_CONTEXT__UNSAFE_SETPREC_METHODDEF
+    #define _DECIMAL_CONTEXT__UNSAFE_SETPREC_METHODDEF
+#endif /* !defined(_DECIMAL_CONTEXT__UNSAFE_SETPREC_METHODDEF) */
+
+#ifndef _DECIMAL_CONTEXT__UNSAFE_SETEMIN_METHODDEF
+    #define _DECIMAL_CONTEXT__UNSAFE_SETEMIN_METHODDEF
+#endif /* !defined(_DECIMAL_CONTEXT__UNSAFE_SETEMIN_METHODDEF) */
+
+#ifndef _DECIMAL_CONTEXT__UNSAFE_SETEMAX_METHODDEF
+    #define _DECIMAL_CONTEXT__UNSAFE_SETEMAX_METHODDEF
+#endif /* !defined(_DECIMAL_CONTEXT__UNSAFE_SETEMAX_METHODDEF) */
+
 #ifndef _DECIMAL_CONTEXT_APPLY_METHODDEF
     #define _DECIMAL_CONTEXT_APPLY_METHODDEF
 #endif /* !defined(_DECIMAL_CONTEXT_APPLY_METHODDEF) */
-/*[clinic end generated code: output=1e10ddd6610e17dc input=a9049054013a1b77]*/
+/*[clinic end generated code: output=e938de3a355a353a input=a9049054013a1b77]*/