Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8754016
Add a minimal decimal capsule API.
skrah Jul 17, 2020
72f95d8
Add PyDec_GetConst() and PyDec_GetDigits().
skrah Jul 18, 2020
83366fb
Group the functions into simple and advanced API.
skrah Jul 18, 2020
3636589
Add PyDec_IsSpecial(), PyDec_IsNaN() and PyDec_IsInfinite().
skrah Jul 18, 2020
3208099
Mention ABI stability of mpd_t.
skrah Jul 18, 2020
fa6e201
Remove test_decimal_api_get_digits() duplicate.
skrah Jul 18, 2020
3a0db41
Move the TypeError into PyDec_AsUint128Triple() for a consistent API.
skrah Jul 18, 2020
2fcc6ff
Fix error message.
skrah Jul 18, 2020
9ac33c3
Add documentation.
skrah Jul 18, 2020
d8e23da
Appease the Sphinx linter.
skrah Jul 18, 2020
948a62e
Rename decimal.h to pydecimal.h.
skrah Jul 20, 2020
cff9084
Move decimal test functions out of the datetime section.
skrah Jul 20, 2020
fff8826
Fix typo.
skrah Jul 20, 2020
193bc41
Merge branch 'master' of https://github.com/python/cpython into minim…
skrah Jul 20, 2020
79c46d9
Make maxcontext a static const.
skrah Jul 20, 2020
9bd11b6
Merge branch 'master' of https://github.com/python/cpython into minim…
skrah Jul 22, 2020
81992c5
Remove libmpdec_triple.h.
skrah Jul 22, 2020
b62baf6
Merge branch 'master' of https://github.com/python/cpython into minim…
skrah Aug 8, 2020
dd860dd
Merge branch 'master' of https://github.com/python/cpython into minim…
skrah Aug 10, 2020
3bf0e2d
Fix array type (not that it matters with all that capsule casting).
skrah Aug 10, 2020
ec73b29
Add blurb.
skrah Aug 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add PyDec_GetConst() and PyDec_GetDigits().
  • Loading branch information
Stefan Krah committed Jul 18, 2020
commit 72f95d80087185d358981056d149dfb6a9cbce36
24 changes: 20 additions & 4 deletions Include/decimal.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,22 +81,32 @@ typedef struct {

#define PyDec_Get_INDEX 2
#define PyDec_Get_RETURN mpd_t *
#define PyDec_Get_ARGS (const PyObject *)
#define PyDec_Get_ARGS (PyObject *)

#define PyDec_AsUint128Triple_INDEX 3
#define PyDec_GetConst_INDEX 3
#define PyDec_GetConst_RETURN const mpd_t *
#define PyDec_GetConst_ARGS (const PyObject *)

#define PyDec_GetDigits_INDEX 4
#define PyDec_GetDigits_RETURN int64_t
#define PyDec_GetDigits_ARGS (const PyObject *)

#define PyDec_AsUint128Triple_INDEX 5
#define PyDec_AsUint128Triple_RETURN mpd_uint128_triple_t
#define PyDec_AsUint128Triple_ARGS (const PyObject *)

#define PyDec_FromUint128Triple_INDEX 4
#define PyDec_FromUint128Triple_INDEX 6
#define PyDec_FromUint128Triple_RETURN PyObject *
#define PyDec_FromUint128Triple_ARGS (const mpd_uint128_triple_t *triple)

#define CPYTHON_DECIMAL_MAX_API 5
#define CPYTHON_DECIMAL_MAX_API 7

#ifdef CPYTHON_DECIMAL_MODULE
static PyDec_TypeCheck_RETURN PyDec_TypeCheck PyDec_TypeCheck_ARGS;
static PyDec_Alloc_RETURN PyDec_Alloc PyDec_Alloc_ARGS;
static PyDec_Get_RETURN PyDec_Get PyDec_Get_ARGS;
static PyDec_GetConst_RETURN PyDec_GetConst PyDec_GetConst_ARGS;
static PyDec_GetDigits_RETURN PyDec_GetDigits PyDec_GetDigits_ARGS;
static PyDec_AsUint128Triple_RETURN PyDec_AsUint128Triple PyDec_AsUint128Triple_ARGS;
static PyDec_FromUint128Triple_RETURN PyDec_FromUint128Triple PyDec_FromUint128Triple_ARGS;
#else
Expand All @@ -111,6 +121,12 @@ static void **_decimal_api;
#define PyDec_Get \
(*(PyDec_Get_RETURN (*)PyDec_Get_ARGS) _decimal_api[PyDec_Get_INDEX])

#define PyDec_GetConst \
(*(PyDec_GetConst_RETURN (*)PyDec_GetConst_ARGS) _decimal_api[PyDec_GetConst_INDEX])

#define PyDec_GetDigits \
(*(PyDec_GetDigits_RETURN (*)PyDec_GetDigits_ARGS) _decimal_api[PyDec_GetDigits_INDEX])

#define PyDec_AsUint128Triple \
(*(PyDec_AsUint128Triple_RETURN (*)PyDec_AsUint128Triple_ARGS) _decimal_api[PyDec_AsUint128Triple_INDEX])

Expand Down
27 changes: 27 additions & 0 deletions Lib/test/test_decimal.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import inspect
import threading

from _testcapi import decimal_get_digits
from _testcapi import decimal_as_triple
from _testcapi import decimal_from_triple

Expand Down Expand Up @@ -4845,6 +4846,30 @@ def from_triple(triple):
p = decimal_from_triple(ptriple)
self.assertEqual(str(c), str(p))

def test_decimal_get_digits(self):
# Capsule API

d = C.Decimal("0")
self.assertEqual(decimal_get_digits(d), 1)

d = C.Decimal("1234567890")
self.assertEqual(decimal_get_digits(d), 10)

d = C.Decimal("inf")
self.assertEqual(decimal_get_digits(d), 0)

d = C.Decimal("NaN")
self.assertEqual(decimal_get_digits(d), 0)

d = C.Decimal("sNaN")
self.assertEqual(decimal_get_digits(d), 0)

d = C.Decimal("NaN1234567890")
self.assertEqual(decimal_get_digits(d), 10)

d = C.Decimal("sNaN1234567890")
self.assertEqual(decimal_get_digits(d), 10)

def test_decimal_api_errors(self):
# Capsule API

Expand All @@ -4868,6 +4893,8 @@ def test_decimal_api_errors(self):
self.assertRaises(C.InvalidOperation, decimal_from_triple, (0, 0, 0, 2**63-1))
self.assertRaises(C.InvalidOperation, decimal_from_triple, (0, 0, 0, -2**63))

self.assertRaises(TypeError, decimal_get_digits, "X")

class CWhitebox(unittest.TestCase):
"""Whitebox testing for _decimal"""

Expand Down
28 changes: 27 additions & 1 deletion Modules/_decimal/_decimal.c
Original file line number Diff line number Diff line change
Expand Up @@ -5577,7 +5577,7 @@ PyDec_Alloc(void)
}

