Comment puis-je désactiver la nouvelle fonctionnalité d'historique de Python 3.4?

10

Depuis la mise à niveau vers Python 3.4, toutes les commandes interactives sont enregistrées ~/.python_history. Je ne veux pas que Python crée ou écrive dans ce fichier.

La création d'un lien symbolique vers /dev/nullne fonctionne pas, Python supprime le fichier et le recrée. La documentation suggère de supprimer le sys.__interactivehook__, mais cela supprime également la complétion de tabulation. Que faut-il faire pour désactiver l'écriture de ce fichier historique tout en préservant la complétion des tabulations?

Détails supplémentaires:

Lekensteyn
la source
Avez-vous essayé de le réduire en root?
goldilocks
@goldilocks Je ne considère pas que c'est une solution acceptable, et ni l'un ni l'autre ne l'utilise chattr. Je recherche un seul fichier de configuration (utilisateur) ou variable d'environnement.
Lekensteyn
D'accord, mais vous savez déjà qu'il n'y a pas une telle solution acceptable puisque vous avez regardé la documentation.
goldilocks
En fait, chmodest la solution suggérée par les développeurs de python dans ce rapport de bogue d'il y a quelques semaines, bien qu'il y soit également mentionné ~/.inputrc(il n'y a pas de man readlineBTW, sauf pour la fonction de bibliothèque).
goldilocks
@goldilocks Oui, j'étais sur le point de créer un lien vers ce rapport de bogue. Je ne sais pas comment l'utiliser inputrcet chmodne fonctionne pas non plus pour moi, le fichier est quand même modifié (Arch Linux). Il existe une info inputrcpage, mais je ne suis généralement pas si content de lire les pages d'informations car elles sont difficiles à parcourir.
Lekensteyn

Réponses:

7

Depuis Python 3.6, vous pouvez utiliser readline.set_auto_history pour désactiver ceci:

import readline
readline.set_auto_history(False)
Colin Watson
la source
C'est bon pour le shell Python, mais attention: il ne semble pas fonctionner en ipython.
z0r
Cela désactive complètement l'histoire. Personnellement, je suis d'accord avec le fait que l'historique soit préservé dans ma session d'interpréteur, mais je ne veux tout simplement pas que mon historique soit écrit sur le disque et conservé entre les sessions.
jamesdlin
Ça ne marche pas. Cela n'empêche pas le fichier d'être enregistré, et à la place, il rompt l'historique pendant la session. Dans tous les cas, Python réactivera silencieusement la "fonctionnalité" la prochaine fois que vous l'exécuterez.
Boann
5

Cela fonctionne pour moi.

Création de ~/.pythonrcfichier:

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)

Exportez-le ensuite:

export PYTHONSTARTUP=~/.pythonrc
cuonglm
la source
Cela semble permettre d' écrire un fichier historique au lieu de le désactiver si je ne me trompe pas? À moins set_history_lengthque quelque chose ne soit magique? La tabulation est effectuée pour les fonctions, pas pour l'historique.
Lekensteyn
@Lekensteyn: oui, la taille de l'historique est égale à zéro, donc rien n'est écrit dans le fichier historique. Oh, je pensais que vous vouliez conserver la commande entre les sessions.
cuonglm
2
Cela continue ~/.python_historyà être écrit (vérifié avec PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Je commence à penser qu'il n'y a aucun moyen de désactiver cela, mais conservez la tabulation sans dupliquer le code de /usr/lib/python3.4/site.py.
Lekensteyn
AFAIK, il n'y a aucun moyen de vraiment le désactiver.
cuonglm
2

Une autre solution ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None
Waxrat
la source
Je ne sais pas pourquoi ce n'est pas plus voté. C'est simple et supprime directement l' écriture du fichier d'historique au lieu de désactiver complètement l'historique.
jamesdlin
C'était le seul correctif qui a fonctionné pour moi. Merci.
Boann
1

Pour empêcher Python d'écrire ~/.python_history, désactivez le hook qui active cette fonctionnalité:

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

Si vous souhaitez activer la complétion de tabulation et désactiver la fonction d'historique, vous pouvez adapter le site.enablerlcompletercode. Écrivez le code suivant ~/.pythonrcet définissez-le export PYTHONSTARTUP=~/.pythonrcdans votre shell pour l'activer.

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
Lekensteyn
la source
0

Jusqu'à ce qu'il soit corrigé d'une manière ou d'une autre dans Python lui-même, vous pouvez le faire sur les systèmes UNIX:

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

Après cela, vous obtiendrez

Erreur dans atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] Est un répertoire

chaque fois que vous terminez un shell python. Le statut de sortie sera toujours 0.

Notez que si vous le laissez en tant que fichier, vous devez créer et rendre immuable un autre fichier, ~/.python_history

int_ua
la source
0

Mettez ce qui suit dans un fichier et définissez- PYTHONSTARTUPle (ou appelez le fichier sitecustomize.pyet rendez-le accessible à partir du PYTHONPATH)

import readline
import atexit
import sys

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

De cette façon, vous aurez toujours accès à la tabulation et à l'historique précédent, mais les commandes que vous entrez ne seront pas ajoutées au fichier historique.

berdario
la source
Cela ne semble pas fonctionner (Python 3.5.1 sur Arch Linux), le fichier historique est toujours écrit en sortie même si le PYTHONSTARTUPscript est en effet exécuté.
Lekensteyn
Je viens de le tester sur mon Arch Linux vm, et cela fonctionne très bien: gist.github.com/berdario/640b3ab00b128fdf3338
berdario
0

Voici ma méthode (qui s'est avérée être fondamentalement une version plus fiable et pythonique de la méthode de berdario). Il désactive uniquement l'écriture .python_history, mais pas la lecture s'il existe, ou l'ajout de nouvelles lignes à l'historique de l'instance actuelle. Je recommande de l'enregistrer sous site-packages/sitecustomize.py, car sitec'est le module qui écrit .python_historyet importe sitecustomizes'il existe , bien que le nommer autre chose et le pointer avec des PYTHONSTARTUPœuvres fonctionne aussi.

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

mise à jour: ce que j'ai fait pour 3.7, spécifique à mon système, pas pep8:

import rlcompleter,readline as r,sys
def f():r.parse_and_bind('tab:complete');r.read_init_file()
sys.__interactivehook__=f
bébé d'enfouissement
la source
Python 3.7.3. Ca ne fonctionne pas. L'historique est toujours enregistré.
Boann
0

Ma solution actuelle (pour les versions assez récentes de Python 3) empêche l'utilisation par défaut de ~ / .python_history mais laisse la possibilité d'écrire explicitement l'historique dans un fichier donné (en utilisant readline.write_history_file (filename) ou readline.append_history_file (... )) doit avoir ce qui suit dans son fichier PYTHONSTARTUP:

import readline
import time

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

Il a l'effet secondaire agréable (pour moi) étiquetant toute histoire explicitement écrite avec l'heure de démarrage de l'interpréteur. Cela fonctionne grâce au correctif du bogue 5845 qui peut être vu ici .

Ron Kaminsky
la source