[Python-checkins] bpo-38634: Allow non-apple build to cope with libedit (GH-16986)

Miss Islington (bot) webhook-mailer at python.org
Wed Dec 4 11:21:21 EST 2019


https://github.com/python/cpython/commit/68669ef7883ea6338ca441e50f4f9d975f54d017
commit: 68669ef7883ea6338ca441e50f4f9d975f54d017
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2019-12-04T08:21:16-08:00
summary:

bpo-38634: Allow non-apple build to cope with libedit (GH-16986)


The readline module now detects if Python is linked to libedit at runtime
on all platforms.  Previously, the check was only done on macOS.

If Python is used as a library by a binary linking to libedit, the linker
resolves the rl_initialize symbol required by the readline module against
libedit instead of libreadline, which leads to a segfault.

Take advantage of the existing supporting code to have readline module being
compatible with both situations.
(cherry picked from commit 7105319ada2e663659020cbe9fdf7ff38f421ab2)

Co-authored-by: serge-sans-paille <serge.guelton at telecom-bretagne.eu>

files:
A Misc/NEWS.d/next/Library/2019-12-04-15-56-28.bpo-38634.pq0ZWa.rst
M Modules/readline.c

diff --git a/Misc/NEWS.d/next/Library/2019-12-04-15-56-28.bpo-38634.pq0ZWa.rst b/Misc/NEWS.d/next/Library/2019-12-04-15-56-28.bpo-38634.pq0ZWa.rst
new file mode 100644
index 0000000000000..d60c3172c2e51
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-12-04-15-56-28.bpo-38634.pq0ZWa.rst
@@ -0,0 +1,2 @@
+The :mod:`readline` module now detects if Python is linked to libedit at runtime
+on all platforms.  Previously, the check was only done on macOS.
diff --git a/Modules/readline.c b/Modules/readline.c
index 57335fe911bff..081657fb23699 100644
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -45,14 +45,14 @@ extern char **completion_matches(char *, CPFunction *);
 #endif
 #endif
 
-#ifdef __APPLE__
 /*
  * It is possible to link the readline module to the readline
  * emulation library of editline/libedit.
  *
- * On OSX this emulation library is not 100% API compatible
- * with the "real" readline and cannot be detected at compile-time,
- * hence we use a runtime check to detect if we're using libedit
+ * This emulation library is not 100% API compatible with the "real" readline
+ * and cannot be detected at compile-time,
+ * hence we use a runtime check to detect if the Python readlinke module is
+ * linked to libedit.
  *
  * Currently there is one known API incompatibility:
  * - 'get_history' has a 1-based index with GNU readline, and a 0-based
@@ -64,7 +64,6 @@ static int using_libedit_emulation = 0;
 static const char libedit_version_tag[] = "EditLine wrapper";
 
 static int libedit_history_start = 0;
-#endif /* __APPLE__ */
 
 #ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK
 static void
@@ -693,7 +692,6 @@ get_history_item(PyObject *self, PyObject *args)
 
     if (!PyArg_ParseTuple(args, "i:get_history_item", &idx))
         return NULL;
-#ifdef  __APPLE__
     if (using_libedit_emulation) {
         /* Older versions of libedit's readline emulation
          * use 0-based indexes, while readline and newer
@@ -713,7 +711,6 @@ get_history_item(PyObject *self, PyObject *args)
             Py_RETURN_NONE;
         }
     }
-#endif /* __APPLE__ */
     if ((hist_ent = history_get(idx)))
         return decode(hist_ent->line);
     else {
@@ -1080,7 +1077,6 @@ setup_readline(readlinestate *mod_state)
     /* The name must be defined before initialization */
     rl_readline_name = "python";
 
-#ifdef __APPLE__
     /* the libedit readline emulation resets key bindings etc
      * when calling rl_initialize.  So call it upfront
      */
@@ -1097,7 +1093,6 @@ setup_readline(readlinestate *mod_state)
         libedit_history_start = 1;
     }
     clear_history();
-#endif /* __APPLE__ */
 
     using_history();
 
@@ -1126,9 +1121,7 @@ setup_readline(readlinestate *mod_state)
     mod_state->begidx = PyLong_FromLong(0L);
     mod_state->endidx = PyLong_FromLong(0L);
 
-#ifdef __APPLE__
     if (!using_libedit_emulation)
-#endif
     {
         if (!isatty(STDOUT_FILENO)) {
             /* Issue #19884: stdout is not a terminal. Disable meta modifier
@@ -1148,11 +1141,9 @@ setup_readline(readlinestate *mod_state)
      * XXX: A bug in the readline-2.2 library causes a memory leak
      * inside this function.  Nothing we can do about it.
      */
-#ifdef __APPLE__
     if (using_libedit_emulation)
         rl_read_init_file(NULL);
     else
-#endif /* __APPLE__ */
         rl_initialize();
 
     RESTORE_LOCALE(saved_locale)
@@ -1281,12 +1272,10 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
         int length = _py_get_history_length();
         if (length > 0) {
             HIST_ENTRY *hist_ent;
-#ifdef __APPLE__
             if (using_libedit_emulation) {
                 /* handle older 0-based or newer 1-based indexing */
                 hist_ent = history_get(length + libedit_history_start - 1);
             } else
-#endif /* __APPLE__ */
                 hist_ent = history_get(length);
             line = hist_ent ? hist_ent->line : "";
         } else
@@ -1314,10 +1303,8 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
 PyDoc_STRVAR(doc_module,
 "Importing this module enables command line editing using GNU readline.");
 
-#ifdef __APPLE__
 PyDoc_STRVAR(doc_module_le,
 "Importing this module enables command line editing using libedit readline.");
-#endif /* __APPLE__ */
 
 static struct PyModuleDef readlinemodule = {
     PyModuleDef_HEAD_INIT,
@@ -1338,7 +1325,6 @@ PyInit_readline(void)
     PyObject *m;
     readlinestate *mod_state;
 
-#ifdef __APPLE__
     if (strncmp(rl_library_version, libedit_version_tag, strlen(libedit_version_tag)) == 0) {
         using_libedit_emulation = 1;
     }
@@ -1346,7 +1332,6 @@ PyInit_readline(void)
     if (using_libedit_emulation)
         readlinemodule.m_doc = doc_module_le;
 
-#endif /* __APPLE__ */
 
     m = PyModule_Create(&readlinemodule);
 



More information about the Python-checkins mailing list