FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-157475: Add structured version info for decimal by serhiy-storchaka · Pull Request #157476 · python/cpython · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .py  (2) .rst  (3) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
40 changes: 40 additions & 0 deletions Doc/library/decimal.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1632,6 +1632,46 @@ are also included in the pure Python version for compatibility.

.. versionadded:: 3.8.3

The following constants are only available in the C module.

.. data:: LIBMPDEC_VERSION

The version string of the libmpdec library that was used for building
the module.
This may be different from the libmpdec library actually used at runtime,
which is available as :const:`libmpdec_version`.

.. versionadded:: next

.. data:: libmpdec_version

The version string of the libmpdec library actually loaded by the
interpreter.

.. versionadded:: next

.. data:: LIBMPDEC_VERSION_INFO

A named tuple containing the three components of the libmpdec library
version that was used for building the module:
*major*, *minor*, and *micro*.
All values are integers.
The components can also be accessed by name,
so ``decimal.LIBMPDEC_VERSION_INFO[0]`` is equivalent to
``decimal.LIBMPDEC_VERSION_INFO.major`` and so on.
This may be different from the libmpdec library actually used at runtime,
which is available as :const:`libmpdec_version_info`.

.. versionadded:: next

.. data:: libmpdec_version_info

A named tuple containing the version of the libmpdec library
actually loaded by the interpreter,
with the same fields as :const:`LIBMPDEC_VERSION_INFO`.

.. versionadded:: next


Rounding modes
--------------
Expand Down
10 changes: 10 additions & 0 deletions Doc/whatsnew/3.16.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,16 @@ concurrent.futures
(Contributed by xzmeng and Serhiy Storchaka in :gh:`108518`.)


decimal
-------

* Added constants :const:`~decimal.LIBMPDEC_VERSION`,
:const:`~decimal.libmpdec_version`, :const:`~decimal.LIBMPDEC_VERSION_INFO`,
and :const:`~decimal.libmpdec_version_info` in the C implementation,
which provide information about the version of the libmpdec library in use.
(Contributed by Serhiy Storchaka in :gh:`157475`.)


dbm.gnu
-------

Expand Down
2 changes: 1 addition & 1 deletion Lib/test/pythoninfo.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ def collect_decimal(info_add):
except ImportError:
return

attributes = ('__libmpdec_version__',)
attributes = ('LIBMPDEC_VERSION', 'libmpdec_version')
copy_attributes(info_add, _decimal, '_decimal.%s', attributes)


Expand Down
41 changes: 39 additions & 2 deletions Lib/test/test_decimal.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -4534,8 +4534,13 @@ def test_module_attributes(self):

self.assertEqual(C.SPEC_VERSION, P.SPEC_VERSION)

self.assertLessEqual(set(dir(C)), set(dir(P)))
self.assertEqual([n for n in dir(C) if n[:2] != '__'], sorted(P.__all__))
# Information about the libmpdec library, specific to the C module.
libmpdec_names = {'LIBMPDEC_VERSION', 'LIBMPDEC_VERSION_INFO',
'libmpdec_version', 'libmpdec_version_info'}
self.assertLessEqual(set(dir(C)) - libmpdec_names, set(dir(P)))
self.assertEqual([n for n in dir(C)
if n[:2] != '__' and n not in libmpdec_names],
sorted(P.__all__))

def test_context_attributes(self):

Expand Down Expand Up @@ -5059,6 +5064,38 @@ def test_constants(self):
self.assertEqual(C.DecTraps,
C.DecErrors|C.DecOverflow|C.DecUnderflow)

@requires_cdecimal
class CVersion(unittest.TestCase):
"""Information about the libmpdec library in _decimal"""

def _test_libmpdec_version(self, v, string):
self.assertIsInstance(v[:], tuple)
self.assertEqual(len(v), 3)
self.assertIsInstance(v[0], int)
self.assertIsInstance(v[1], int)
self.assertIsInstance(v[2], int)
self.assertIsInstance(v.major, int)
self.assertIsInstance(v.minor, int)
self.assertIsInstance(v.micro, int)
self.assertEqual(v[0], v.major)
self.assertEqual(v[1], v.minor)
self.assertEqual(v[2], v.micro)
self.assertGreaterEqual(v.major, 2)
self.assertGreaterEqual(v.minor, 0)
self.assertGreaterEqual(v.micro, 0)
self.assertEqual(string, '%d.%d.%d' % v)

