Issue #26870: Add readline.set_auto_history(), originally by Tyler Crompton

This commit is contained in:
Martin Panter 2016-05-15 01:26:25 +00:00
parent 4dd27f0adc
commit f0dbf7a6ab
6 changed files with 96 additions and 1 deletions

View File

@ -156,6 +156,20 @@ The following functions operate on a global history list:
This calls :c:func:`add_history` in the underlying library. This calls :c:func:`add_history` in the underlying library.
.. function:: set_auto_history(enabled)
Enable or disable automatic calls to :c:func:`add_history` when reading
input via readline. The *enabled* argument should be a Boolean value
that when true, enables auto history, and that when False, disables
auto history.
.. versionadded:: 3.6
.. impl-detail::
Auto history is enabled by default, and changes to this do not persist
across multiple sessions.
Startup hooks Startup hooks
------------- -------------

View File

@ -239,6 +239,14 @@ Protocol version 4 already supports this case. (Contributed by Serhiy
Storchaka in :issue:`24164`.) Storchaka in :issue:`24164`.)
readline
--------
Added :func:`~readline.set_auto_history` to enable or disable
automatic addition of input to the history list. (Contributed by
Tyler Crompton in :issue:`26870`.)
rlcompleter rlcompleter
----------- -----------

View File

@ -1,7 +1,11 @@
""" """
Very minimal unittests for parts of the readline module. Very minimal unittests for parts of the readline module.
""" """
from errno import EIO
import os import os
import selectors
import subprocess
import sys
import tempfile import tempfile
import unittest import unittest
from test.support import import_module, unlink from test.support import import_module, unlink
@ -96,6 +100,51 @@ class TestReadline(unittest.TestCase):
TERM='xterm-256color') TERM='xterm-256color')
self.assertEqual(stdout, b'') self.assertEqual(stdout, b'')
auto_history_script = """\
import readline
readline.set_auto_history({})
input()
print("History length:", readline.get_current_history_length())
"""
def test_auto_history_enabled(self):
output = run_pty(self.auto_history_script.format(True))
self.assertIn(b"History length: 1\r\n", output)
def test_auto_history_disabled(self):
output = run_pty(self.auto_history_script.format(False))
self.assertIn(b"History length: 0\r\n", output)
def run_pty(script, input=b"dummy input\r"):
pty = import_module('pty')
output = bytearray()
[master, slave] = pty.openpty()
args = (sys.executable, '-c', script)
proc = subprocess.Popen(args, stdin=slave, stdout=slave, stderr=slave)
os.close(slave)
with proc, selectors.DefaultSelector() as sel:
sel.register(master, selectors.EVENT_READ | selectors.EVENT_WRITE)
os.set_blocking(master, False)
while True:
for [_, events] in sel.select():
if events & selectors.EVENT_READ:
try:
chunk = os.read(master, 0x10000)
except OSError as err:
# Linux raises EIO when the slave is closed
if err.errno != EIO:
raise
chunk = b""
if not chunk:
os.close(master)
return output
output.extend(chunk)
if events & selectors.EVENT_WRITE:
input = input[os.write(master, input):]
if not input:
sel.modify(master, selectors.EVENT_READ)
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

View File

@ -307,6 +307,7 @@ Ryan Coyner
Christopher A. Craig Christopher A. Craig
Jeremy Craven Jeremy Craven
Laura Creighton Laura Creighton
Tyler Crompton
Simon Cross Simon Cross
Felipe Cruz Felipe Cruz
Drew Csillag Drew Csillag

View File

@ -277,6 +277,10 @@ Core and Builtins
Library Library
------- -------
- Issue #26870: Added readline.set_auto_history(), which can stop entries
being automatically added to the history list. Based on patch by Tyler
Crompton.
- Issue #26039: zipfile.ZipFile.open() can now be used to write data into a ZIP - Issue #26039: zipfile.ZipFile.open() can now be used to write data into a ZIP
file, as well as for extracting data. Patch by Thomas Kluyver. file, as well as for extracting data. Patch by Thomas Kluyver.

View File

@ -575,6 +575,24 @@ PyDoc_STRVAR(doc_add_history,
"add_history(string) -> None\n\ "add_history(string) -> None\n\
add an item to the history buffer"); add an item to the history buffer");
static int should_auto_add_history = 1;
/* Enable or disable automatic history */
static PyObject *
py_set_auto_history(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "p:set_auto_history",
&should_auto_add_history)) {
return NULL;
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(doc_set_auto_history,
"set_auto_history(enabled) -> None\n\
Enables or disables automatic history.");
/* Get the tab-completion word-delimiters that readline uses */ /* Get the tab-completion word-delimiters that readline uses */
@ -791,6 +809,7 @@ static struct PyMethodDef readline_methods[] =
{"set_completer_delims", set_completer_delims, {"set_completer_delims", set_completer_delims,
METH_VARARGS, doc_set_completer_delims}, METH_VARARGS, doc_set_completer_delims},
{"set_auto_history", py_set_auto_history, METH_VARARGS, doc_set_auto_history},
{"add_history", py_add_history, METH_VARARGS, doc_add_history}, {"add_history", py_add_history, METH_VARARGS, doc_add_history},
{"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history}, {"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_history},
{"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history}, {"replace_history_item", py_replace_history, METH_VARARGS, doc_replace_history},
@ -1266,7 +1285,7 @@ call_readline(FILE *sys_stdin, FILE *sys_stdout, const char *prompt)
/* we have a valid line */ /* we have a valid line */
n = strlen(p); n = strlen(p);
if (n > 0) { if (should_auto_add_history && n > 0) {
const char *line; const char *line;
int length = _py_get_history_length(); int length = _py_get_history_length();
if (length > 0) if (length > 0)