Commit f0dbf7a6 authored by Martin Panter's avatar Martin Panter

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

parent 4dd27f0a
...@@ -156,6 +156,20 @@ The following functions operate on a global history list: ...@@ -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
------------- -------------
......
...@@ -239,6 +239,14 @@ Protocol version 4 already supports this case. (Contributed by Serhiy ...@@ -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
----------- -----------
......
""" """
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): ...@@ -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()
...@@ -307,6 +307,7 @@ Ryan Coyner ...@@ -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
......
...@@ -277,6 +277,10 @@ Core and Builtins ...@@ -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.
......
...@@ -575,6 +575,24 @@ PyDoc_STRVAR(doc_add_history, ...@@ -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[] = ...@@ -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) ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment