From 00f9edb98dd64e14daf5c44f303deca5cbc3cdeb Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 19 Jun 2018 23:29:22 +0200 Subject: [PATCH] bpo-33901: Add _gdbm._GDBM_VERSION (GH-7794) * Fix also PyInit__gdbm() to catch errors. * test.pythoninfo: add gdbm.version * test_dbm_gnu now logs GDBM_VERSION when run in verbose mode. * pythoninfo: rename function to collect_gdbm() --- Lib/test/pythoninfo.py | 10 ++++++++++ Lib/test/test_dbm_gnu.py | 11 +++++++++++ Modules/_gdbmmodule.c | 41 +++++++++++++++++++++++++++++++--------- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Lib/test/pythoninfo.py b/Lib/test/pythoninfo.py index 9242a36bedd..3958764a6ae 100644 --- a/Lib/test/pythoninfo.py +++ b/Lib/test/pythoninfo.py @@ -525,6 +525,15 @@ def collect_cc(info_add): info_add('CC.version', text) +def collect_gdbm(info_add): + try: + import _gdbm + except ImportError: + return + + info_add('gdbm.GDBM_VERSION', '.'.join(map(str, _gdbm._GDBM_VERSION))) + + def collect_info(info): error = False info_add = info.add @@ -552,6 +561,7 @@ def collect_info(info): collect_testcapi, collect_resource, collect_cc, + collect_gdbm, # Collecting from tests should be last as they have side effects. collect_test_socket, diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py index 379601ad86d..49f91705b5b 100644 --- a/Lib/test/test_dbm_gnu.py +++ b/Lib/test/test_dbm_gnu.py @@ -8,6 +8,17 @@ from test.support import TESTFN, TESTFN_NONASCII, unlink filename = TESTFN class TestGdbm(unittest.TestCase): + @staticmethod + def setUpClass(): + if support.verbose: + try: + import _gdbm + version = _gdbm._GDBM_VERSION + except (ImportError, AttributeError): + pass + else: + print(f"gdbm version: {version}") + def setUp(self): self.g = None diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c index 9996d8c26fb..a68cf029429 100644 --- a/Modules/_gdbmmodule.c +++ b/Modules/_gdbmmodule.c @@ -654,20 +654,43 @@ static struct PyModuleDef _gdbmmodule = { PyMODINIT_FUNC PyInit__gdbm(void) { - PyObject *m, *d, *s; + PyObject *m; if (PyType_Ready(&Dbmtype) < 0) return NULL; m = PyModule_Create(&_gdbmmodule); - if (m == NULL) + if (m == NULL) { return NULL; - d = PyModule_GetDict(m); - DbmError = PyErr_NewException("_gdbm.error", PyExc_OSError, NULL); - if (DbmError != NULL) { - PyDict_SetItemString(d, "error", DbmError); - s = PyUnicode_FromString(dbmmodule_open_flags); - PyDict_SetItemString(d, "open_flags", s); - Py_DECREF(s); } + + DbmError = PyErr_NewException("_gdbm.error", PyExc_OSError, NULL); + if (DbmError == NULL) { + goto error; + } + Py_INCREF(DbmError); + if (PyModule_AddObject(m, "error", DbmError) < 0) { + Py_DECREF(DbmError); + goto error; + } + + if (PyModule_AddStringConstant(m, "open_flags", + dbmmodule_open_flags) < 0) { + goto error; + } + + PyObject *obj = Py_BuildValue("iii", GDBM_VERSION_MAJOR, + GDBM_VERSION_MINOR, GDBM_VERSION_PATCH); + if (obj == NULL) { + goto error; + } + if (PyModule_AddObject(m, "_GDBM_VERSION", obj) < 0) { + Py_DECREF(obj); + goto error; + } + return m; + +error: + Py_DECREF(m); + return NULL; }