Force Python to update command history file from command line?

637 views Asked by At

I use Python without a GUI/IDE by issuing Python from the Bash command line. I use it within a Cygwin environment, which behaves like a Linux system in many respects.

The file used for the history of commands issued at the Python command line is stored in ~/.python_history. I can easily scoot in and yank content for manipulation using vim's Buffer Explorer. It's also easy to yank manipulated content into the system clipboard for pasting at the Python command line. (For more tactical revisions of commands, on the other hand, I just use readline to vim previous commands and a single-line basis.)

I have found that ~/.python_history doesn't update after each command. I'm not sure how often it is updated, but it's clear that exiting Python causes it to update. Putting into the background with Ctrl+Z does not.

(Is there a quick and convenient way from the Python command line to force an update to ~/.python_history?

Since my original posting of this question, I've had occasion to figure out Linux (Ubuntu) as a VirtualBox virtual machine. However, it seems very excessive to fire up an entire guest operating system just to be able to access the command history as a palette as opposed to one line at a time using the Up-Arrow key (or equivalently, k if one's command line editor is set to Vim). I'd even be happy with a Python counterpart to Bash's "fix command" (fc) command, even though I would have to erase all the lines that I don't want to execute.


Various things tried

As per the responses, I tried importing readline.write_history_file, but it isn't recognized, even though readline itself is:

$python
Python 3.8.10 (default, May 20 2021, 11:41:59) 
[GCC 10.2.0] on cygwin
Type "help", "copyright", "credits" or "license" for more information.

# Show modules
>>> import sys
>>> modulenames = set(sys.modules) & set(globals())
>>> allmodules = [sys.modules[name] for name in modulenames]
>>> print(allmodules)
[<module 'sys' (built-in)>]

# Fail to import readline.write_history_file
>>> import readline.write_history_file as whf 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'readline.write_history_file'; 'readline' is not a package

# However, readline itself imports
>>> import readline
>>> readline.get_history_item(2)
'version'

readline does appear to be explicitly part of the Cygwin repository, so I didn't try pip install readline:

  • Search Cygwin packages for readline (followed by browser search for the string python)

  • The one result that appears to be most relevant shows dll,py, and pyc files with readline[s] in the file name, but I'm not sure what that says about the form taken by the readline module itself. I welcome clarifications/explanations about this.

In fact, I'm reluctant to try installing anything outside of the Cygwin package manager using pip for fear of creating inconsistencies.

1

There are 1 answers

5
TheEagle On

Reading through this module, I found out readline.write_history_file(path) may be what you are searching for:

Save the history list to a readline history file, overwriting any existing file. The default filename is ~/.history First thing in the interactive interpreter, do

import readline.write_history_file as whf # write history file

Then you can do whf() or whf("path/to/.historyfile"), and your python history gets saved to disk immediately.

EDIT:

I'm not sure how often it is updated

It is only updated when you exit the interpreter. If you kill it, the history won't get saved, and Ctrl+Z just causes the interpreter to be suspended. If you then unsuspend it (by executing fg or bg, for example) and exit it normally, the history file will get written.