7

Since upgrading to Python 3.4, all interactive commands are logged to ~/.python_history. I don't want Python to create or write to this file.

Creating a symlink to /dev/null does not work, Python removes the file and recreates it. The documentation suggests to delete the sys.__interactivehook__, but this also removes tab-completion. What should be done to disable writing this history file but still preserve tab-completion?

Additional details:

  • Have you tried chowning it to root? – goldilocks Mar 25 '14 at 15:45
  • @goldilocks I do not consider that an acceptable solution, and neither is using chattr. I am looking for a single (user) configuration file or environment variable. – Lekensteyn Mar 25 '14 at 15:47
  • Okay, but you already know there is no such acceptable solution since you've looked at the documentation. – goldilocks Mar 25 '14 at 15:50
  • In fact, chmod is the solution suggested by python devs in this bug report from a few weeks ago, although there is also some mention of ~/.inputrc there (there is no man readline, BTW, except for the library function). – goldilocks Mar 25 '14 at 15:55
  • @goldilocks Yes, I was about to link to that bug report. I don't know how to use inputrc though and chmod does not work for me either, the file gets modified anyway (Arch Linux). There exists an info inputrc page, but I am generally not so happy with reading info pages as they are difficult to navigate through. – Lekensteyn Mar 25 '14 at 15:56
5

As of Python 3.6, you can use readline.set_auto_history to disable this:

import readline
readline.set_auto_history(False)
3

This works for me.

Creating ~/.pythonrc file:

import os
import atexit
import readline

readline_history_file = os.path.join(os.path.expanduser('~'), '.python_history')
try:
    readline.read_history_file(readline_history_file)
except IOError:
    pass

readline.set_history_length(0)
atexit.register(readline.write_history_file, readline_history_file)

Then export it:

export PYTHONSTARTUP=~/.pythonrc
  • This seems to enable writing a history file instead of disabling it if I am not mistaken? Unless set_history_length does something magical? Tab-completion is done for functions, not history. – Lekensteyn Mar 25 '14 at 16:52
  • @Lekensteyn: yes, it make history size equal zero so nothing is written to history file. Oh, I though you want to preserve command between sessions. – cuonglm Mar 25 '14 at 16:54
  • 1
    This still causes ~/.python_history to be written (verified with PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). I start to think that there is no way to disable this, but keep tab-completion without duplicating code from /usr/lib/python3.4/site.py. – Lekensteyn Mar 25 '14 at 16:58
  • AFAIK, there is no way to really disable it. – cuonglm Mar 25 '14 at 17:06
1

To prevent Python from writing ~/.python_history, disable the hook that activates this functionality:

import sys
# Disable history (...but also auto-completion :/ )
if hasattr(sys, '__interactivehook__'):
    del sys.__interactivehook__

If you would like to enable tab-completion and disable the history feature, you can adapt the site.enablerlcompleter code. Write the following code to ~/.pythonrc and set export PYTHONSTARTUP=~/.pythonrc in your shell to enable it.

import sys
def register_readline_completion():
    # rlcompleter must be loaded for Python-specific completion
    try: import readline, rlcompleter
    except ImportError: return
    # Enable tab-completion
    readline_doc = getattr(readline, '__doc__', '')
    if readline_doc is not None and 'libedit' in readline_doc:
        readline.parse_and_bind('bind ^I rl_complete')
    else:
        readline.parse_and_bind('tab: complete')
sys.__interactivehook__ = register_readline_completion
0

Until it's fixed in some way in Python itself you can do this on UNIX systems:

rm ~/.python-history
mkdir ~/.python-history
sudo chattr +i ~/.python-history || sudo chflags simmutable ~/.python-history

After that you will be getting

Error in atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] Is a directory

every time you terminate a python shell. Exit status will still be 0.

Notice that if you leave it as file you need to create and make immutable another file, ~/.python_history

0

Put the following in a file and set PYTHONSTARTUP to it (or call the file sitecustomize.py and make it accessible from the PYTHONPATH)

import readline
import atexit
import sys

sys.__interactivehook__()
atexit.unregister(readline.write_history_file)

This way you'll still have access to tab-completion and previous history, but the commands you enter won't be added to the history file.

  • This does not seem to work (Python 3.5.1 on Arch Linux), the history file is still written on exit even through the PYTHONSTARTUP script is indeed executed. – Lekensteyn Feb 9 '16 at 14:39
  • I just tested it on my Arch Linux vm, and it works fine: gist.github.com/berdario/640b3ab00b128fdf3338 – berdario Feb 10 '16 at 0:54
0

Another ~/.pythonrc solution:

import readline
readline.write_history_file = lambda *args: None
0

Here's my method (which turned out to be basically a more reliable and pythonic version of berdario's method). It only disables writing to .python_history, but not reading from it if it exists, or appending new lines to the current instance's history. I recommend saving it as site-packages/sitecustomize.py, because site is the module that both writes to .python_history and imports sitecustomize if it exists, although naming it something else and pointing to it with PYTHONSTARTUP works too.

import sys
oldhook = getattr(sys, '__interactivehook__', None)
if oldhook:
    def newhook():
        import readline, atexit
        oldhook()
        atexit.unregister(readline.write_history_file)
    sys.__interactivehook__ = newhook

update: what i did for 3.7, specific to my system, not pep8:

import rlcompleter,readline as r,sys
def f():r.parse_and_bind('tab:complete');r.read_init_file()
sys.__interactivehook__=f

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.