def test_libmpdec_version(self):
if support.verbose:
print(f'LIBMPDEC_VERSION = {C.LIBMPDEC_VERSION}', flush=True)
print(f'libmpdec_version = {C.libmpdec_version}', flush=True)
print(f'LIBMPDEC_VERSION_INFO = {C.LIBMPDEC_VERSION_INFO}', flush=True)
print(f'libmpdec_version_info = {C.libmpdec_version_info}', flush=True)
self._test_libmpdec_version(C.LIBMPDEC_VERSION_INFO, C.LIBMPDEC_VERSION)
self._test_libmpdec_version(C.libmpdec_version_info, C.libmpdec_version)
self.assertEqual(C.LIBMPDEC_VERSION_INFO[0], C.libmpdec_version_info[0])
self.assertIs(C.libmpdec_version, C.__libmpdec_version__)

@requires_cdecimal
class CWhitebox(unittest.TestCase):
"""Whitebox testing for _decimal"""
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Add constants :const:`decimal.LIBMPDEC_VERSION`,
:const:`decimal.libmpdec_version`, :const:`decimal.LIBMPDEC_VERSION_INFO`,
and :const:`decimal.libmpdec_version_info` in the C implementation, which
provide information about the version of the libmpdec library in use.
100 changes: 99 additions & 1 deletion Modules/_decimal/_decimal.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7756,6 +7756,104 @@ cfunc_noargs(PyTypeObject *t, const char *name)
return NULL;
}

PyDoc_STRVAR(libmpdec_version_info__doc__,
"decimal.libmpdec_version_info\n\
\n\
libmpdec version information as a named tuple.");

static PyStructSequence_Field libmpdec_version_info_fields[] = {
{"major", "Major release number"},
{"minor", "Minor release number"},
{"micro", "Micro release number"},
{0}
};

static PyStructSequence_Desc libmpdec_version_info_desc = {
"decimal.libmpdec_version_info", /* name */
libmpdec_version_info__doc__, /* doc */
libmpdec_version_info_fields, /* fields */
3
};

static PyObject *
make_libmpdec_version_info(PyTypeObject *type, int major, int minor, int micro)
{
PyObject *version;
int pos = 0;

version = PyStructSequence_New(type);
if (version == NULL) {
return NULL;
}

#define SetItem(VALUE) \
PyStructSequence_SET_ITEM(version, pos++, VALUE); \
if (PyErr_Occurred()) { \
Py_DECREF(version); \
return NULL; \
}

SetItem(PyLong_FromLong(major))
SetItem(PyLong_FromLong(minor))
SetItem(PyLong_FromLong(micro))
#undef SetItem

return version;
}

static PyObject *
parse_libmpdec_version_info(PyTypeObject *type, const char *version)
{
int major, minor, micro;
if (sscanf(version, "%d.%d.%d", &major, &minor, &micro) != 3) {
PyErr_Format(PyExc_RuntimeError,
"unexpected libmpdec version string %s", version);
return NULL;
}
return make_libmpdec_version_info(type, major, minor, micro);
}

static int
add_version_constants(PyObject *m)
{
const char *version = mpd_version();
if (PyModule_AddStringConstant(m, "LIBMPDEC_VERSION", MPD_VERSION) < 0) {
return -1;
}
PyObject *obj = PyUnicode_FromString(version);
if (obj == NULL) {
return -1;
}
if (PyModule_AddObjectRef(m, "libmpdec_version", obj) < 0 ||
PyModule_AddObjectRef(m, "__libmpdec_version__", obj) < 0)
{
Py_DECREF(obj);
return -1;
}
Py_DECREF(obj);
PyTypeObject *version_type;
version_type = PyStructSequence_NewType(&libmpdec_version_info_desc);
if (version_type == NULL) {
return -1;
}
if (PyModule_Add(m, "LIBMPDEC_VERSION_INFO",
make_libmpdec_version_info(version_type, MPD_MAJOR_VERSION,
MPD_MINOR_VERSION,
MPD_MICRO_VERSION)) < 0)
{
Py_DECREF(version_type);
return -1;
}
if (PyModule_Add(m, "libmpdec_version_info",
parse_libmpdec_version_info(version_type, version)) < 0)
{
Py_DECREF(version_type);
return -1;
}
Py_DECREF(version_type);
return 0;
}

static int minalloc_is_set = 0;

static int
Expand Down Expand Up @@ -8004,7 +8102,7 @@ _decimal_exec(PyObject *m)

/* Add specification version number */
CHECK_INT(PyModule_AddStringConstant(m, "SPEC_VERSION", MPD_SPEC_VERSION));
CHECK_INT(PyModule_AddStringConstant(m, "__libmpdec_version__", mpd_version()));
CHECK_INT(add_version_constants(m));

return 0;

Expand Down
Loading

Back | FazBrowse Home | New Git URL