mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-76007: Deprecate __version__ attribute in decimal (#140302)
Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Sergey B Kirpichev <skirpichev@gmail.com> Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
This commit is contained in:
parent
33b2ca80bb
commit
00026d19c2
8 changed files with 74 additions and 7 deletions
|
|
@ -8,6 +8,7 @@ Pending removal in Python 3.20
|
||||||
- :mod:`argparse`
|
- :mod:`argparse`
|
||||||
- :mod:`csv`
|
- :mod:`csv`
|
||||||
- :mod:`!ctypes.macholib`
|
- :mod:`!ctypes.macholib`
|
||||||
|
- :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
|
||||||
- :mod:`imaplib`
|
- :mod:`imaplib`
|
||||||
- :mod:`ipaddress`
|
- :mod:`ipaddress`
|
||||||
- :mod:`json`
|
- :mod:`json`
|
||||||
|
|
|
||||||
|
|
@ -1569,7 +1569,16 @@ In addition to the three supplied contexts, new contexts can be created with the
|
||||||
Constants
|
Constants
|
||||||
---------
|
---------
|
||||||
|
|
||||||
The constants in this section are only relevant for the C module. They
|
.. data:: SPEC_VERSION
|
||||||
|
|
||||||
|
The highest version of the General Decimal Arithmetic
|
||||||
|
Specification that this implementation complies with.
|
||||||
|
See https://speleotrove.com/decimal/decarith.html for the specification.
|
||||||
|
|
||||||
|
.. versionadded:: next
|
||||||
|
|
||||||
|
|
||||||
|
The following constants are only relevant for the C module. They
|
||||||
are also included in the pure Python version for compatibility.
|
are also included in the pure Python version for compatibility.
|
||||||
|
|
||||||
+---------------------------------+---------------------+-------------------------------+
|
+---------------------------------+---------------------+-------------------------------+
|
||||||
|
|
|
||||||
|
|
@ -851,6 +851,7 @@ New deprecations
|
||||||
- :mod:`argparse`
|
- :mod:`argparse`
|
||||||
- :mod:`csv`
|
- :mod:`csv`
|
||||||
- :mod:`!ctypes.macholib`
|
- :mod:`!ctypes.macholib`
|
||||||
|
- :mod:`decimal` (use :data:`decimal.SPEC_VERSION` instead)
|
||||||
- :mod:`imaplib`
|
- :mod:`imaplib`
|
||||||
- :mod:`ipaddress`
|
- :mod:`ipaddress`
|
||||||
- :mod:`json`
|
- :mod:`json`
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,16 @@
|
||||||
'HAVE_THREADS',
|
'HAVE_THREADS',
|
||||||
|
|
||||||
# C version: compile time choice that enables the coroutine local context
|
# C version: compile time choice that enables the coroutine local context
|
||||||
'HAVE_CONTEXTVAR'
|
'HAVE_CONTEXTVAR',
|
||||||
|
|
||||||
|
# Highest version of the spec this module complies with
|
||||||
|
'SPEC_VERSION',
|
||||||
]
|
]
|
||||||
|
|
||||||
__xname__ = __name__ # sys.modules lookup (--without-threads)
|
__xname__ = __name__ # sys.modules lookup (--without-threads)
|
||||||
__name__ = 'decimal' # For pickling
|
__name__ = 'decimal' # For pickling
|
||||||
__version__ = '1.70' # Highest version of the spec this complies with
|
SPEC_VERSION = '1.70' # Highest version of the spec this complies with
|
||||||
# See http://speleotrove.com/decimal/
|
# See https://speleotrove.com/decimal/decarith.html
|
||||||
__libmpdec_version__ = "2.4.2" # compatible libmpdec version
|
__libmpdec_version__ = "2.4.2" # compatible libmpdec version
|
||||||
|
|
||||||
import math as _math
|
import math as _math
|
||||||
|
|
@ -6399,3 +6402,11 @@ def _format_number(is_negative, intpart, fracpart, exp, spec):
|
||||||
# _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS
|
# _PyHASH_10INV is the inverse of 10 modulo the prime _PyHASH_MODULUS
|
||||||
_PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
|
_PyHASH_10INV = pow(10, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
|
||||||
del sys
|
del sys
|
||||||
|
|
||||||
|
def __getattr__(name):
|
||||||
|
if name == "__version__":
|
||||||
|
from warnings import _deprecated
|
||||||
|
|
||||||
|
_deprecated("__version__", remove=(3, 20))
|
||||||
|
return SPEC_VERSION
|
||||||
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,8 @@
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from _decimal import *
|
from _decimal import *
|
||||||
from _decimal import __version__ # noqa: F401
|
|
||||||
from _decimal import __libmpdec_version__ # noqa: F401
|
from _decimal import __libmpdec_version__ # noqa: F401
|
||||||
|
from _decimal import __getattr__ # noqa: F401
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import _pydecimal
|
import _pydecimal
|
||||||
import sys
|
import sys
|
||||||
|
|
|
||||||
|
|
@ -4474,7 +4474,7 @@ def test_module_attributes(self):
|
||||||
self.assertTrue(C.HAVE_THREADS is True or C.HAVE_THREADS is False)
|
self.assertTrue(C.HAVE_THREADS is True or C.HAVE_THREADS is False)
|
||||||
self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False)
|
self.assertTrue(P.HAVE_THREADS is True or P.HAVE_THREADS is False)
|
||||||
|
|
||||||
self.assertEqual(C.__version__, P.__version__)
|
self.assertEqual(C.SPEC_VERSION, P.SPEC_VERSION)
|
||||||
|
|
||||||
self.assertLessEqual(set(dir(C)), set(dir(P)))
|
self.assertLessEqual(set(dir(C)), set(dir(P)))
|
||||||
self.assertEqual([n for n in dir(C) if n[:2] != '__'], sorted(P.__all__))
|
self.assertEqual([n for n in dir(C) if n[:2] != '__'], sorted(P.__all__))
|
||||||
|
|
@ -5929,6 +5929,23 @@ def doit(ty):
|
||||||
doit('Context')
|
doit('Context')
|
||||||
|
|
||||||
|
|
||||||
|
class TestModule:
|
||||||
|
def test_deprecated__version__(self):
|
||||||
|
with self.assertWarnsRegex(
|
||||||
|
DeprecationWarning,
|
||||||
|
"'__version__' is deprecated and slated for removal in Python 3.20",
|
||||||
|
) as cm:
|
||||||
|
getattr(self.decimal, "__version__")
|
||||||
|
self.assertEqual(cm.filename, __file__)
|
||||||
|
|
||||||
|
|
||||||
|
@requires_cdecimal
|
||||||
|
class CTestModule(TestModule, unittest.TestCase):
|
||||||
|
decimal = C
|
||||||
|
class PyTestModule(TestModule, unittest.TestCase):
|
||||||
|
decimal = P
|
||||||
|
|
||||||
|
|
||||||
def load_tests(loader, tests, pattern):
|
def load_tests(loader, tests, pattern):
|
||||||
if TODO_TESTS is not None:
|
if TODO_TESTS is not None:
|
||||||
# Run only Arithmetic tests
|
# Run only Arithmetic tests
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
:mod:`decimal`: Deprecate ``__version__`` and replace with
|
||||||
|
:data:`decimal.SPEC_VERSION`.
|
||||||
|
|
@ -58,6 +58,9 @@
|
||||||
|
|
||||||
#include "clinic/_decimal.c.h"
|
#include "clinic/_decimal.c.h"
|
||||||
|
|
||||||
|
#define MPD_SPEC_VERSION "1.70" // Highest version of the spec this complies with
|
||||||
|
// See https://speleotrove.com/decimal/decarith.html
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
module _decimal
|
module _decimal
|
||||||
class _decimal.Decimal "PyObject *" "&dec_spec"
|
class _decimal.Decimal "PyObject *" "&dec_spec"
|
||||||
|
|
@ -7566,12 +7569,35 @@ static PyType_Spec context_spec = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
decimal_getattr(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *name;
|
||||||
|
if (!PyArg_UnpackTuple(args, "__getattr__", 1, 1, &name)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PyUnicode_Check(name) && PyUnicode_EqualToUTF8(name, "__version__")) {
|
||||||
|
if (PyErr_WarnEx(PyExc_DeprecationWarning,
|
||||||
|
"'__version__' is deprecated and slated for removal in Python 3.20",
|
||||||
|
1) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyUnicode_FromString(MPD_SPEC_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyErr_Format(PyExc_AttributeError, "module 'decimal' has no attribute %R", name);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef _decimal_methods [] =
|
static PyMethodDef _decimal_methods [] =
|
||||||
{
|
{
|
||||||
_DECIMAL_GETCONTEXT_METHODDEF
|
_DECIMAL_GETCONTEXT_METHODDEF
|
||||||
_DECIMAL_SETCONTEXT_METHODDEF
|
_DECIMAL_SETCONTEXT_METHODDEF
|
||||||
_DECIMAL_LOCALCONTEXT_METHODDEF
|
_DECIMAL_LOCALCONTEXT_METHODDEF
|
||||||
_DECIMAL_IEEECONTEXT_METHODDEF
|
_DECIMAL_IEEECONTEXT_METHODDEF
|
||||||
|
{"__getattr__", decimal_getattr, METH_VARARGS, "Module __getattr__"},
|
||||||
{ NULL, NULL, 1, NULL }
|
{ NULL, NULL, 1, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -7891,7 +7917,7 @@ _decimal_exec(PyObject *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add specification version number */
|
/* Add specification version number */
|
||||||
CHECK_INT(PyModule_AddStringConstant(m, "__version__", "1.70"));
|
CHECK_INT(PyModule_AddStringConstant(m, "SPEC_VERSION", MPD_SPEC_VERSION));
|
||||||
CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
|
CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue