Skip to content

Commit c056a08

Browse files
gh-73487: Convert _decimal to use Argument Clinic (part 4) (#137931)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
1 parent 7dc42b6 commit c056a08

File tree

3 files changed

+488
-128
lines changed

3 files changed

+488
-128
lines changed

Modules/_decimal/_decimal.c

Lines changed: 154 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -923,14 +923,34 @@ context_getallcr(PyObject *self, void *Py_UNUSED(closure))
923923
}
924924
#endif
925925

926+
/*[clinic input]
927+
_decimal.Context.Etiny
928+
929+
Return a value equal to Emin - prec + 1.
930+
931+
This is the minimum exponent value for subnormal results. When
932+
underflow occurs, the exponent is set to Etiny.
933+
[clinic start generated code]*/
934+
926935
static PyObject *
927-
context_getetiny(PyObject *self, PyObject *Py_UNUSED(dummy))
936+
_decimal_Context_Etiny_impl(PyObject *self)
937+
/*[clinic end generated code: output=c9a4a1a3e3575289 input=1274040f303f2244]*/
928938
{
929939
return PyLong_FromSsize_t(mpd_etiny(CTX(self)));
930940
}
931941

942+
/*[clinic input]
943+
_decimal.Context.Etop
944+
945+
Return a value equal to Emax - prec + 1.
946+
947+
This is the maximum exponent if the _clamp field of the context is set
948+
to 1 (IEEE clamp mode). Etop() must not be negative.
949+
[clinic start generated code]*/
950+
932951
static PyObject *
933-
context_getetop(PyObject *self, PyObject *Py_UNUSED(dummy))
952+
_decimal_Context_Etop_impl(PyObject *self)
953+
/*[clinic end generated code: output=f0a3f6e1b829074e input=838a4409316ec728]*/
934954
{
935955
return PyLong_FromSsize_t(mpd_etop(CTX(self)));
936956
}
@@ -3149,21 +3169,29 @@ PyDec_FromObject(PyObject *v, PyObject *context)
31493169
}
31503170
}
31513171

3172+
/*[clinic input]
3173+
@classmethod
3174+
_decimal.Decimal.__new__ as dec_new
3175+
3176+
value: object(c_default="NULL") = "0"
3177+
context: object = None
3178+
3179+
Construct a new Decimal object.
3180+
3181+
value can be an integer, string, tuple, or another Decimal object. If
3182+
no value is given, return Decimal('0'). The context does not affect
3183+
the conversion and is only passed to determine if the InvalidOperation
3184+
trap is active.
3185+
[clinic start generated code]*/
3186+
31523187
static PyObject *
3153-
dec_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
3188+
dec_new_impl(PyTypeObject *type, PyObject *value, PyObject *context)
3189+
/*[clinic end generated code: output=35f48a40c65625ba input=5f8a0892d3fcef80]*/
31543190
{
3155-
static char *kwlist[] = {"value", "context", NULL};
3156-
PyObject *v = NULL;
3157-
PyObject *context = Py_None;
3158-
3159-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwlist,
3160-
&v, &context)) {
3161-
return NULL;
3162-
}
31633191
decimal_state *state = get_module_state_by_def(type);
31643192
CONTEXT_CHECK_VA(state, context);
31653193

3166-
return PyDecType_FromObjectExact(type, v, context);
3194+
return PyDecType_FromObjectExact(type, value, context);
31673195
}
31683196

31693197
static PyObject *
@@ -4105,32 +4133,36 @@ PyDec_AsFloat(PyObject *dec)
41054133
return f;
41064134
}
41074135

