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 /Modules/_decimal | |
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 'Modules/_decimal')
-rw-r--r-- | Modules/_decimal/_decimal.c | 200 | ||||
-rw-r--r-- | Modules/_decimal/tests/bench.py | 9 | ||||
-rw-r--r-- | Modules/_decimal/tests/deccheck.py | 81 | ||||
-rw-r--r-- | Modules/_decimal/tests/formathelper.py | 5 |
4 files changed, 19 insertions, 276 deletions
diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 664d45a..83e237d 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2020 Stefan Krah. All rights reserved. + * Copyright (c) 2008-2012 Stefan Krah. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,8 +33,6 @@ #include <stdlib.h> -#define CPYTHON_DECIMAL_MODULE -#include "pydecimal.h" #include "docstrings.h" @@ -5570,175 +5568,6 @@ static PyTypeObject PyDecContext_Type = }; -/****************************************************************************/ -/* C-API */ -/****************************************************************************/ - -/* Simple API */ -static int -PyDec_TypeCheck(const PyObject *v) -{ - return PyDec_Check(v); -} - -static int -PyDec_IsSpecial(const PyObject *v) -{ - if (!PyDec_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "PyDec_IsSpecial: argument must be a Decimal"); - return -1; - } - - return mpd_isspecial(MPD(v)); -} - -static int -PyDec_IsNaN(const PyObject *v) -{ - if (!PyDec_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "PyDec_IsNaN: argument must be a Decimal"); - return -1; - } - - return mpd_isnan(MPD(v)); -} - -static int -PyDec_IsInfinite(const PyObject *v) -{ - if (!PyDec_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "PyDec_IsInfinite: argument must be a Decimal"); - return -1; - } - - return mpd_isinfinite(MPD(v)); -} - -static int64_t -PyDec_GetDigits(const PyObject *v) -{ - if (!PyDec_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "PyDec_GetDigits: argument must be a Decimal"); - return -1; - } - - return MPD(v)->digits; -} - -static mpd_uint128_triple_t -PyDec_AsUint128Triple(const PyObject *v) -{ - if (!PyDec_Check(v)) { - mpd_uint128_triple_t triple = { MPD_TRIPLE_ERROR, 0, 0, 0, 0 }; - PyErr_SetString(PyExc_TypeError, - "PyDec_AsUint128Triple: argument must be a Decimal"); - return triple; - } - - return mpd_as_uint128_triple(MPD(v)); -} - -static PyObject * -PyDec_FromUint128Triple(const mpd_uint128_triple_t *triple) -{ - PyObject *context; - PyObject *result; - uint32_t status = 0; - - CURRENT_CONTEXT(context); - - result = dec_alloc(); - if (result == NULL) { - return NULL; - } - - if (mpd_from_uint128_triple(MPD(result), triple, &status) < 0) { - if (dec_addstatus(context, status)) { - Py_DECREF(result); - return NULL; - } - } - - return result; -} - -/* Advanced API */ -static PyObject * -PyDec_Alloc(void) -{ - return dec_alloc(); -} - -static mpd_t * -PyDec_Get(PyObject *v) -{ - if (!PyDec_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "PyDec_Get: argument must be a Decimal"); - return NULL; - } - - 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 void -destroy_api(PyObject *capsule) -{ - void *capi = PyCapsule_GetPointer(capsule, PyDec_CAPSULE_NAME); - PyMem_Free(capi); -} - -static PyObject * -init_api(void) -{ - void **_decimal_api = PyMem_Calloc(CPYTHON_DECIMAL_MAX_API, sizeof(void *)); - if (_decimal_api == NULL) { - PyErr_NoMemory(); - return NULL; - } - - /* Simple API */ - _decimal_api[PyDec_TypeCheck_INDEX] = (void *)PyDec_TypeCheck; - _decimal_api[PyDec_IsSpecial_INDEX] = (void *)PyDec_IsSpecial; - _decimal_api[PyDec_IsNaN_INDEX] = (void *)PyDec_IsNaN; - _decimal_api[PyDec_IsInfinite_INDEX] = (void *)PyDec_IsInfinite; - _decimal_api[PyDec_GetDigits_INDEX] = (void *)PyDec_GetDigits; - _decimal_api[PyDec_AsUint128Triple_INDEX] = (void *)PyDec_AsUint128Triple; - _decimal_api[PyDec_FromUint128Triple_INDEX] = (void *)PyDec_FromUint128Triple; - - /* Advanced API */ - _decimal_api[PyDec_Alloc_INDEX] = (void *)PyDec_Alloc; - _decimal_api[PyDec_Get_INDEX] = (void *)PyDec_Get; - _decimal_api[PyDec_GetConst_INDEX] = (void *)PyDec_GetConst; - - PyObject *capsule = PyCapsule_New(_decimal_api, PyDec_CAPSULE_NAME, destroy_api); - if (!capsule) { - PyMem_Free(_decimal_api); - } - return capsule; -} - - -/****************************************************************************/ -/* Module */ -/****************************************************************************/ - static PyMethodDef _decimal_methods [] = { { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, @@ -5849,27 +5678,17 @@ PyInit__decimal(void) DecCondMap *cm; struct ssize_constmap *ssize_cm; struct int_constmap *int_cm; - static PyObject *capsule = NULL; - static int initialized = 0; int i; /* Init libmpdec */ - if (!initialized) { - mpd_traphandler = dec_traphandler; - mpd_mallocfunc = PyMem_Malloc; - mpd_reallocfunc = PyMem_Realloc; - mpd_callocfunc = mpd_callocfunc_em; - mpd_free = PyMem_Free; - mpd_setminalloc(_Py_DEC_MINALLOC); - - capsule = init_api(); - if (capsule == NULL) { - return NULL; - } + mpd_traphandler = dec_traphandler; + mpd_mallocfunc = PyMem_Malloc; + mpd_reallocfunc = PyMem_Realloc; + mpd_callocfunc = mpd_callocfunc_em; + mpd_free = PyMem_Free; + mpd_setminalloc(_Py_DEC_MINALLOC); - initialized = 1; - } /* Init external C-API functions */ _py_long_multiply = PyLong_Type.tp_as_number->nb_multiply; @@ -6094,10 +5913,6 @@ PyInit__decimal(void) CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70")); CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version())); - /* Add capsule API */ - if (PyModule_AddObjectRef(m, "_API", capsule) < 0) { - goto error; - } return m; @@ -6121,7 +5936,6 @@ error: Py_CLEAR(basic_context_template); /* GCOV_NOT_REACHED */ Py_CLEAR(extended_context_template); /* GCOV_NOT_REACHED */ Py_CLEAR(m); /* GCOV_NOT_REACHED */ - Py_CLEAR(capsule); /* GCOV_NOT_REACHED */ return NULL; /* GCOV_NOT_REACHED */ } diff --git a/Modules/_decimal/tests/bench.py b/Modules/_decimal/tests/bench.py index 88fd7b5..3726db1 100644 --- a/Modules/_decimal/tests/bench.py +++ b/Modules/_decimal/tests/bench.py @@ -7,10 +7,13 @@ import time +try: + from test.support import import_fresh_module +except ImportError: + from test.test_support import import_fresh_module -import _decimal as C -import _pydecimal as P - +C = import_fresh_module('decimal', fresh=['_decimal']) +P = import_fresh_module('decimal', blocked=['_decimal']) # # NOTE: This is the pi function from the decimal documentation, modified diff --git a/Modules/_decimal/tests/deccheck.py b/Modules/_decimal/tests/deccheck.py index 5de57d1..98ecd50 100644 --- a/Modules/_decimal/tests/deccheck.py +++ b/Modules/_decimal/tests/deccheck.py @@ -47,18 +47,14 @@ from subprocess import PIPE, STDOUT from queue import Queue, Empty from threading import Thread, Event, Lock +from test.support import import_fresh_module from randdec import randfloat, all_unary, all_binary, all_ternary from randdec import unary_optarg, binary_optarg, ternary_optarg from formathelper import rand_format, rand_locale from _pydecimal import _dec_from_triple -from _testcapi import decimal_as_triple -from _testcapi import decimal_from_triple - -import _decimal as C -import _pydecimal as P - - +C = import_fresh_module('decimal', fresh=['_decimal']) +P = import_fresh_module('decimal', blocked=['_decimal']) EXIT_STATUS = 0 @@ -162,45 +158,6 @@ TernaryRestricted = ['__pow__', 'context.power'] # ====================================================================== -# Triple tests -# ====================================================================== - -def c_as_triple(dec): - sign, hi, lo, exp = decimal_as_triple(dec) - - coeff = hi * 2**64 + lo - return (sign, coeff, exp) - -def c_from_triple(triple): - sign, coeff, exp = triple - - hi = coeff // 2**64 - lo = coeff % 2**64 - return decimal_from_triple((sign, hi, lo, exp)) - -def p_as_triple(dec): - sign, digits, exp = dec.as_tuple() - - s = "".join(str(d) for d in digits) - coeff = int(s) if s else 0 - - if coeff < 0 or coeff >= 2**128: - raise ValueError("value out of bounds for a uint128 triple") - - return (sign, coeff, exp) - -def p_from_triple(triple): - sign, coeff, exp = triple - - if coeff < 0 or coeff >= 2**128: - raise ValueError("value out of bounds for a uint128 triple") - - digits = tuple(int(c) for c in str(coeff)) - - return P.Decimal((sign, digits, exp)) - - -# ====================================================================== # Unified Context # ====================================================================== @@ -893,44 +850,12 @@ def verify(t, stat): t.presults.append(str(t.rp.imag)) t.presults.append(str(t.rp.real)) - ctriple = None - if str(t.rc) == str(t.rp): # see skip handler - try: - ctriple = c_as_triple(t.rc) - except ValueError: - try: - ptriple = p_as_triple(t.rp) - except ValueError: - pass - else: - raise RuntimeError("ValueError not raised") - else: - cres = c_from_triple(ctriple) - t.cresults.append(ctriple) - t.cresults.append(str(cres)) - - ptriple = p_as_triple(t.rp) - pres = p_from_triple(ptriple) - t.presults.append(ptriple) - t.presults.append(str(pres)) - if t.with_maxcontext and isinstance(t.rmax, C.Decimal): t.maxresults.append(t.rmax.to_eng_string()) t.maxresults.append(t.rmax.as_tuple()) t.maxresults.append(str(t.rmax.imag)) t.maxresults.append(str(t.rmax.real)) - if ctriple is not None: - # NaN payloads etc. depend on precision and clamp. - if all_nan(t.rc) and all_nan(t.rmax): - t.maxresults.append(ctriple) - t.maxresults.append(str(cres)) - else: - maxtriple = c_as_triple(t.rmax) - maxres = c_from_triple(maxtriple) - t.maxresults.append(maxtriple) - t.maxresults.append(str(maxres)) - nc = t.rc.number_class().lstrip('+-s') stat[nc] += 1 else: diff --git a/Modules/_decimal/tests/formathelper.py b/Modules/_decimal/tests/formathelper.py index 482e02a..19b2aad 100644 --- a/Modules/_decimal/tests/formathelper.py +++ b/Modules/_decimal/tests/formathelper.py @@ -31,10 +31,11 @@ import os, sys, locale, random import platform, subprocess +from test.support import import_fresh_module from distutils.spawn import find_executable -import _decimal as C -import _pydecimal as P +C = import_fresh_module('decimal', fresh=['_decimal']) +P = import_fresh_module('decimal', blocked=['_decimal']) windows_lang_strings = [ |