| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 0f5abe6 commit 8b34557
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,6 +57,38 @@ Readline library in general. | |||
| 57 | 57 | ||
| 58 | 58 | .. versionadded:: 3.13 | |
| 59 | 59 | ||
| 60 | + .. data:: READLINE_VERSION_INFO | ||
| 61 | + | ||
| 62 | + A named tuple containing the two components of the Readline library | ||
| 63 | + version that was used for building the module: *major* and *minor*. | ||
| 64 | + Both values are integers. | ||
| 65 | + The components can also be accessed by name, | ||
| 66 | + so ``readline.READLINE_VERSION_INFO[0]`` is equivalent to | ||
| 67 | + ``readline.READLINE_VERSION_INFO.major`` and so on. | ||
| 68 | + This may be different from the Readline library actually used at runtime, | ||
| 69 | + which is available as :const:`readline_version_info`. | ||
| 70 | + | ||
| 71 | + With the ``editline`` backend, this is the version of the Readline | ||
| 72 | + interface emulated by libedit, not the version of libedit. | ||
| 73 | + | ||
| 74 | + .. versionadded:: next | ||
| 75 | + | ||
| 76 | + .. data:: readline_version_info | ||
| 77 | + | ||
| 78 | + A named tuple containing the version of the Readline library | ||
| 79 | + actually loaded by the interpreter, | ||
| 80 | + with the same fields as :const:`READLINE_VERSION_INFO`. | ||
| 81 | + | ||
| 82 | + .. versionadded:: next | ||
| 83 | + | ||
| 84 | + .. data:: readline_version | ||
| 85 | + | ||
| 86 | + The version string of the Readline library actually loaded by the | ||
| 87 | + interpreter, like ``'8.3'``. | ||
| 88 | + With the ``editline`` backend, this is ``'EditLine wrapper'``. | ||
| 89 | + | ||
| 90 | + .. versionadded:: next | ||
| 91 | + | ||
| 60 | 92 | Init file | |
| 61 | 93 | --------- | |
| 62 | 94 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -530,6 +530,16 @@ pydoc | |||
| 530 | 530 | (Contributed by Serhiy Storchaka in :gh:`153906`.) | |
| 531 | 531 | ||
| 532 | 532 | ||
| 533 | + readline | ||
| 534 | + -------- | ||
| 535 | + | ||
| 536 | + * Added constants :const:`~readline.READLINE_VERSION_INFO`, | ||
| 537 | + :const:`~readline.readline_version_info` and | ||
| 538 | + :const:`~readline.readline_version`, which provide information about | ||
| 539 | + the version of the Readline library in use. | ||
| 540 | + (Contributed by Serhiy Storchaka in :gh:`157485`.) | ||
| 541 | + | ||
| 542 | + | ||
| 533 | 543 | re | |
| 534 | 544 | -- | |
| 535 | 545 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -427,27 +427,13 @@ def collect_readline(info_add): | |||
| 427 | 427 | except ImportError: | |
| 428 | 428 | return | |
| 429 | 429 | ||
| 430 | - def format_attr(attr, value): | ||
| 431 | - if isinstance(value, int): | ||
| 432 | - return "%#x" % value | ||
| 433 | - else: | ||
| 434 | - return value | ||
| 435 | - | ||
| 436 | 430 | attributes = ( | |
| 437 | - "_READLINE_VERSION", | ||
| 438 | - "_READLINE_RUNTIME_VERSION", | ||
| 439 | - "_READLINE_LIBRARY_VERSION", | ||
| 431 | + "backend", | ||
| 432 | + "READLINE_VERSION_INFO", | ||
| 433 | + "readline_version_info", | ||
| 434 | + "readline_version", | ||
| 440 | 435 | ) | |
| 441 | - copy_attributes(info_add, readline, 'readline.%s', attributes, | ||
| 442 | - formatter=format_attr) | ||
| 443 | - | ||
| 444 | - if not hasattr(readline, "_READLINE_LIBRARY_VERSION"): | ||
| 445 | - # _READLINE_LIBRARY_VERSION has been added to CPython 3.7 | ||
| 446 | - doc = getattr(readline, '__doc__', '') | ||
| 447 | - if 'libedit readline' in doc: | ||
| 448 | - info_add('readline.library', 'libedit readline') | ||
| 449 | - elif 'GNU readline' in doc: | ||
| 450 | - info_add('readline.library', 'GNU readline') | ||
| 436 | + copy_attributes(info_add, readline, 'readline.%s', attributes) | ||
| 451 | 437 | ||
| 452 | 438 | ||
| 453 | 439 | def run_command(cmd, check=True, **kwargs): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,21 +19,14 @@ | |||
| 19 | 19 | # Skip tests if there is no readline module | |
| 20 | 20 | readline = import_module('readline') | |
| 21 | 21 | ||
| 22 | - if hasattr(readline, "_READLINE_LIBRARY_VERSION"): | ||
| 23 | - is_editline = ("EditLine wrapper" in readline._READLINE_LIBRARY_VERSION) | ||
| 24 | - else: | ||
| 25 | - is_editline = readline.backend == "editline" | ||
| 22 | + is_editline = readline.backend == "editline" | ||
| 26 | 23 | ||
| 27 | 24 | ||
| 28 | 25 | def setUpModule(): | |
| 29 | 26 | if verbose: | |
| 30 | - # Python implementations other than CPython may not have | ||
| 31 | - # these private attributes | ||
| 32 | - if hasattr(readline, "_READLINE_VERSION"): | ||
| 33 | - print(f"readline version: {readline._READLINE_VERSION:#x}") | ||
| 34 | - print(f"readline runtime version: {readline._READLINE_RUNTIME_VERSION:#x}") | ||
| 35 | - if hasattr(readline, "_READLINE_LIBRARY_VERSION"): | ||
| 36 | - print(f"readline library version: {readline._READLINE_LIBRARY_VERSION!r}") | ||
| 27 | + print(f"readline version: {readline.READLINE_VERSION_INFO}") | ||
| 28 | + print(f"readline runtime version: {readline.readline_version_info}") | ||
| 29 | + print(f"readline library version: {readline.readline_version!r}") | ||
| 37 | 30 | print(f"use libedit emulation? {is_editline}") | |
| 38 | 31 | ||
| 39 | 32 | ||
@@ -210,7 +203,36 @@ def test_append_limited_history(self): | |||
| 210 | 203 | ||
| 211 | 204 | class TestReadline(unittest.TestCase): | |
| 212 | 205 | ||
| 213 | - @unittest.skipIf(readline._READLINE_VERSION < 0x0601 and not is_editline, | ||
| 206 | + def _test_readline_version(self, v): | ||
| 207 | + self.assertIsInstance(v[:], tuple) | ||
| 208 | + self.assertEqual(len(v), 2) | ||
| 209 | + self.assertIsInstance(v[0], int) | ||
| 210 | + self.assertIsInstance(v[1], int) | ||
| 211 | + self.assertIsInstance(v.major, int) | ||
| 212 | + self.assertIsInstance(v.minor, int) | ||
| 213 | + self.assertEqual(v[0], v.major) | ||
| 214 | + self.assertEqual(v[1], v.minor) | ||
| 215 | + self.assertGreaterEqual(v.major, 4) | ||
| 216 | + self.assertGreaterEqual(v.minor, 0) | ||
| 217 | + | ||
| 218 | + def test_readline_version(self): | ||
| 219 | + self._test_readline_version(readline.READLINE_VERSION_INFO) | ||
| 220 | + self._test_readline_version(readline.readline_version_info) | ||
| 221 | + self.assertIsInstance(readline.readline_version, str) | ||
| 222 | + if not is_editline: | ||
| 223 | + self.assertEqual(readline.readline_version, | ||
| 224 | + '%d.%d' % readline.readline_version_info) | ||
| 225 | + # Private names kept for backward compatibility. | ||
| 226 | + self.assertEqual(readline._READLINE_VERSION, | ||
| 227 | + readline.READLINE_VERSION_INFO.major << 8 | | ||
| 228 | + readline.READLINE_VERSION_INFO.minor) | ||
| 229 | + self.assertEqual(readline._READLINE_RUNTIME_VERSION, | ||
| 230 | + readline.readline_version_info.major << 8 | | ||
| 231 | + readline.readline_version_info.minor) | ||
| 232 | + self.assertIs(readline._READLINE_LIBRARY_VERSION, | ||
| 233 | + readline.readline_version) | ||
| 234 | + | ||
| 235 | + @unittest.skipIf(readline.READLINE_VERSION_INFO < (6, 1) and not is_editline, | ||
| 214 | 236 | "not supported in this library version") | |
| 215 | 237 | def test_init(self): | |
| 216 | 238 | # Issue #19884: Ensure that the ANSI sequence "\033[1034h" is not | |
@@ -366,7 +388,7 @@ def display(substitution, matches, longest_match_length): | |||
| 366 | 388 | # See https://cnswww.cns.cwru.edu/php/chet/readline/CHANGES | |
| 367 | 389 | # - editline: history size is broken on OS X 10.11.6. | |
| 368 | 390 | # Newer versions were not tested yet. | |
| 369 | - @unittest.skipIf(readline._READLINE_VERSION < 0x600, | ||
| 391 | + @unittest.skipIf(readline.READLINE_VERSION_INFO < (6, 0), | ||
| 370 | 392 | "this readline version does not support history-size") | |
| 371 | 393 | @unittest.skipIf(is_editline, | |
| 372 | 394 | "editline history size configuration is broken") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + Add constants :const:`readline.READLINE_VERSION_INFO`, | ||
| 2 | + :const:`readline.readline_version_info` and :const:`readline.readline_version`, | ||
| 3 | + which provide information about the version of the Readline library in use. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1802,6 +1802,96 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt) | |||
| 1802 | 1802 | } | |
| 1803 | 1803 | ||
| 1804 | 1804 | ||
| 1805 | + PyDoc_STRVAR(readline_version_info__doc__, | ||
| 1806 | + "readline.readline_version_info\n\ | ||
| 1807 | + \n\ | ||
| 1808 | + Readline version information as a named tuple."); | ||
| 1809 | + | ||
| 1810 | + static PyStructSequence_Field readline_version_info_fields[] = { | ||
| 1811 | + {"major", "Major release number"}, | ||
| 1812 | + {"minor", "Minor release number"}, | ||
| 1813 | + {0} | ||
| 1814 | + }; | ||
| 1815 | + | ||
| 1816 | + static PyStructSequence_Desc readline_version_info_desc = { | ||
| 1817 | + "readline.readline_version_info", /* name */ | ||
| 1818 | + readline_version_info__doc__, /* doc */ | ||
| 1819 | + readline_version_info_fields, /* fields */ | ||
| 1820 | + 2 | ||
| 1821 | + }; | ||
| 1822 | + | ||
| 1823 | + static PyObject * | ||
| 1824 | + make_readline_version_info(PyTypeObject *type, int number) | ||
| 1825 | + { | ||
| 1826 | + PyObject *version; | ||
| 1827 | + int pos = 0; | ||
| 1828 | + int major = (number >> 8) & 0xff; | ||
| 1829 | + int minor = number & 0xff; | ||
| 1830 | + | ||
| 1831 | + version = PyStructSequence_New(type); | ||
| 1832 | + if (version == NULL) { | ||
| 1833 | + return NULL; | ||
| 1834 | + } | ||
| 1835 | + | ||
| 1836 | + #define SetItem(VALUE) \ | ||
| 1837 | + PyStructSequence_SET_ITEM(version, pos++, VALUE); \ | ||
| 1838 | + if (PyErr_Occurred()) { \ | ||
| 1839 | + Py_DECREF(version); \ | ||
| 1840 | + return NULL; \ | ||
| 1841 | + } | ||
| 1842 | + | ||
| 1843 | + SetItem(PyLong_FromLong(major)) | ||
| 1844 | + SetItem(PyLong_FromLong(minor)) | ||
| 1845 | + #undef SetItem | ||
| 1846 | + | ||
| 1847 | + return version; | ||
| 1848 | + } | ||
| 1849 | + | ||
| 1850 | + static int | ||
| 1851 | + add_version_constants(PyObject *m) | ||
| 1852 | + { | ||
| 1853 | + if (PyModule_AddIntConstant(m, "_READLINE_VERSION", | ||
| 1854 | + RL_READLINE_VERSION) < 0) { | ||
| 1855 | + return -1; | ||
| 1856 | + } | ||
| 1857 | + if (PyModule_AddIntConstant(m, "_READLINE_RUNTIME_VERSION", | ||
| 1858 | + rl_readline_version) < 0) { | ||
| 1859 | + return -1; | ||
| 1860 | + } | ||
| 1861 | + PyObject *obj = PyUnicode_FromString(rl_library_version); | ||
| 1862 | + if (obj == NULL) { | ||
| 1863 | + return -1; | ||
| 1864 | + } | ||
| 1865 | + if (PyModule_AddObjectRef(m, "readline_version", obj) < 0 || | ||
| 1866 | + PyModule_AddObjectRef(m, "_READLINE_LIBRARY_VERSION", obj) < 0) | ||
| 1867 | + { | ||
| 1868 | + Py_DECREF(obj); | ||
| 1869 | + return -1; | ||
| 1870 | + } | ||
| 1871 | + Py_DECREF(obj); | ||
| 1872 | + PyTypeObject *version_type; | ||
| 1873 | + version_type = PyStructSequence_NewType(&readline_version_info_desc); | ||
| 1874 | + if (version_type == NULL) { | ||
| 1875 | + return -1; | ||
| 1876 | + } | ||
| 1877 | + if (PyModule_Add(m, "READLINE_VERSION_INFO", | ||
| 1878 | + make_readline_version_info(version_type, | ||
| 1879 | + RL_READLINE_VERSION)) < 0) | ||
| 1880 | + { | ||
| 1881 | + Py_DECREF(version_type); | ||
| 1882 | + return -1; | ||
| 1883 | + } | ||
| 1884 | + if (PyModule_Add(m, "readline_version_info", | ||
| 1885 | + make_readline_version_info(version_type, | ||
| 1886 | + rl_readline_version)) < 0) | ||
| 1887 | + { | ||
| 1888 | + Py_DECREF(version_type); | ||
| 1889 | + return -1; | ||
| 1890 | + } | ||
| 1891 | + Py_DECREF(version_type); | ||
| 1892 | + return 0; | ||
| 1893 | + } | ||
| 1894 | + | ||
| 1805 | 1895 | /* Initialize the module */ | |
| 1806 | 1896 | ||
| 1807 | 1897 | PyDoc_STRVAR(doc_module, | |
@@ -1853,17 +1943,7 @@ PyInit_readline(void) | |||
| 1853 | 1943 | PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED); | |
| 1854 | 1944 | #endif | |
| 1855 | 1945 | ||
| 1856 | - if (PyModule_AddIntConstant(m, "_READLINE_VERSION", | ||
| 1857 | - RL_READLINE_VERSION) < 0) { | ||
| 1858 | - goto error; | ||
| 1859 | - } | ||
| 1860 | - if (PyModule_AddIntConstant(m, "_READLINE_RUNTIME_VERSION", | ||
| 1861 | - rl_readline_version) < 0) { | ||
| 1862 | - goto error; | ||
| 1863 | - } | ||
| 1864 | - if (PyModule_AddStringConstant(m, "_READLINE_LIBRARY_VERSION", | ||
| 1865 | - rl_library_version) < 0) | ||
| 1866 | - { | ||
| 1946 | + if (add_version_constants(m) < 0) { | ||
| 1867 | 1947 | goto error; | |
| 1868 | 1948 | } | |
| 1869 | 1949 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments