diff options
author | 2021-02-12 12:04:46 -0800 | |
---|---|---|
committer | 2021-02-12 12:04:46 -0800 | |
commit | fd053fdd39fbdf114b4218ea4309666bafa95788 (patch) | |
tree | 360827543b553179e7d8526506106076071874d8 /Modules | |
parent | bpo-43204: Fix LibTomCrypt URL in md5module.c and sha*module.c comments (GH-2... (diff) | |
download | cpython-fd053fdd39fbdf114b4218ea4309666bafa95788.tar.gz cpython-fd053fdd39fbdf114b4218ea4309666bafa95788.tar.bz2 cpython-fd053fdd39fbdf114b4218ea4309666bafa95788.zip |
bpo-43172: readline now passes its tests when built against libedit (GH-24499)
bpo-43172: readline now passes its tests when built against libedit.
Existing irreconcilable API differences remain in readline.get_begidx
and readline.get_endidx behavior based on libreadline vs libedit use.
A note about that has been documented.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/clinic/readline.c.h | 10 | ||||
-rw-r--r-- | Modules/readline.c | 38 |
2 files changed, 36 insertions, 12 deletions
diff --git a/Modules/clinic/readline.c.h b/Modules/clinic/readline.c.h index 80207caf071..d1ee8089f73 100644 --- a/Modules/clinic/readline.c.h +++ b/Modules/clinic/readline.c.h @@ -384,7 +384,7 @@ PyDoc_STRVAR(readline_remove_history_item__doc__, "remove_history_item($module, pos, /)\n" "--\n" "\n" -"Remove history item given by its position."); +"Remove history item given by its zero-based position."); #define READLINE_REMOVE_HISTORY_ITEM_METHODDEF \ {"remove_history_item", (PyCFunction)readline_remove_history_item, METH_O, readline_remove_history_item__doc__}, @@ -412,7 +412,9 @@ PyDoc_STRVAR(readline_replace_history_item__doc__, "replace_history_item($module, pos, line, /)\n" "--\n" "\n" -"Replaces history item given by its position with contents of line."); +"Replaces history item given by its position with contents of line.\n" +"\n" +"pos is zero-based."); #define READLINE_REPLACE_HISTORY_ITEM_METHODDEF \ {"replace_history_item", (PyCFunction)(void(*)(void))readline_replace_history_item, METH_FASTCALL, readline_replace_history_item__doc__}, @@ -563,7 +565,7 @@ PyDoc_STRVAR(readline_get_history_item__doc__, "get_history_item($module, index, /)\n" "--\n" "\n" -"Return the current contents of history item at index."); +"Return the current contents of history item at one-based index."); #define READLINE_GET_HISTORY_ITEM_METHODDEF \ {"get_history_item", (PyCFunction)readline_get_history_item, METH_O, readline_get_history_item__doc__}, @@ -683,4 +685,4 @@ readline_redisplay(PyObject *module, PyObject *Py_UNUSED(ignored)) #ifndef READLINE_CLEAR_HISTORY_METHODDEF #define READLINE_CLEAR_HISTORY_METHODDEF #endif /* !defined(READLINE_CLEAR_HISTORY_METHODDEF) */ -/*[clinic end generated code: output=cb44f391ccbfb565 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=f7d390113b27989f input=a9049054013a1b77]*/ diff --git a/Modules/readline.c b/Modules/readline.c index 02b2c40e6b9..c900e079543 100644 --- a/Modules/readline.c +++ b/Modules/readline.c @@ -67,7 +67,8 @@ extern char **completion_matches(char *, CPFunction *); static int using_libedit_emulation = 0; static const char libedit_version_tag[] = "EditLine wrapper"; -static int libedit_history_start = 0; +static int8_t libedit_history_start = 0; +static int8_t libedit_append_replace_history_offset = 0; #ifdef HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK static void @@ -320,7 +321,8 @@ readline_append_history_file_impl(PyObject *module, int nelements, filename_bytes = NULL; filename = NULL; } - errno = err = append_history(nelements, filename); + errno = err = append_history( + nelements - libedit_append_replace_history_offset, filename); if (!err && _history_length >= 0) history_truncate_file(filename, _history_length); Py_XDECREF(filename_bytes); @@ -592,12 +594,12 @@ readline.remove_history_item pos as entry_number: int / -Remove history item given by its position. +Remove history item given by its zero-based position. [clinic start generated code]*/ static PyObject * readline_remove_history_item_impl(PyObject *module, int entry_number) -/*[clinic end generated code: output=ab114f029208c7e8 input=c8520ac3da50224e]*/ +/*[clinic end generated code: output=ab114f029208c7e8 input=f248beb720ff1838]*/ { HIST_ENTRY *entry; @@ -626,12 +628,14 @@ readline.replace_history_item / Replaces history item given by its position with contents of line. + +pos is zero-based. [clinic start generated code]*/ static PyObject * readline_replace_history_item_impl(PyObject *module, int entry_number, PyObject *line) -/*[clinic end generated code: output=f8cec2770ca125eb input=b7ccef0780ae041b]*/ +/*[clinic end generated code: output=f8cec2770ca125eb input=368bb66fe5ee5222]*/ { PyObject *encoded; HIST_ENTRY *old_entry; @@ -645,7 +649,9 @@ readline_replace_history_item_impl(PyObject *module, int entry_number, if (encoded == NULL) { return NULL; } - old_entry = replace_history_entry(entry_number, PyBytes_AS_STRING(encoded), (void *)NULL); + old_entry = replace_history_entry( + entry_number + libedit_append_replace_history_offset, + PyBytes_AS_STRING(encoded), (void *)NULL); Py_DECREF(encoded); if (!old_entry) { PyErr_Format(PyExc_ValueError, @@ -786,12 +792,12 @@ readline.get_history_item index as idx: int / -Return the current contents of history item at index. +Return the current contents of history item at one-based index. [clinic start generated code]*/ static PyObject * readline_get_history_item_impl(PyObject *module, int idx) -/*[clinic end generated code: output=83d3e53ea5f34b3d input=63fff0c3c4323269]*/ +/*[clinic end generated code: output=83d3e53ea5f34b3d input=8adf5c80e6c7ff2b]*/ { HIST_ENTRY *hist_ent; @@ -1191,6 +1197,22 @@ setup_readline(readlinestate *mod_state) } else { libedit_history_start = 1; } + /* Some libedit implementations use 1 based indexing on + * replace_history_entry where libreadline uses 0 based. + * The API our module presents is supposed to be 0 based. + * It's a mad mad mad mad world. + */ + { + add_history("2"); + HIST_ENTRY *old_entry = replace_history_entry(1, "X", NULL); + _py_free_history_entry(old_entry); + HIST_ENTRY *item = history_get(libedit_history_start); + if (item && item->line && strcmp(item->line, "X")) { + libedit_append_replace_history_offset = 0; + } else { + libedit_append_replace_history_offset = 1; + } + } clear_history(); using_history(); |