Skip to content

Commit a984076

Browse files
committed
Fix readline history truncation when length is reduced
The `readline.set_history_length()` function did not previously truncate the in-memory history when the new length was set to a value smaller than the current number of history items. This could lead to unexpected behavior where `get_history_length()` would still report the old length and writing the history to a file would write more entries than the new limit. This patch modifies `set_history_length()` to explicitly remove the oldest history entries using `remove_history()` when the length is decreased, ensuring the in-memory history is correctly truncated to the new limit. This brings the function's behavior in line with expectations and fixes failures in `test_write_read_limited_history`. FIXME: In conflict with 208b0fb ? Signed-off-by: Matěj Cepl <mcepl@cepl.eu>
1 parent a183a11 commit a984076

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

Modules/readline.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ static PyModuleDef readlinemodule;
145145

146146
#define readlinestate_global ((readlinestate *)PyModule_GetState(PyState_FindModule(&readlinemodule)))
147147

148+
static int _py_get_history_length(void);
149+
static void _py_free_history_entry(HIST_ENTRY *entry);
148150

149151
/* Convert to/from multibyte C strings */
150152

@@ -384,6 +386,27 @@ readline_set_history_length_impl(PyObject *module, int length)
384386
/*[clinic end generated code: output=e161a53e45987dc7 input=b8901bf16488b760]*/
385387
{
386388
_history_length = length;
389+
390+
if (length < 0) {
391+
stifle_history(-1);
392+
}
393+
else {
394+
int current_length = _py_get_history_length();
395+
if (length < current_length) {
396+
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0500
397+
HISTORY_STATE *state = history_get_history_state();
398+
if (state) {
399+
int i;
400+
for (i = 0; i < current_length - length; i++) {
401+
_py_free_history_entry(remove_history(0));
402+
}
403+
state->length = length;
404+
free(state);
405+
}
406+
#endif
407+
}
408+
stifle_history(length);
409+
}
387410
Py_RETURN_NONE;
388411
}
389412

0 commit comments

Comments
 (0)