| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent cecacee commit 1be7598
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1012,6 +1012,12 @@ function to temporarily change the active context. | |||
| 1012 | 1012 | .. versionchanged:: 3.11 | |
| 1013 | 1013 | :meth:`localcontext` now supports setting context attributes through the use of keyword arguments. | |
| 1014 | 1014 | ||
| 1015 | + .. function:: IEEEContext(bits) | ||
| 1016 | + | ||
| 1017 | + Return a context object initialized to the proper values for one of the | ||
| 1018 | + IEEE interchange formats. The argument must be a multiple of 32 and less | ||
| 1019 | + than :const:`IEEE_CONTEXT_MAX_BITS`. | ||
| 1020 | + | ||
| 1015 | 1021 | New contexts can also be created using the :class:`Context` constructor | |
| 1016 | 1022 | described below. In addition, the module provides three pre-made contexts: | |
| 1017 | 1023 | ||
@@ -1533,18 +1539,19 @@ Constants | |||
| 1533 | 1539 | The constants in this section are only relevant for the C module. They | |
| 1534 | 1540 | are also included in the pure Python version for compatibility. | |
| 1535 | 1541 | ||
| 1536 | - +---------------------+---------------------+-------------------------------+ | ||
| 1537 | - | | 32-bit | 64-bit | | ||
| 1538 | - +=====================+=====================+===============================+ | ||
| 1539 | - | .. data:: MAX_PREC | ``425000000`` | ``999999999999999999`` | | ||
| 1540 | - +---------------------+---------------------+-------------------------------+ | ||
| 1541 | - | .. data:: MAX_EMAX | ``425000000`` | ``999999999999999999`` | | ||
| 1542 | - +---------------------+---------------------+-------------------------------+ | ||
| 1543 | - | .. data:: MIN_EMIN | ``-425000000`` | ``-999999999999999999`` | | ||
| 1544 | - +---------------------+---------------------+-------------------------------+ | ||
| 1545 | - | .. data:: MIN_ETINY | ``-849999999`` | ``-1999999999999999997`` | | ||
| 1546 | - +---------------------+---------------------+-------------------------------+ | ||
| 1547 | - | ||
| 1542 | + +---------------------------------+---------------------+-------------------------------+ | ||
| 1543 | + | | 32-bit | 64-bit | | ||
| 1544 | + +=================================+=====================+===============================+ | ||
| 1545 | + | .. data:: MAX_PREC | ``425000000`` | ``999999999999999999`` | | ||
| 1546 | + +---------------------------------+---------------------+-------------------------------+ | ||
| 1547 | + | .. data:: MAX_EMAX | ``425000000`` | ``999999999999999999`` | | ||
| 1548 | + +---------------------------------+---------------------+-------------------------------+ | ||
| 1549 | + | .. data:: MIN_EMIN | ``-425000000`` | ``-999999999999999999`` | | ||
| 1550 | + +---------------------------------+---------------------+-------------------------------+ | ||
| 1551 | + | .. data:: MIN_ETINY | ``-849999999`` | ``-1999999999999999997`` | | ||
| 1552 | + +---------------------------------+---------------------+-------------------------------+ | ||
| 1553 | + | .. data:: IEEE_CONTEXT_MAX_BITS | ``256`` | ``512`` | | ||
| 1554 | + +---------------------------------+---------------------+-------------------------------+ | ||
| 1548 | 1555 | ||
| 1549 | 1556 | .. data:: HAVE_THREADS | |
| 1550 | 1557 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -38,10 +38,10 @@ | |||
| 38 | 38 | 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP', | |
| 39 | 39 | ||
| 40 | 40 | # Functions for manipulating contexts | |
| 41 | - 'setcontext', 'getcontext', 'localcontext', | ||
| 41 | + 'setcontext', 'getcontext', 'localcontext', 'IEEEContext', | ||
| 42 | 42 | ||
| 43 | 43 | # Limits for the C version for compatibility | |
| 44 | - 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', | ||
| 44 | + 'MAX_PREC', 'MAX_EMAX', 'MIN_EMIN', 'MIN_ETINY', 'IEEE_CONTEXT_MAX_BITS', | ||
| 45 | 45 | ||
| 46 | 46 | # C version: compile time choice that enables the thread local context (deprecated, now always true) | |
| 47 | 47 | 'HAVE_THREADS', | |
@@ -83,10 +83,12 @@ | |||
| 83 | 83 | MAX_PREC = 999999999999999999 | |
| 84 | 84 | MAX_EMAX = 999999999999999999 | |
| 85 | 85 | MIN_EMIN = -999999999999999999 | |
| 86 | + IEEE_CONTEXT_MAX_BITS = 512 | ||
| 86 | 87 | else: | |
| 87 | 88 | MAX_PREC = 425000000 | |
| 88 | 89 | MAX_EMAX = 425000000 | |
| 89 | 90 | MIN_EMIN = -425000000 | |
| 91 | + IEEE_CONTEXT_MAX_BITS = 256 | ||
| 90 | 92 | ||
| 91 | 93 | MIN_ETINY = MIN_EMIN - (MAX_PREC-1) | |
| 92 | 94 | ||
@@ -417,6 +419,31 @@ def sin(x): | |||
| 417 | 419 | return ctx_manager | |
| 418 | 420 | ||
| 419 | 421 | ||
| 422 | + def IEEEContext(bits, /): | ||
| 423 | + """ | ||
| 424 | + Return a context object initialized to the proper values for one of the | ||
| 425 | + IEEE interchange formats. The argument must be a multiple of 32 and less | ||
| 426 | + than IEEE_CONTEXT_MAX_BITS. | ||
| 427 | + """ | ||
| 428 | + import sys | ||
| 429 | + | ||
| 430 | + if bits >= sys.maxsize: | ||
| 431 | + raise OverflowError("Python int too large to convert to C ssize_t") | ||
| 432 | + if bits <= 0 or bits > IEEE_CONTEXT_MAX_BITS or bits % 32: | ||
| 433 | + raise ValueError("argument must be a multiple of 32, " | ||
| 434 | + f"with a maximum of {IEEE_CONTEXT_MAX_BITS}") | ||
| 435 | + | ||
| 436 | + ctx = Context() | ||
| 437 | + ctx.prec = 9 * (bits//32) - 2 | ||
| 438 | + ctx.Emax = 3 * (1 << (bits//16 + 3)) | ||
| 439 | + ctx.Emin = 1 - ctx.Emax | ||
| 440 | + ctx.rounding = ROUND_HALF_EVEN | ||
| 441 | + ctx.clamp = 1 | ||
| 442 | + ctx.traps = {s: False for s in _signals} | ||
| 443 | + | ||
| 444 | + return ctx | ||
| 445 | + | ||
| 446 | + | ||
| 420 | 447 | ##### Decimal class ####################################################### | |
| 421 | 448 | ||
| 422 | 449 | # Do not subclass Decimal from numbers.Real and do not register it as such | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -4362,6 +4362,50 @@ class CContextSubclassing(ContextSubclassing, unittest.TestCase): | |||
| 4362 | 4362 | class PyContextSubclassing(ContextSubclassing, unittest.TestCase): | |
| 4363 | 4363 | decimal = P | |
| 4364 | 4364 | ||
| 4365 | + class IEEEContexts: | ||
| 4366 | + | ||
| 4367 | + def test_ieee_context(self): | ||
| 4368 | + # issue 8786: Add support for IEEE 754 contexts to decimal module. | ||
| 4369 | + IEEEContext = self.decimal.IEEEContext | ||
| 4370 | + | ||
| 4371 | + def assert_rest(self, context): | ||
| 4372 | + self.assertEqual(context.clamp, 1) | ||
| 4373 | + assert_signals(self, context, 'traps', []) | ||
| 4374 | + assert_signals(self, context, 'flags', []) | ||
| 4375 | + | ||
| 4376 | + c = IEEEContext(32) | ||
| 4377 | + self.assertEqual(c.prec, 7) | ||
| 4378 | + self.assertEqual(c.Emax, 96) | ||
| 4379 | + self.assertEqual(c.Emin, -95) | ||
| 4380 | + assert_rest(self, c) | ||
| 4381 | + | ||
| 4382 | + c = IEEEContext(64) | ||
| 4383 | + self.assertEqual(c.prec, 16) | ||
| 4384 | + self.assertEqual(c.Emax, 384) | ||
| 4385 | + self.assertEqual(c.Emin, -383) | ||
| 4386 | + assert_rest(self, c) | ||
| 4387 | + | ||
| 4388 | + c = IEEEContext(128) | ||
| 4389 | + self.assertEqual(c.prec, 34) | ||
| 4390 | + self.assertEqual(c.Emax, 6144) | ||
| 4391 | + self.assertEqual(c.Emin, -6143) | ||
| 4392 | + assert_rest(self, c) | ||
| 4393 | + | ||
| 4394 | + # Invalid values | ||
| 4395 | + self.assertRaises(OverflowError, IEEEContext, 2**63) | ||
| 4396 | + self.assertRaises(ValueError, IEEEContext, -1) | ||
| 4397 | + self.assertRaises(ValueError, IEEEContext, 1024) | ||
| 4398 | + | ||
| 4399 | + def test_constants(self): | ||
| 4400 | + # IEEEContext | ||
| 4401 | + self.assertEqual(self.decimal.IEEE_CONTEXT_MAX_BITS, 512) | ||
| 4402 | + | ||
| 4403 | + @requires_cdecimal | ||
| 4404 | + class CIEEEContexts(IEEEContexts, unittest.TestCase): | ||
| 4405 | + decimal = C | ||
| 4406 | + class PyIEEEContexts(IEEEContexts, unittest.TestCase): | ||
| 4407 | + decimal = P | ||
| 4408 | + | ||
| 4365 | 4409 | @skip_if_extra_functionality | |
| 4366 | 4410 | @requires_cdecimal | |
| 4367 | 4411 | class CheckAttributes(unittest.TestCase): | |
@@ -4848,42 +4892,6 @@ def test_py__round(self): | |||
| 4848 | 4892 | class CFunctionality(unittest.TestCase): | |
| 4849 | 4893 | """Extra functionality in _decimal""" | |
| 4850 | 4894 | ||
| 4851 | - @requires_extra_functionality | ||
| 4852 | - def test_c_ieee_context(self): | ||
| 4853 | - # issue 8786: Add support for IEEE 754 contexts to decimal module. | ||
| 4854 | - IEEEContext = C.IEEEContext | ||
| 4855 | - DECIMAL32 = C.DECIMAL32 | ||
| 4856 | - DECIMAL64 = C.DECIMAL64 | ||
| 4857 | - DECIMAL128 = C.DECIMAL128 | ||
| 4858 | - | ||
| 4859 | - def assert_rest(self, context): | ||
| 4860 | - self.assertEqual(context.clamp, 1) | ||
| 4861 | - assert_signals(self, context, 'traps', []) | ||
| 4862 | - assert_signals(self, context, 'flags', []) | ||
| 4863 | - | ||
| 4864 | - c = IEEEContext(DECIMAL32) | ||
| 4865 | - self.assertEqual(c.prec, 7) | ||
| 4866 | - self.assertEqual(c.Emax, 96) | ||
| 4867 | - self.assertEqual(c.Emin, -95) | ||
| 4868 | - assert_rest(self, c) | ||
| 4869 | - | ||
| 4870 | - c = IEEEContext(DECIMAL64) | ||
| 4871 | - self.assertEqual(c.prec, 16) | ||
| 4872 | - self.assertEqual(c.Emax, 384) | ||
| 4873 | - self.assertEqual(c.Emin, -383) | ||
| 4874 | - assert_rest(self, c) | ||
| 4875 | - | ||
| 4876 | - c = IEEEContext(DECIMAL128) | ||
| 4877 | - self.assertEqual(c.prec, 34) | ||
| 4878 | - self.assertEqual(c.Emax, 6144) | ||
| 4879 | - self.assertEqual(c.Emin, -6143) | ||
| 4880 | - assert_rest(self, c) | ||
| 4881 | - | ||
| 4882 | - # Invalid values | ||
| 4883 | - self.assertRaises(OverflowError, IEEEContext, 2**63) | ||
| 4884 | - self.assertRaises(ValueError, IEEEContext, -1) | ||
| 4885 | - self.assertRaises(ValueError, IEEEContext, 1024) | ||
| 4886 | - | ||
| 4887 | 4895 | @requires_extra_functionality | |
| 4888 | 4896 | def test_c_context(self): | |
| 4889 | 4897 | Context = C.Context | |
@@ -4904,12 +4912,6 @@ def test_constants(self): | |||
| 4904 | 4912 | C.DecSubnormal, C.DecUnderflow | |
| 4905 | 4913 | ) | |
| 4906 | 4914 | ||
| 4907 | - # IEEEContext | ||
| 4908 | - self.assertEqual(C.DECIMAL32, 32) | ||
| 4909 | - self.assertEqual(C.DECIMAL64, 64) | ||
| 4910 | - self.assertEqual(C.DECIMAL128, 128) | ||
| 4911 | - self.assertEqual(C.IEEE_CONTEXT_MAX_BITS, 512) | ||
| 4912 | - | ||
| 4913 | 4915 | # Conditions | |
| 4914 | 4916 | for i, v in enumerate(cond): | |
| 4915 | 4917 | self.assertEqual(v, 1<<i) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + Expose function :func:`decimal.IEEEContext()` to support creation of | ||
| 2 | + contexts, corresponding to the IEEE 754 (2008) decimal interchange formats. | ||
| 3 | + Patch by Sergey B Kirpichev. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1516,10 +1516,9 @@ init_extended_context(PyObject *v) | |||
| 1516 | 1516 | CtxCaps(v) = 1; | |
| 1517 | 1517 | } | |
| 1518 | 1518 | ||
| 1519 | - #ifdef EXTRA_FUNCTIONALITY | ||
| 1520 | 1519 | /* Factory function for creating IEEE interchange format contexts */ | |
| 1521 | 1520 | static PyObject * | |
| 1522 | - ieee_context(PyObject *dummy UNUSED, PyObject *v) | ||
| 1521 | + ieee_context(PyObject *self, PyObject *v) | ||
| 1523 | 1522 | { | |
| 1524 | 1523 | PyObject *context; | |
| 1525 | 1524 | mpd_ssize_t bits; | |
@@ -1536,7 +1535,7 @@ ieee_context(PyObject *dummy UNUSED, PyObject *v) | |||
| 1536 | 1535 | goto error; | |
| 1537 | 1536 | } | |
| 1538 | 1537 | ||
| 1539 | - decimal_state *state = get_module_state_by_def(Py_TYPE(v)); | ||
| 1538 | + decimal_state *state = get_module_state(self); | ||
| 1540 | 1539 | context = PyObject_CallObject((PyObject *)state->PyDecContext_Type, NULL); | |
| 1541 | 1540 | if (context == NULL) { | |
| 1542 | 1541 | return NULL; | |
@@ -1552,7 +1551,6 @@ ieee_context(PyObject *dummy UNUSED, PyObject *v) | |||
| 1552 | 1551 | ||
| 1553 | 1552 | return NULL; | |
| 1554 | 1553 | } | |
| 1555 | - #endif | ||
| 1556 | 1554 | ||
| 1557 | 1555 | static PyObject * | |
| 1558 | 1556 | context_copy(PyObject *self, PyObject *args UNUSED) | |
@@ -5751,9 +5749,7 @@ static PyMethodDef _decimal_methods [] = | |||
| 5751 | 5749 | { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext}, | |
| 5752 | 5750 | { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext}, | |
| 5753 | 5751 | { "localcontext", _PyCFunction_CAST(ctxmanager_new), METH_VARARGS|METH_KEYWORDS, doc_localcontext}, | |
| 5754 | - #ifdef EXTRA_FUNCTIONALITY | ||
| 5755 | 5752 | { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context}, | |
| 5756 | - #endif | ||
| 5757 | 5753 | { NULL, NULL, 1, NULL } | |
| 5758 | 5754 | }; | |
| 5759 | 5755 | ||
@@ -5770,11 +5766,8 @@ static struct ssize_constmap ssize_constants [] = { | |||
| 5770 | 5766 | struct int_constmap { const char *name; int val; }; | |
| 5771 | 5767 | static struct int_constmap int_constants [] = { | |
| 5772 | 5768 | /* int constants */ | |
| 5773 | - #ifdef EXTRA_FUNCTIONALITY | ||
| 5774 | - {"DECIMAL32", MPD_DECIMAL32}, | ||
| 5775 | - {"DECIMAL64", MPD_DECIMAL64}, | ||
| 5776 | - {"DECIMAL128", MPD_DECIMAL128}, | ||
| 5777 | 5769 | {"IEEE_CONTEXT_MAX_BITS", MPD_IEEE_CONTEXT_MAX_BITS}, | |
| 5770 | + #ifdef EXTRA_FUNCTIONALITY | ||
| 5778 | 5771 | /* int condition flags */ | |
| 5779 | 5772 | {"DecClamped", MPD_Clamped}, | |
| 5780 | 5773 | {"DecConversionSyntax", MPD_Conversion_syntax}, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -37,15 +37,12 @@ exiting the with-statement. If no context is specified, a copy of the current\n\ | |||
| 37 | 37 | default context is used.\n\ | |
| 38 | 38 | \n"); | |
| 39 | 39 | ||
| 40 | - #ifdef EXTRA_FUNCTIONALITY | ||
| 41 | 40 | PyDoc_STRVAR(doc_ieee_context, | |
| 42 | 41 | "IEEEContext($module, bits, /)\n--\n\n\ | |
| 43 | 42 | Return a context object initialized to the proper values for one of the\n\ | |
| 44 | 43 | IEEE interchange formats. The argument must be a multiple of 32 and less\n\ | |
| 45 | - than IEEE_CONTEXT_MAX_BITS. For the most common values, the constants\n\ | ||
| 46 | - DECIMAL32, DECIMAL64 and DECIMAL128 are provided.\n\ | ||
| 44 | + than IEEE_CONTEXT_MAX_BITS.\n\ | ||
| 47 | 45 | \n"); | |
| 48 | - #endif | ||
| 49 | 46 | ||
| 50 | 47 | ||
| 51 | 48 | /******************************************************************************/ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments