summaryrefslogtreecommitdiff
path: root/Modules/_decimal
diff options
context:
space:
mode:
authorStefan Krah <skrah@bytereef.org>2016-07-17 14:12:59 +0200
committerStefan Krah <skrah@bytereef.org>2016-07-17 14:12:59 +0200
commit243d8a7866a3ea0e0dde9e80c5258d7171dfdebe (patch)
treed7d978e97dc3c06e1321361a9e920d77b457edae /Modules/_decimal
parentcaaf53e748f664c40d77649fd47df0a8ab01ec27 (diff)
parent8c126f17f09eeb75d3d3c9737150384cd1dd9c03 (diff)
downloadcpython-git-243d8a7866a3ea0e0dde9e80c5258d7171dfdebe.tar.gz
Merge 3.5.
Diffstat (limited to 'Modules/_decimal')
-rw-r--r--Modules/_decimal/_decimal.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c
index dd33f973e4..3ba8e35ce9 100644
--- a/Modules/_decimal/_decimal.c
+++ b/Modules/_decimal/_decimal.c
@@ -2207,6 +2207,14 @@ PyDecType_FromLongExact(PyTypeObject *type, const PyObject *pylong,
return dec;
}
+/* External C-API functions */
+static binaryfunc _py_long_multiply;
+static binaryfunc _py_long_floor_divide;
+static ternaryfunc _py_long_power;
+static unaryfunc _py_float_abs;
+static PyCFunction _py_long_bit_length;
+static PyCFunction _py_float_as_integer_ratio;
+
/* Return a PyDecObject or a subtype from a PyFloatObject.
Conversion is exact. */
static PyObject *
@@ -2257,13 +2265,13 @@ PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v,
}
/* absolute value of the float */
- tmp = PyObject_CallMethod(v, "__abs__", NULL);
+ tmp = _py_float_abs(v);
if (tmp == NULL) {
return NULL;
}
/* float as integer ratio: numerator/denominator */
- n_d = PyObject_CallMethod(tmp, "as_integer_ratio", NULL);
+ n_d = _py_float_as_integer_ratio(tmp, NULL);
Py_DECREF(tmp);
if (n_d == NULL) {
return NULL;
@@ -2271,7 +2279,7 @@ PyDecType_FromFloatExact(PyTypeObject *type, PyObject *v,
n = PyTuple_GET_ITEM(n_d, 0);
d = PyTuple_GET_ITEM(n_d, 1);
- tmp = PyObject_CallMethod(d, "bit_length", NULL);
+ tmp = _py_long_bit_length(d, NULL);
if (tmp == NULL) {
Py_DECREF(n_d);
return NULL;
@@ -3397,7 +3405,6 @@ dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED)
mpd_ssize_t exp;
PyObject *context;
uint32_t status = 0;
- PyNumberMethods *long_methods = PyLong_Type.tp_as_number;
if (mpd_isspecial(MPD(self))) {
if (mpd_isnan(MPD(self))) {
@@ -3444,14 +3451,14 @@ dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED)
goto error;
}
- Py_SETREF(exponent, long_methods->nb_power(tmp, exponent, Py_None));
+ Py_SETREF(exponent, _py_long_power(tmp, exponent, Py_None));
Py_DECREF(tmp);
if (exponent == NULL) {
goto error;
}
if (exp >= 0) {
- Py_SETREF(numerator, long_methods->nb_multiply(numerator, exponent));
+ Py_SETREF(numerator, _py_long_multiply(numerator, exponent));
if (numerator == NULL) {
goto error;
}
@@ -3467,8 +3474,8 @@ dec_as_integer_ratio(PyObject *self, PyObject *args UNUSED)
if (tmp == NULL) {
goto error;
}
- Py_SETREF(numerator, long_methods->nb_floor_divide(numerator, tmp));
- Py_SETREF(denominator, long_methods->nb_floor_divide(denominator, tmp));
+ Py_SETREF(numerator, _py_long_floor_divide(numerator, tmp));
+ Py_SETREF(denominator, _py_long_floor_divide(denominator, tmp));
Py_DECREF(tmp);
if (numerator == NULL || denominator == NULL) {
goto error;
@@ -5611,6 +5618,32 @@ static struct int_constmap int_constants [] = {
#define CHECK_PTR(expr) \
do { if ((expr) == NULL) goto error; } while (0)
+
+static PyCFunction
+cfunc_noargs(PyTypeObject *t, const char *name)
+{
+ struct PyMethodDef *m;
+
+ if (t->tp_methods == NULL) {
+ goto error;
+ }
+
+ for (m = t->tp_methods; m->ml_name != NULL; m++) {
+ if (strcmp(name, m->ml_name) == 0) {
+ if (!(m->ml_flags & METH_NOARGS)) {
+ goto error;
+ }
+ return m->ml_meth;
+ }
+ }
+
+error:
+ PyErr_Format(PyExc_RuntimeError,
+ "internal error: could not find method %s", name);
+ return NULL;
+}
+
+
PyMODINIT_FUNC
PyInit__decimal(void)
{
@@ -5635,6 +5668,16 @@ PyInit__decimal(void)
mpd_setminalloc(_Py_DEC_MINALLOC);
+ /* Init external C-API functions */
+ _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply;
+ _py_long_floor_divide = PyLong_Type.tp_as_number->nb_floor_divide;
+ _py_long_power = PyLong_Type.tp_as_number->nb_power;
+ _py_float_abs = PyFloat_Type.tp_as_number->nb_absolute;
+ ASSIGN_PTR(_py_float_as_integer_ratio, cfunc_noargs(&PyFloat_Type,
+ "as_integer_ratio"));
+ ASSIGN_PTR(_py_long_bit_length, cfunc_noargs(&PyLong_Type, "bit_length"));
+
+
/* Init types */
PyDec_Type.tp_base = &PyBaseObject_Type;
PyDecContext_Type.tp_base = &PyBaseObject_Type;