]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-112510: Add `readline.backend` for the backend readline uses (GH-112511)
authorTian Gao <gaogaotiantian@hotmail.com>
Fri, 1 Dec 2023 14:05:55 +0000 (05:05 -0900)
committerGitHub <noreply@github.com>
Fri, 1 Dec 2023 14:05:55 +0000 (14:05 +0000)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Donghee Na <donghee.na92@gmail.com>
Doc/library/readline.rst
Lib/site.py
Lib/test/test_pdb.py
Lib/test/test_readline.py
Misc/NEWS.d/next/Library/2023-11-29-02-26-32.gh-issue-112510.j-zXGc.rst [new file with mode: 0644]
Modules/readline.c

index 8fb0eca8df74d89ba161036eb4bbd84b08719a56..2e0f45ced30b9cdc0dee881301de0d9a52d610ce 100644 (file)
@@ -27,16 +27,15 @@ Readline library in general.
 .. note::
 
   The underlying Readline library API may be implemented by
-  the ``libedit`` library instead of GNU readline.
+  the ``editline`` (``libedit``) library instead of GNU readline.
   On macOS the :mod:`readline` module detects which library is being used
   at run time.
 
-  The configuration file for ``libedit`` is different from that
+  The configuration file for ``editline`` is different from that
   of GNU readline. If you programmatically load configuration strings
-  you can check for the text "libedit" in :const:`readline.__doc__`
-  to differentiate between GNU readline and libedit.
+  you can use :data:`backend` to determine which library is being used.
 
-  If you use *editline*/``libedit`` readline emulation on macOS, the
+  If you use ``editline``/``libedit`` readline emulation on macOS, the
   initialization file located in your home directory is named
   ``.editrc``. For example, the following content in ``~/.editrc`` will
   turn ON *vi* keybindings and TAB completion::
@@ -44,6 +43,12 @@ Readline library in general.
     python:bind -v
     python:bind ^I rl_complete
 
+.. data:: backend
+
+   The name of the underlying Readline library being used, either
+   ``"readline"`` or ``"editline"``.
+
+   .. versionadded:: 3.13
 
 Init file
 ---------
index 672fa7b000ad02c8815ed2abae32135fdd5c457b..2517b7e5f1d22a3f10d73a16ea2f231afa2ded1c 100644 (file)
@@ -444,8 +444,7 @@ def enablerlcompleter():
 
         # Reading the initialization (config) file may not be enough to set a
         # completion key, so we set one first and then read the file.
-        readline_doc = getattr(readline, '__doc__', '')
-        if readline_doc is not None and 'libedit' in readline_doc:
+        if readline.backend == 'editline':
             readline.parse_and_bind('bind ^I rl_complete')
         else:
             readline.parse_and_bind('tab: complete')
index 2a279ca869e9c7ba7bc7e123a492d72c457f138a..50d8c8f52a909de500214a3da5d5a1a2950dd8f6 100644 (file)
@@ -3293,7 +3293,7 @@ class PdbTestReadline(unittest.TestCase):
         # Ensure that the readline module is loaded
         # If this fails, the test is skipped because SkipTest will be raised
         readline = import_module('readline')
-        if readline.__doc__ and "libedit" in readline.__doc__:
+        if readline.backend == "editline":
             raise unittest.SkipTest("libedit readline is not supported for pdb")
 
     def test_basic_completion(self):
index 6c2726d3209ecf049373bd47a959dab177db33ea..5e0e6f8dfac6510cebc02f6bea937c58e55671ca 100644 (file)
@@ -19,7 +19,7 @@ readline = import_module('readline')
 if hasattr(readline, "_READLINE_LIBRARY_VERSION"):
     is_editline = ("EditLine wrapper" in readline._READLINE_LIBRARY_VERSION)
 else:
-    is_editline = (readline.__doc__ and "libedit" in readline.__doc__)
+    is_editline = readline.backend == "editline"
 
 
 def setUpModule():
@@ -145,6 +145,9 @@ class TestReadline(unittest.TestCase):
                                               TERM='xterm-256color')
         self.assertEqual(stdout, b'')
 
+    def test_backend(self):
+        self.assertIn(readline.backend, ("readline", "editline"))
+
     auto_history_script = """\
 import readline
 readline.set_auto_history({})
@@ -171,7 +174,7 @@ print("History length:", readline.get_current_history_length())
                 if state == 0 and text == "$":
                     return "$complete"
                 return None
-            if "libedit" in getattr(readline, "__doc__", ""):
+            if readline.backend == "editline":
                 readline.parse_and_bind(r'bind "\\t" rl_complete')
             else:
                 readline.parse_and_bind(r'"\\t": complete')
@@ -198,7 +201,7 @@ print("History length:", readline.get_current_history_length())
 
         script = r"""import readline
 
-is_editline = readline.__doc__ and "libedit" in readline.__doc__
+is_editline = readline.backend == "editline"
 inserted = "[\xEFnserted]"
 macro = "|t\xEB[after]"
 set_pre_input_hook = getattr(readline, "set_pre_input_hook", None)
diff --git a/Misc/NEWS.d/next/Library/2023-11-29-02-26-32.gh-issue-112510.j-zXGc.rst b/Misc/NEWS.d/next/Library/2023-11-29-02-26-32.gh-issue-112510.j-zXGc.rst
new file mode 100644 (file)
index 0000000..02de6fa
--- /dev/null
@@ -0,0 +1 @@
+Add :data:`readline.backend` for the backend readline uses (``editline`` or ``readline``)
index eb9a3d4693ee90b8d99ac78be71244110314e02e..afbb7f8f0ec18f62b9e2d8c6eae37e23e4ca4c49 100644 (file)
@@ -1538,6 +1538,7 @@ static struct PyModuleDef readlinemodule = {
 PyMODINIT_FUNC
 PyInit_readline(void)
 {
+    const char *backend = "readline";
     PyObject *m;
     readlinestate *mod_state;
 
@@ -1545,8 +1546,10 @@ PyInit_readline(void)
         using_libedit_emulation = 1;
     }
 
-    if (using_libedit_emulation)
+    if (using_libedit_emulation) {
         readlinemodule.m_doc = doc_module_le;
+        backend = "editline";
+    }
 
 
     m = PyModule_Create(&readlinemodule);
@@ -1568,6 +1571,10 @@ PyInit_readline(void)
         goto error;
     }
 
+    if (PyModule_AddStringConstant(m, "backend", backend) < 0) {
+        goto error;
+    }
+
     mod_state = (readlinestate *) PyModule_GetState(m);
     if (mod_state == NULL){
         goto error;