4136+
/*[clinic input]
4137+
_decimal.Decimal.__round__
4138+
4139+
ndigits: object = NULL
4140+
/
4141+
4142+
Return the Integral closest to self, rounding half toward even.
4143+
[clinic start generated code]*/
4144+
41084145
static PyObject *
4109-
PyDec_Round(PyObject *dec, PyObject *args)
4146+
_decimal_Decimal___round___impl(PyObject *self, PyObject *ndigits)
4147+
/*[clinic end generated code: output=ca6b3570a8df0c91 input=dc72084114f59380]*/
41104148
{
41114149
PyObject *result;
4112-
PyObject *x = NULL;
41134150
uint32_t status = 0;
41144151
PyObject *context;
4115-
4116-
decimal_state *state = get_module_state_by_def(Py_TYPE(dec));
4152+
decimal_state *state = get_module_state_by_def(Py_TYPE(self));
41174153
CURRENT_CONTEXT(state, context);
4118-
if (!PyArg_ParseTuple(args, "|O", &x)) {
4119-
return NULL;
4120-
}
4121-
4122-
if (x) {
4154+
if (ndigits) {
41234155
mpd_uint_t dq[1] = {1};
41244156
mpd_t q = {MPD_STATIC|MPD_CONST_DATA,0,1,1,1,dq};
41254157
mpd_ssize_t y;
41264158

4127-
if (!PyLong_Check(x)) {
4159+
if (!PyLong_Check(ndigits)) {
41284160
PyErr_SetString(PyExc_TypeError,
41294161
"optional arg must be an integer");
41304162
return NULL;
41314163
}
41324164

4133-
y = PyLong_AsSsize_t(x);
4165+
y = PyLong_AsSsize_t(ndigits);
41344166
if (y == -1 && PyErr_Occurred()) {
41354167
return NULL;
41364168
}
@@ -4140,7 +4172,7 @@ PyDec_Round(PyObject *dec, PyObject *args)
41404172
}
41414173

41424174
q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y;
4143-
mpd_qquantize(MPD(result), MPD(dec), &q, CTX(context), &status);
4175+
mpd_qquantize(MPD(result), MPD(self), &q, CTX(context), &status);
41444176
if (dec_addstatus(context, status)) {
41454177
Py_DECREF(result);
41464178
return NULL;
@@ -4149,7 +4181,7 @@ PyDec_Round(PyObject *dec, PyObject *args)
41494181
return result;
41504182
}
41514183
else {
4152-
return dec_as_long(dec, context, MPD_ROUND_HALF_EVEN);
4184+
return dec_as_long(self, context, MPD_ROUND_HALF_EVEN);
41534185
}
41544186
}
41554187

@@ -5418,9 +5450,15 @@ dec_richcompare(PyObject *v, PyObject *w, int op)
54185450
return PyBool_FromLong(r);
54195451
}
54205452

5421-
/* __ceil__ */
5453+
/*[clinic input]
5454+
_decimal.Decimal.__ceil__
5455+
5456+
Return the ceiling as an Integral.
5457+
[clinic start generated code]*/
5458+
54225459
static PyObject *
5423-
dec_ceil(PyObject *self, PyObject *Py_UNUSED(dummy))
5460+
_decimal_Decimal___ceil___impl(PyObject *self)
5461+
/*[clinic end generated code: output=e755a6fb7bceac19 input=4a18ef307ac57da0]*/
54245462
{
54255463
PyObject *context;
54265464

@@ -5429,9 +5467,15 @@ dec_ceil(PyObject *self, PyObject *Py_UNUSED(dummy))
54295467
return dec_as_long(self, context, MPD_ROUND_CEILING);
54305468
}
54315469

5432-
/* __complex__ */
5470+
/*[clinic input]
5471+
_decimal.Decimal.__complex__
5472+
5473+
Convert this value to exact type complex.
5474+
[clinic start generated code]*/
5475+
54335476
static PyObject *
5434-
dec_complex(PyObject *self, PyObject *Py_UNUSED(dummy))
5477+
_decimal_Decimal___complex___impl(PyObject *self)
5478+
/*[clinic end generated code: output=c9b5b4a9fdebc912 input=6b11c6f20af7061a]*/
54355479
{
54365480
PyObject *f;
54375481
double x;
@@ -5450,16 +5494,42 @@ dec_complex(PyObject *self, PyObject *Py_UNUSED(dummy))
54505494
return PyComplex_FromDoubles(x, 0);
54515495
}
54525496

5453-
/* __copy__ (METH_NOARGS) and __deepcopy__ (METH_O) */
5497+
/*[clinic input]
5498+
_decimal.Decimal.__copy__
5499+
5500+
[clinic start generated code]*/
5501+
5502+
static PyObject *
5503+
_decimal_Decimal___copy___impl(PyObject *self)
5504+
/*[clinic end generated code: output=8eb3656c0250762b input=3dfd30a3e1493c01]*/
5505+
{
5506+
return Py_NewRef(self);
5507+
}
5508+
5509+
/*[clinic input]
5510+
_decimal.Decimal.__deepcopy__
5511+
5512+
memo: object
5513+
/
5514+
5515+
[clinic start generated code]*/
5516+
54545517
static PyObject *
5455-
dec_copy(PyObject *self, PyObject *Py_UNUSED(dummy))
5518+
_decimal_Decimal___deepcopy__(PyObject *self, PyObject *memo)
5519+
/*[clinic end generated code: output=988fb34e0136b376 input=f95598c6f43233aa]*/
54565520
{
54575521
return Py_NewRef(self);
54585522
}
54595523

5460-
/* __floor__ */
5524+
/*[clinic input]
5525+
_decimal.Decimal.__floor__
5526+
5527+
Return the floor as an Integral.
5528+
[clinic start generated code]*/
5529+
54615530
static PyObject *
5462-
dec_floor(PyObject *self, PyObject *Py_UNUSED(dummy))
5531+
_decimal_Decimal___floor___impl(PyObject *self)
5532+
/*[clinic end generated code: output=56767050ac1a1d5a input=cabcc5618564548b]*/
54635533
{
54645534
PyObject *context;
54655535

@@ -5595,9 +5665,15 @@ dec_hash(PyObject *op)
55955665
return self->hash;
55965666
}
55975667

5598-
/* __reduce__ */
5668+
/*[clinic input]
5669+
_decimal.Decimal.__reduce__
5670+
5671+
Return state information for pickling.
5672+
[clinic start generated code]*/
5673+
55995674
static PyObject *
5600-
dec_reduce(PyObject *self, PyObject *Py_UNUSED(dummy))
5675+
_decimal_Decimal___reduce___impl(PyObject *self)
5676+
/*[clinic end generated code: output=84fa6648a496a8d2 input=0345ea951d9b986f]*/
56015677
{
56025678
PyObject *result, *str;
56035679

@@ -5612,9 +5688,17 @@ dec_reduce(PyObject *self, PyObject *Py_UNUSED(dummy))
56125688
return result;
56135689
}
56145690

5615-
/* __sizeof__ */
5691+
/*[clinic input]
5692+
_decimal.Decimal.__sizeof__
5693+
5694+
self as v: self
5695+
5696+
Returns size in memory, in bytes
5697+
[clinic start generated code]*/
5698+
56165699
static PyObject *
5617-
dec_sizeof(PyObject *v, PyObject *Py_UNUSED(dummy))
5700+
_decimal_Decimal___sizeof___impl(PyObject *v)
5701+
/*[clinic end generated code: output=f16de05097c62b79 input=a557db538cfddbb7]*/
56185702
{
56195703
size_t res = _PyObject_SIZE(Py_TYPE(v));
56205704
if (mpd_isdynamic_data(MPD(v))) {
@@ -5623,9 +5707,15 @@ dec_sizeof(PyObject *v, PyObject *Py_UNUSED(dummy))
56235707
return PyLong_FromSize_t(res);
56245708
}
56255709

5626-
/* __trunc__ */
5710+
/*[clinic input]
5711+
_decimal.Decimal.__trunc__
5712+
5713+
Return the Integral closest to x between 0 and x.
5714+
[clinic start generated code]*/
5715+
56275716
static PyObject *
5628-
dec_trunc(PyObject *self, PyObject *Py_UNUSED(dummy))
5717+
_decimal_Decimal___trunc___impl(PyObject *self)
5718+
/*[clinic end generated code: output=9ef59578960f80c0 input=a965a61096dcefeb]*/
56295719
{
56305720
PyObject *context;
56315721

@@ -5743,16 +5833,16 @@ static PyMethodDef dec_methods [] =
57435833
_DECIMAL_DECIMAL_AS_INTEGER_RATIO_METHODDEF
57445834

57455835
/* Special methods */
5746-
{ "__copy__", dec_copy, METH_NOARGS, NULL },
5747-
{ "__deepcopy__", dec_copy, METH_O, NULL },
5836+
_DECIMAL_DECIMAL___COPY___METHODDEF
5837+
_DECIMAL_DECIMAL___DEEPCOPY___METHODDEF
57485838
_DECIMAL_DECIMAL___FORMAT___METHODDEF
5749-
{ "__reduce__", dec_reduce, METH_NOARGS, NULL },
5750-
{ "__round__", PyDec_Round, METH_VARARGS, NULL },
5751-
{ "__ceil__", dec_ceil, METH_NOARGS, NULL },
5752-
{ "__floor__", dec_floor, METH_NOARGS, NULL },
5753-
{ "__trunc__", dec_trunc, METH_NOARGS, NULL },
5754-
{ "__complex__", dec_complex, METH_NOARGS, NULL },
5755-
{ "__sizeof__", dec_sizeof, METH_NOARGS, NULL },
5839+
_DECIMAL_DECIMAL___REDUCE___METHODDEF
5840+
_DECIMAL_DECIMAL___ROUND___METHODDEF
5841+
_DECIMAL_DECIMAL___CEIL___METHODDEF
5842+
_DECIMAL_DECIMAL___FLOOR___METHODDEF
5843+
_DECIMAL_DECIMAL___TRUNC___METHODDEF
5844+
_DECIMAL_DECIMAL___COMPLEX___METHODDEF
5845+
_DECIMAL_DECIMAL___SIZEOF___METHODDEF
57565846

57575847
{ NULL, NULL, 1 }
57585848
};
@@ -5765,7 +5855,7 @@ static PyType_Slot dec_slots[] = {
57655855
{Py_tp_repr, dec_repr},
57665856
{Py_tp_hash, dec_hash},
57675857
{Py_tp_str, dec_str},
5768-
{Py_tp_doc, (void *)doc_decimal},
5858+
{Py_tp_doc, (void *)dec_new__doc__},
57695859
{Py_tp_richcompare, dec_richcompare},
57705860
{Py_tp_methods, dec_methods},
57715861
{Py_tp_getset, dec_getsets},
@@ -6119,8 +6209,18 @@ _decimal_Context_power_impl(PyObject *context, PyObject *base, PyObject *exp,
61196209
DecCtx_TernaryFunc(mpd_qfma)
61206210

61216211
/* No argument */
6212+
6213+
/*[clinic input]
6214+
_decimal.Context.radix
6215+
6216+
self as context: self
6217+
6218+
Return 10.
6219+
[clinic start generated code]*/
6220+
61226221
static PyObject *
6123-
ctx_mpd_radix(PyObject *context, PyObject *dummy)
6222+
_decimal_Context_radix_impl(PyObject *context)
6223+
/*[clinic end generated code: output=9218fa309e0fcaa1 input=faeaa5b71f838c38]*/
61246224
{
61256225
decimal_state *state = get_module_state_from_ctx(context);
61266226
return _dec_mpd_radix(state);
@@ -6403,9 +6503,9 @@ static PyMethodDef context_methods [] =
64036503
{ "fma", ctx_mpd_qfma, METH_VARARGS, doc_ctx_fma },
64046504

64056505
/* No argument */
6406-
{ "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny },
6407-
{ "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop },
6408-
{ "radix", ctx_mpd_radix, METH_NOARGS, doc_ctx_radix },
6506+
_DECIMAL_CONTEXT_ETINY_METHODDEF
6507+
_DECIMAL_CONTEXT_ETOP_METHODDEF
6508+
_DECIMAL_CONTEXT_RADIX_METHODDEF
64096509

64106510
/* Boolean functions */
64116511
{ "is_canonical", ctx_iscanonical, METH_O, doc_ctx_is_canonical },
@@ -6932,7 +7032,7 @@ static struct PyModuleDef_Slot _decimal_slots[] = {
69327032
static struct PyModuleDef _decimal_module = {
69337033
PyModuleDef_HEAD_INIT,
69347034
.m_name = "decimal",
6935-
.m_doc = doc__decimal,
7035+
.m_doc = "C decimal arithmetic module",
69367036
.m_size = sizeof(decimal_state),
69377037
.m_methods = _decimal_methods,
69387038
.m_slots = _decimal_slots,

0 commit comments

Comments
 (0)