.. 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::
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
---------
# 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')
# 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):
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():
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({})
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')
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)
--- /dev/null
+Add :data:`readline.backend` for the backend readline uses (``editline`` or ``readline``)
PyMODINIT_FUNC
PyInit_readline(void)
{
+ const char *backend = "readline";
PyObject *m;
readlinestate *mod_state;
using_libedit_emulation = 1;
}
- if (using_libedit_emulation)
+ if (using_libedit_emulation) {
readlinemodule.m_doc = doc_module_le;
+ backend = "editline";
+ }
m = PyModule_Create(&readlinemodule);
goto error;
}
+ if (PyModule_AddStringConstant(m, "backend", backend) < 0) {
+ goto error;
+ }
+
mod_state = (readlinestate *) PyModule_GetState(m);
if (mod_state == NULL){
goto error;