Come posso disabilitare la nuova funzionalità di cronologia in Python 3.4?


10

Dall'aggiornamento a Python 3.4, tutti i comandi interattivi vengono registrati ~/.python_history. Non voglio che Python crei o scriva su questo file.

La creazione di un collegamento simbolico /dev/nullnon funziona, Python rimuove il file e lo ricrea. La documentazione suggerisce di eliminare il sys.__interactivehook__, ma ciò rimuove anche il completamento della scheda. Cosa si dovrebbe fare per disabilitare la scrittura di questo file di cronologia ma preservare comunque il completamento della scheda?

Dettagli aggiuntivi:


Hai provato a diffonderlo alla radice?
Riccioli d'oro

@goldilocks Non ritengo che sia una soluzione accettabile, e nemmeno la sta usando chattr. Sto cercando un singolo file di configurazione (utente) o una variabile di ambiente.
Lekensteyn,

Va bene, ma sai già che non esiste una soluzione accettabile da quando hai consultato la documentazione.
Riccioli d'oro

In effetti, chmodè la soluzione suggerita dagli sviluppatori di Python in questa segnalazione di bug di alcune settimane fa, anche se c'è anche qualche menzione di ~/.inputrclì (non c'è man readline, BTW, ad eccezione della funzione di libreria).
Riccioli d'oro

@goldilocks Sì, stavo per collegarmi a quel bug report. Non so come usare inputrcperò e chmodnon funziona neanche per me, il file viene comunque modificato (Arch Linux). Esiste una info inputrcpagina, ma in genere non sono così felice di leggere le pagine di informazioni in quanto sono difficili da navigare.
Lekensteyn,

Risposte:


7

A partire da Python 3.6, puoi usare readline.set_auto_history per disabilitare questo:

import readline
readline.set_auto_history(False)

Va bene per la shell Python, ma attenzione: non sembra funzionare in ipython.
z0r,

Questo disabilita completamente la storia. Personalmente sto bene con la cronologia conservata nella mia sessione di interprete, ma non voglio che la mia cronologia venga scritta su disco e conservata in tutte le sessioni.
jamesdlin,

Non funziona Ciò non impedisce il salvataggio del file, ma interrompe la cronologia durante la sessione. In ogni caso, Python riattiva silenziosamente la "funzione" alla successiva esecuzione.
Boann,

5

Questo funziona per me.

Creazione del ~/.pythonrcfile:

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)

Quindi esportalo:

export PYTHONSTARTUP=~/.pythonrc

Questo sembra abilitare la scrittura di un file di cronologia invece di disabilitarlo se non sbaglio? A meno set_history_lengthche non faccia qualcosa di magico? Il completamento della scheda viene eseguito per le funzioni, non per la cronologia.
Lekensteyn,

@Lekensteyn: sì, rende la dimensione della cronologia uguale a zero, quindi nulla viene scritto nel file della cronologia. Oh, ho pensato che tu volessi conservare il comando tra le sessioni.
cuonglm

2
Questo continua ~/.python_historya essere scritto (verificato con PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Comincio a pensare che non ci sia modo di disabilitarlo, ma mantenere il completamento delle schede senza duplicare il codice /usr/lib/python3.4/site.py.
Lekensteyn,

AFAIK, non c'è modo di disabilitarlo davvero.
cuonglm

2

Un'altra soluzione ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None

Non so perché questo non sia più votato. Questo è semplice e sopprime direttamente la scrittura del file della cronologia invece di disabilitare completamente la cronologia.
jamesdlin,

Questa è stata l'unica soluzione che ha funzionato per me. Grazie.
Boann,

1

Per impedire a Python di scrivere ~/.python_history, disabilitare l'hook che attiva questa funzionalità:

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

Se si desidera abilitare il completamento della scheda e disabilitare la funzione cronologia, è possibile adattare il site.enablerlcompletercodice. Scrivi il codice seguente ~/.pythonrce impostalo export PYTHONSTARTUP=~/.pythonrcnella shell per abilitarlo.

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

Fino a quando non viene risolto in qualche modo in Python stesso, puoi farlo sui sistemi UNIX:

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

Dopo ciò otterrai

Errore in atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] È una directory

ogni volta che si termina una shell python. Lo stato di uscita sarà comunque 0.

Nota che se lo lasci come file devi creare e rendere immutabile un altro file, ~/.python_history


0

Inserisci quanto segue in un file e impostalo PYTHONSTARTUP(o chiama il file sitecustomize.pye rendilo accessibile da PYTHONPATH)

import readline
import atexit
import sys

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

In questo modo avrai comunque accesso al completamento della scheda e alla cronologia precedente, ma i comandi che inserisci non verranno aggiunti al file della cronologia.


Questo non sembra funzionare (Python 3.5.1 su Arch Linux), il file di cronologia è ancora scritto all'uscita anche se lo PYTHONSTARTUPscript viene effettivamente eseguito.
Lekensteyn,

L'ho appena testato sul mio Arch Linux VM e funziona benissimo: gist.github.com/berdario/640b3ab00b128fdf3338
berdario

0

Ecco il mio metodo (che si è rivelato sostanzialmente una versione più affidabile e pitonica del metodo berdario). Disabilita solo la scrittura .python_history, ma non la lettura, se esiste, o l'aggiunta di nuove righe alla cronologia dell'istanza corrente. Consiglio di salvarlo come site-packages/sitecustomize.py, perché siteè il modulo che scrive .python_historye importa sitecustomizese esiste , anche se nominarlo con qualcos'altro e indicarlo con PYTHONSTARTUPfunziona anche.

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

aggiornamento: cosa ho fatto per 3.7, specifico per il mio sistema, non per pep8:

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

Python 3.7.3. Non funziona. La cronologia è ancora registrata.
Boann,

0

La mia attuale soluzione (per versioni abbastanza recenti di Python 3) impedisce l'uso predefinito di ~ / .python_history ma lascia la possibilità di scrivere esplicitamente la cronologia in un determinato file (usando readline.write_history_file (nome file) o readline.append_history_file (... )) deve avere quanto segue nel proprio file PYTHONSTARTUP:

import readline
import time

readline.add_history("# " + time.asctime()) # prevent default use of ~/.python_history
readline.set_history_length(-1) # unlimited

Ha il piacevole (per me) effetto collaterale che identifica qualsiasi storia scritta esplicitamente con il tempo di avvio dell'interprete. Funziona a causa della correzione per il bug 5845 che può essere visto qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.