summaryrefslogtreecommitdiffstats
path: root/Modules/_decimal
diff options
context:
space:
mode:
authorAntoine Pitrou <antoine@python.org>2021-03-21 16:27:54 (GMT)
committerGitHub <noreply@github.com>2021-03-21 16:27:54 (GMT)
commitcdddc2b742750e3f289305cf276433a8170c32c1 (patch)
treee4ce948d8cff600cf5721ba00c627f780217a64d /Modules/_decimal
parent77cde5042a2f1eae489c11a67540afaf43cd5cdf (diff)
downloadcpython-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.c200
-rw-r--r--Modules/_decimal/tests/bench.py9
-rw-r--r--Modules/_decimal/tests/deccheck.py81
-rw-r--r--Modules/_decimal/tests/formathelper.py5
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 = [