Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
33f8f15b
Commit
33f8f15b
authored
Nov 26, 2014
by
Benjamin Peterson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add readline.append_history_file (closes #22940)
patch by "bru"
parent
aacfcccd
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
106 additions
and
2 deletions
+106
-2
Doc/library/readline.rst
Doc/library/readline.rst
+28
-1
Lib/test/test_readline.py
Lib/test/test_readline.py
+39
-1
Misc/NEWS
Misc/NEWS
+2
-0
Modules/readline.c
Modules/readline.c
+37
-0
No files found.
Doc/library/readline.rst
View file @
33f8f15b
...
...
@@ -59,6 +59,14 @@ The :mod:`readline` module defines the following functions:
Save a readline history file. The default filename is :file:`~/.history`.
.. function:: append_history_file(nelements[, filename])
Append the last *nelements* of history to a file. The default filename is
:file:`~/.history`. The file must already exist.
.. versionadded:: 3.5
.. function:: clear_history()
Clear the current history. (Note: this function is not available if the
...
...
@@ -209,6 +217,26 @@ from the user's :envvar:`PYTHONSTARTUP` file. ::
This code is actually automatically run when Python is run in
:ref:`interactive mode <tut-interactive>` (see :ref:`rlcompleter-config`).
The following example achieves the same goal but supports concurrent interactive
sessions, by only appending the new history. ::
import atexit
import os
import realine
histfile = os.path.join(os.path.expanduser("~"), ".python_history")
try:
readline.read_history_file(histfile)
h_len = readline.get_history_length()
except FileNotFoundError:
open(histfile, 'wb').close()
h_len = 0
def save(prev_h_len, histfile):
new_h_len = readline.get_history_length()
readline.append_history_file(new_h_len - prev_h_len, histfile)
atexit.register(save, h_len, histfile)
The following example extends the :class:`code.InteractiveConsole` class to
support history save/restore. ::
...
...
@@ -234,4 +262,3 @@ support history save/restore. ::
def save_history(self, histfile):
readline.write_history_file(histfile)
Lib/test/test_readline.py
View file @
33f8f15b
...
...
@@ -2,8 +2,9 @@
Very minimal unittests for parts of the readline module.
"""
import
os
import
tempfile
import
unittest
from
test.support
import
run_unittest
,
import_module
from
test.support
import
run_unittest
,
import_module
,
unlink
from
test.script_helper
import
assert_python_ok
# Skip tests if there is no readline module
...
...
@@ -42,6 +43,43 @@ class TestHistoryManipulation (unittest.TestCase):
self
.
assertEqual
(
readline
.
get_current_history_length
(),
1
)
def
test_write_read_append
(
self
):
hfile
=
tempfile
.
NamedTemporaryFile
(
delete
=
False
)
hfile
.
close
()
hfilename
=
hfile
.
name
self
.
addCleanup
(
unlink
,
hfilename
)
# test write-clear-read == nop
readline
.
clear_history
()
readline
.
add_history
(
"first line"
)
readline
.
add_history
(
"second line"
)
readline
.
write_history_file
(
hfilename
)
readline
.
clear_history
()
self
.
assertEqual
(
readline
.
get_current_history_length
(),
0
)
readline
.
read_history_file
(
hfilename
)
self
.
assertEqual
(
readline
.
get_current_history_length
(),
2
)
self
.
assertEqual
(
readline
.
get_history_item
(
1
),
"first line"
)
self
.
assertEqual
(
readline
.
get_history_item
(
2
),
"second line"
)
# test append
readline
.
append_history_file
(
1
,
hfilename
)
readline
.
clear_history
()
readline
.
read_history_file
(
hfilename
)
self
.
assertEqual
(
readline
.
get_current_history_length
(),
3
)
self
.
assertEqual
(
readline
.
get_history_item
(
1
),
"first line"
)
self
.
assertEqual
(
readline
.
get_history_item
(
2
),
"second line"
)
self
.
assertEqual
(
readline
.
get_history_item
(
3
),
"second line"
)
# test 'no such file' behaviour
os
.
unlink
(
hfilename
)
with
self
.
assertRaises
(
FileNotFoundError
):
readline
.
append_history_file
(
1
,
hfilename
)
# write_history_file can create the target
readline
.
write_history_file
(
hfilename
)
class
TestReadline
(
unittest
.
TestCase
):
...
...
Misc/NEWS
View file @
33f8f15b
...
...
@@ -191,6 +191,8 @@ Core and Builtins
Library
-------
-
Issue
#
22940
:
Add
readline
.
append_history_file
.
-
Issue
#
19676
:
Added
the
"namereplace"
error
handler
.
-
Issue
#
22788
:
Add
*
context
*
parameter
to
logging
.
handlers
.
HTTPHandler
.
...
...
Modules/readline.c
View file @
33f8f15b
...
...
@@ -237,6 +237,41 @@ Save a readline history file.\n\
The default filename is ~/.history."
);
/* Exported function to save part of a readline history file */
static
PyObject
*
append_history_file
(
PyObject
*
self
,
PyObject
*
args
)
{
int
nelements
;
PyObject
*
filename_obj
=
Py_None
,
*
filename_bytes
;
char
*
filename
;
int
err
;
if
(
!
PyArg_ParseTuple
(
args
,
"i|O:append_history_file"
,
&
nelements
,
&
filename_obj
))
return
NULL
;
if
(
filename_obj
!=
Py_None
)
{
if
(
!
PyUnicode_FSConverter
(
filename_obj
,
&
filename_bytes
))
return
NULL
;
filename
=
PyBytes_AsString
(
filename_bytes
);
}
else
{
filename_bytes
=
NULL
;
filename
=
NULL
;
}
errno
=
err
=
append_history
(
nelements
,
filename
);
if
(
!
err
&&
_history_length
>=
0
)
history_truncate_file
(
filename
,
_history_length
);
Py_XDECREF
(
filename_bytes
);
errno
=
err
;
if
(
errno
)
return
PyErr_SetFromErrno
(
PyExc_IOError
);
Py_RETURN_NONE
;
}
PyDoc_STRVAR
(
doc_append_history_file
,
"append_history_file(nelements[, filename]) -> None
\n
\
Append the last nelements of the history list to file.
\n
\
The default filename is ~/.history."
);
/* Set history length */
static
PyObject
*
...
...
@@ -747,6 +782,8 @@ static struct PyMethodDef readline_methods[] =
METH_VARARGS
,
doc_read_history_file
},
{
"write_history_file"
,
write_history_file
,
METH_VARARGS
,
doc_write_history_file
},
{
"append_history_file"
,
append_history_file
,
METH_VARARGS
,
doc_append_history_file
},
{
"get_history_item"
,
get_history_item
,
METH_VARARGS
,
doc_get_history_item
},
{
"get_current_history_length"
,
(
PyCFunction
)
get_current_history_length
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment