summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Panter <vadmium+py@gmail.com>2016-05-15 01:26:25 (GMT)
committerMartin Panter <vadmium+py@gmail.com>2016-05-15 01:26:25 (GMT)
commitf0dbf7a6abc821c77e912deae81e3a27cf334c54 (patch)
treebf28e30216f084dc637caa140960a9b14e7aef60
parent4dd27f0adcee901bff19c536d8442d666440a415 (diff)
downloadcpython-f0dbf7a6abc821c77e912deae81e3a27cf334c54.zip
cpython-f0dbf7a6abc821c77e912deae81e3a27cf334c54.tar.gz
cpython-f0dbf7a6abc821c77e912deae81e3a27cf334c54.tar.bz2
Issue #26870: Add readline.set_auto_history(), originally by Tyler Crompton
-rw-r--r--Doc/library/readline.rst14
-rw-r--r--Doc/whatsnew/3.6.rst8
-rw-r--r--Lib/test/test_readline.py49
-rw-r--r--Misc/ACKS1
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/readline.c21
6 files changed, 96 insertions, 1 deletions
diff --git a/Doc/library/readline.rst b/Doc/library/readline.rst
index 42e0ad5..f777920 100644
--- a/Doc/library/readline.rst
+++ b/Doc/library/readline.rst
@@ -156,6 +156,20 @@ The following functions operate on a global history list:
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
-------------
diff --git a/Doc/whatsnew/3.6.rst b/Doc/whatsnew/3.6.rst
index 384e35a..bad0f9e 100644
--- a/Doc/whatsnew/3.6.rst
+++ b/Doc/whatsnew/3.6.rst
@@ -239,6 +239,14 @@ Protocol version 4 already supports this case. (Contributed by Serhiy
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
-----------
diff --git a/Lib/test/test_readline.py b/Lib/test/test_readline.py
index 35330ab..84fd119 100644
--- a/Lib/test/test_readline.py
+++ b/Lib/test/test_readline.py
@@ -1,7 +1,11 @@
"""
Very minimal unittests for parts of the readline module.
"""
+from errno import EIO
import os
+import selectors
+import subprocess
+import sys
import tempfile
import unittest
from test.support import import_module, unlink
@@ -96,6 +100,51 @@ class TestReadline(unittest.TestCase):
TERM='xterm-256color')
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__":
unittest.main()
diff --git a/Misc/ACKS b/Misc/ACKS
index ebc3fc6..65d7040 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -307,6 +307,7 @@ Ryan Coyner
Christopher A. Craig
Jeremy Craven
Laura Creighton
+Tyler Crompton
Simon Cross
Felipe Cruz
Drew Csillag
diff --git a/Misc/NEWS b/Misc/NEWS
index bede515..80996bd 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -277,6 +277,10 @@ Core and Builtins
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
file, as well as for extracting data. Patch by Thomas Kluyver.
diff --git a/Modules/readline.c b/Modules/readline.c
index a323b69..de1cc17 100644
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -575,6 +575,24 @@ PyDoc_STRVAR(doc_add_history,
"add_history(string) -> None\n\
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 */
@@ -791,6 +809,7 @@ static struct PyMethodDef readline_methods[] =
{"set_completer_delims", 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},
{"remove_history_item", py_remove_history, METH_VARARGS, doc_remove_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 */
n = strlen(p);
- if (n > 0) {
+ if (should_auto_add_history && n > 0) {
const char *line;
int length = _py_get_history_length();
if (length > 0)