static mpd_t *
PyDec_Get(const PyObject *v)
PyDec_Get(PyObject *v)
{
if (!PyDec_Check(v)) {
PyErr_SetString(PyExc_TypeError,
Expand All @@ -5588,6 +5588,30 @@ PyDec_Get(const PyObject *v)
return MPD(v);
}

static const mpd_t *
PyDec_GetConst(const PyObject *v)
{
if (!PyDec_Check(v)) {
PyErr_SetString(PyExc_TypeError,
"PyDec_GetConst: argument must be a Decimal");
return NULL;
}

return MPD(v);
}

static int64_t
PyDec_GetDigits(const PyObject *v)
{
if (!PyDec_Check(v)) {
PyErr_SetString(PyExc_TypeError,
"PyDec_GetConst: argument must be a Decimal");
return -1;
}

return MPD(v)->digits;
}

static mpd_uint128_triple_t
PyDec_AsUint128Triple(const PyObject *v)
{
Expand Down Expand Up @@ -5629,6 +5653,8 @@ init_api(void)
_decimal_api[PyDec_TypeCheck_INDEX] = (void *)PyDec_TypeCheck;
_decimal_api[PyDec_Alloc_INDEX] = (void *)PyDec_Alloc;
_decimal_api[PyDec_Get_INDEX] = (void *)PyDec_Get;
_decimal_api[PyDec_GetConst_INDEX] = (void *)PyDec_GetConst;
_decimal_api[PyDec_GetDigits_INDEX] = (void *)PyDec_GetDigits;
_decimal_api[PyDec_AsUint128Triple_INDEX] = (void *)PyDec_AsUint128Triple;
_decimal_api[PyDec_FromUint128Triple_INDEX] = (void *)PyDec_FromUint128Triple;

Expand Down
23 changes: 23 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2708,6 +2708,28 @@ test_PyDateTime_DELTA_GET(PyObject *self, PyObject *obj)

/* Test decimal API */
static int decimal_initialized = 0;
static PyObject *
decimal_get_digits(PyObject *module, PyObject *dec)
{
int64_t digits;

(void)module;
if (!decimal_initialized) {
if (import_decimal() < 0) {
return NULL;
}

decimal_initialized = 1;
}

digits = PyDec_GetDigits(dec);
if (digits < 0) {
return NULL;
}

return PyLong_FromLongLong(digits);
}

static PyObject *
decimal_as_triple(PyObject *module, PyObject *dec)
{
Expand Down Expand Up @@ -5461,6 +5483,7 @@ static PyMethodDef TestMethods[] = {
{"datetime_check_datetime", datetime_check_datetime, METH_VARARGS},
{"datetime_check_delta", datetime_check_delta, METH_VARARGS},
{"datetime_check_tzinfo", datetime_check_tzinfo, METH_VARARGS},
{"decimal_get_digits", decimal_get_digits, METH_O},
{"decimal_as_triple", decimal_as_triple, METH_O},
{"decimal_from_triple", decimal_from_triple, METH_O},
{"make_timezones_capi", make_timezones_capi, METH_NOARGS},
Expand Down