diff options
author | Antoine Pitrou <antoine@python.org> | 2021-03-21 16:27:54 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-21 16:27:54 (GMT) |
commit | cdddc2b742750e3f289305cf276433a8170c32c1 (patch) | |
tree | e4ce948d8cff600cf5721ba00c627f780217a64d /Doc | |
parent | 77cde5042a2f1eae489c11a67540afaf43cd5cdf (diff) | |
download | cpython-cdddc2b742750e3f289305cf276433a8170c32c1.zip cpython-cdddc2b742750e3f289305cf276433a8170c32c1.tar.gz cpython-cdddc2b742750e3f289305cf276433a8170c32c1.tar.bz2 |
bpo-43422: Revert _decimal C API addition (GH-24960)
Stefan Krah requested the reversal of these (unreleased) changes, quoting him:
> The capsule API does not meet my testing standards, since I've focused
on the upstream mpdecimal in the last couple of months.
> Additionally, I'd like to refine the API, perhaps together with the
Arrow community.
Automerge-Triggered-By: GH:pitrou
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/c-api/concrete.rst | 1 | ||||
-rw-r--r-- | Doc/c-api/decimal.rst | 231 |
2 files changed, 0 insertions, 232 deletions
diff --git a/Doc/c-api/concrete.rst b/Doc/c-api/concrete.rst index bf263d6..c1d9fa1 100644 --- a/Doc/c-api/concrete.rst +++ b/Doc/c-api/concrete.rst @@ -115,4 +115,3 @@ Other Objects coro.rst contextvars.rst datetime.rst - decimal.rst diff --git a/Doc/c-api/decimal.rst b/Doc/c-api/decimal.rst deleted file mode 100644 index 94cc4a7..0000000 --- a/Doc/c-api/decimal.rst +++ /dev/null @@ -1,231 +0,0 @@ -.. sectionauthor:: Stefan Krah - -.. highlight:: c - - -Decimal capsule API -=================== - -Capsule API functions can be used in the same manner as regular library -functions, provided that the API has been initialized. - - -Initialize ----------- - -Typically, a C extension module that uses the decimal API will do these -steps in its init function: - -.. code-block:: c - - #include "pydecimal.h" - - static int decimal_initialized = 0; - if (!decimal_initialized) { - if (import_decimal() < 0) { - return NULL; - } - - decimal_initialized = 1; - } - - -Type checking, predicates, accessors ------------------------------------- - -.. c:function:: int PyDec_TypeCheck(const PyObject *dec) - - Return 1 if ``dec`` is a Decimal, 0 otherwise. This function does not set - any exceptions. - - -.. c:function:: int PyDec_IsSpecial(const PyObject *dec) - - Return 1 if ``dec`` is ``NaN``, ``sNaN`` or ``Infinity``, 0 otherwise. - - Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that - this is the only failure mode, so if ``dec`` has already been type-checked, no - errors can occur and the function can be treated as a simple predicate. - - -.. c:function:: int PyDec_IsNaN(const PyObject *dec) - - Return 1 if ``dec`` is ``NaN`` or ``sNaN``, 0 otherwise. - - Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that - this is the only failure mode, so if ``dec`` has already been type-checked, no - errors can occur and the function can be treated as a simple predicate. - - -.. c:function:: int PyDec_IsInfinite(const PyObject *dec) - - Return 1 if ``dec`` is ``Infinity``, 0 otherwise. - - Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that - this is the only failure mode, so if ``dec`` has already been type-checked, no - errors can occur and the function can be treated as a simple predicate. - - -.. c:function:: int64_t PyDec_GetDigits(const PyObject *dec) - - Return the number of digits in the coefficient. For ``Infinity``, the - number of digits is always zero. Typically, the same applies to ``NaN`` - and ``sNaN``, but both of these can have a payload that is equivalent to - a coefficient. Therefore, ``NaNs`` can have a nonzero return value. - - Set TypeError and return -1 if ``dec`` is not a Decimal. It is guaranteed that - this is the only failure mode, so if ``dec`` has already been type-checked, no - errors can occur and the function can be treated as a simple accessor. - - -Exact conversions between decimals and primitive C types --------------------------------------------------------- - -This API supports conversions for decimals with a coefficient up to 38 digits. - -Data structures -~~~~~~~~~~~~~~~ - -The conversion functions use the following status codes and data structures: - -.. code-block:: c - - /* status cases for getting a triple */ - enum mpd_triple_class { - MPD_TRIPLE_NORMAL, - MPD_TRIPLE_INF, - MPD_TRIPLE_QNAN, - MPD_TRIPLE_SNAN, - MPD_TRIPLE_ERROR, - }; - - typedef struct { - enum mpd_triple_class tag; - uint8_t sign; - uint64_t hi; - uint64_t lo; - int64_t exp; - } mpd_uint128_triple_t; - -The status cases are explained below. ``sign`` is 0 for positive and 1 for negative. -``((uint128_t)hi << 64) + lo`` is the coefficient, ``exp`` is the exponent. - -The data structure is called "triple" because the decimal triple (sign, coeff, exp) -is an established term and (``hi``, ``lo``) represents a single ``uint128_t`` coefficient. - - -Functions -~~~~~~~~~ - -.. c:function:: mpd_uint128_triple_t PyDec_AsUint128Triple(const PyObject *dec) - - Convert a decimal to a triple. As above, it is guaranteed that the only - Python failure mode is a TypeError, checks can be omitted if the type is - known. - - For simplicity, the usage of the function and all special cases are - explained in code form and comments: - -.. code-block:: c - - triple = PyDec_AsUint128Triple(dec); - switch (triple.tag) { - case MPD_TRIPLE_QNAN: - /* - * Success: handle a quiet NaN. - * 1) triple.sign is 0 or 1. - * 2) triple.exp is always 0. - * 3) If triple.hi or triple.lo are nonzero, the NaN has a payload. - */ - break; - - case MPD_TRIPLE_SNAN: - /* - * Success: handle a signaling NaN. - * 1) triple.sign is 0 or 1. - * 2) triple.exp is always 0. - * 3) If triple.hi or triple.lo are nonzero, the sNaN has a payload. - */ - break; - - case MPD_TRIPLE_INF: - /* - * Success: handle Infinity. - * 1) triple.sign is 0 or 1. - * 2) triple.exp is always 0. - * 3) triple.hi and triple.lo are always zero. - */ - break; - - case MPD_TRIPLE_NORMAL: - /* Success: handle a finite value. */ - break; - - case MPD_TRIPLE_ERROR: - /* TypeError check: can be omitted if the type of dec is known. */ - if (PyErr_Occurred()) { - return NULL; - } - - /* Too large for conversion. PyDec_AsUint128Triple() does not set an - exception so applications can choose themselves. Typically this - would be a ValueError. */ - PyErr_SetString(PyExc_ValueError, - "value out of bounds for a uint128 triple"); - return NULL; - } - -.. c:function:: PyObject *PyDec_FromUint128Triple(const mpd_uint128_triple_t *triple) - - Create a decimal from a triple. The following rules must be observed for - initializing the triple: - - 1) ``triple.sign`` must always be 0 (for positive) or 1 (for negative). - - 2) ``MPD_TRIPLE_QNAN``: ``triple.exp`` must be 0. If ``triple.hi`` or ``triple.lo`` - are nonzero, create a ``NaN`` with a payload. - - 3) ``MPD_TRIPLE_SNAN``: ``triple.exp`` must be 0. If ``triple.hi`` or ``triple.lo`` - are nonzero, create an ``sNaN`` with a payload. - - 4) ``MPD_TRIPLE_INF``: ``triple.exp``, ``triple.hi`` and ``triple.lo`` must be zero. - - 5) ``MPD_TRIPLE_NORMAL``: ``MPD_MIN_ETINY + 38 < triple.exp < MPD_MAX_EMAX - 38``. - ``triple.hi`` and ``triple.lo`` can be chosen freely. - - 6) ``MPD_TRIPLE_ERROR``: It is always an error to set this tag. - - - If one of the above conditions is not met, the function returns ``NaN`` if - the ``InvalidOperation`` trap is not set in the thread local context. Otherwise, - it sets the ``InvalidOperation`` exception and returns NULL. - - Additionally, though extremely unlikely give the small allocation sizes, - the function can set ``MemoryError`` and return ``NULL``. - - -Advanced API ------------- - -This API enables the use of ``libmpdec`` functions. Since Python is compiled with -hidden symbols, the API requires an external libmpdec and the ``mpdecimal.h`` -header. - - -Functions -~~~~~~~~~ - -.. c:function:: PyObject *PyDec_Alloc(void) - - Return a new decimal that can be used in the ``result`` position of ``libmpdec`` - functions. - -.. c:function:: mpd_t *PyDec_Get(PyObject *v) - - Get a pointer to the internal ``mpd_t`` of the decimal. Decimals are immutable, - so this function must only be used on a new Decimal that has been created by - PyDec_Alloc(). - -.. c:function:: const mpd_t *PyDec_GetConst(const PyObject *v) - - Get a pointer to the constant internal ``mpd_t`` of the decimal. |