Issue
In bash I can prevent a command from being saved to bash history by putting a space in front of it. I cannot use this method in ipython. How would I do the equivalent in ipython?
Solution
Obsolescence note: this was written for IPython 4.0.1
. As of v5, IPython no longer uses readline
.
No stock way, can be added in or worked around.
There are two kinds of history in IPython:
readline
history. It is available with special keys/key combinations (up/down, Ctrl-R etc). Only stores lines entered (with<Enter>
) on the console (or, inpyreadline
, pasted from the clipboard, too). IPython relies on a local implementation of the Pythonreadline
API which doesn't have a "do not add" function and normally adds every line to history.
IPython has a facility to alleviate this,IPython.core.interactiveshell.ReadlineNoRecord
, a context manager that makes a snapshot of history then restores it. As ofipython 4.0.1
, it's only used by%run
magic to avoid adding script interactive input to history.IPython history. It's saved in the DB and automatic variables. It contains complete inputs (
readline
grabs each<Enter>
'ed line separately for multiline ones) and outputs. Saving is implemented inHistoryManager.store_inputs()
(for inputs) andHistoryManager.store_output()
(for outputs) which is called fromInteractiveShell.run_cell
and is governed by itsstore_history
argument. The latter is in turn called fromTerminalInteractiveShell.interact
withstore_history=True
.
There are two ways to solve the problem for either layer:
prevent adding the input in the first place. This cannot be done with a magic prefixed to a command, only with one that is run as a separate command and toggles a flag. That's because, as you've seen, the current input has already been stored by the time a magic command gets control.
- readline: there's no relevant entry in the public API, so it's implementation-specific. E.g. for
pyreadline
, adding is done withpyreadline.modes.basemode.BaseMode.add_history()
. The mode object is accessible asget_ipython().readline.rl.mode
. - Decorating
run_cell
andadd_history
with wrappers checking flags in corresponding objects and a custom magic command that sets/toggles them should do the trick.
- readline: there's no relevant entry in the public API, so it's implementation-specific. E.g. for
automatically remove
evidenceinput/output from history immediately after execution. This can be done with a prefix magic.- IPython:
HistoryManager
doesn't have any facilities to remove entries (neither from DB nor from variables). Alas, hacking the DB by hand/replacing stockHistoryManager
is necessary. Also note that the class has an optional cache ofHistoryManager.db_cache_size
(disabled by default). - readline:
remove_history_item(index)
is in the API. You need to know the number of lines in the input.
- IPython:
Alternatively, if you only require this to enter passwords, consider other ways that don't echo the password on screen (thus not making it a part of console history):
getpass.getpass()
- storing it elsewhere (like a configuration file only readable by you)
Answered By - ivan_pozdeev
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.