¿Cómo puedo deshabilitar la nueva función de historial en Python 3.4?

10

Desde la actualización a Python 3.4, se registran todos los comandos interactivos ~/.python_history. No quiero que Python cree o escriba en este archivo.

Crear un enlace simbólico a /dev/nullno funciona, Python elimina el archivo y lo vuelve a crear. La documentación sugiere eliminar el sys.__interactivehook__, pero esto también elimina la finalización de tabulación. ¿Qué se debe hacer para deshabilitar la escritura de este archivo de historial pero aún así preservar la finalización de tabulación?

Detalles adicionales:

Lekensteyn
fuente
¿Has probado a rootearlo?
Ricitos
@goldilocks No considero que sea una solución aceptable, y tampoco lo está usando chattr. Estoy buscando un único archivo de configuración (usuario) o variable de entorno.
Lekensteyn
Está bien, pero ya sabes que no hay una solución aceptable ya que has mirado la documentación.
Ricitos
De hecho, chmodes la solución sugerida por los desarrolladores de python en este informe de error de hace unas semanas, aunque también hay alguna mención de ~/.inputrcallí (no hay man readline, por cierto, excepto por la función de biblioteca).
Ricitos
@goldilocks Sí, estaba a punto de vincularme a ese informe de error. Sin inputrcembargo, no sé cómo usarlo y chmodtampoco funciona para mí, el archivo se modifica de todos modos (Arch Linux). Existe una info inputrcpágina, pero generalmente no estoy tan contento con leer páginas de información, ya que son difíciles de navegar.
Lekensteyn

Respuestas:

7

A partir de Python 3.6, puede usar readline.set_auto_history para deshabilitar esto:

import readline
readline.set_auto_history(False)
Colin Watson
fuente
Eso es bueno para el shell Python, pero cuidado: no parece funcionar en ipython.
z0r
Esto deshabilita la historia por completo. Personalmente, estoy bien con la historia que se conserva en mi sesión de intérprete, pero simplemente no quiero que mi historia se escriba en el disco y se conserve en todas las sesiones.
jamesdlin
No funciona Esto no impide que el archivo se guarde y, en cambio, rompe el historial durante la sesión. En cualquier caso, Python vuelve a activar silenciosamente la "función" la próxima vez que la ejecute.
Boann
5

Esto funciona para mi.

Creando ~/.pythonrcarchivo:

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)

Luego exportarlo:

export PYTHONSTARTUP=~/.pythonrc
Cuonglm
fuente
Esto parece permitir escribir un archivo de historial en lugar de deshabilitarlo si no me equivoco. A menos que set_history_lengthhaga algo mágico? La finalización de tabulación se realiza para funciones, no para el historial.
Lekensteyn
@Lekensteyn: sí, hace que el tamaño del historial sea igual a cero, por lo que no se escribe nada en el archivo del historial. Oh, pensé que querías conservar el comando entre sesiones.
Cuonglm
2
Esto todavía hace ~/.python_historyque se escriba (se verifique con PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Empiezo a pensar que no hay forma de desactivar esto, pero mantengo la finalización de tabulación sin duplicar el código /usr/lib/python3.4/site.py.
Lekensteyn
AFAIK, no hay forma de desactivarlo realmente.
Cuonglm
2

Otra solución ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None
Waxrat
fuente
No sé por qué esto no se vota más. Esto es simple y suprime directamente la escritura del archivo de historial en lugar de deshabilitar el historial por completo.
jamesdlin
Esta fue la única solución que funcionó para mí. Gracias.
Boann
1

Para evitar que Python escriba ~/.python_history, deshabilite el enlace que activa esta funcionalidad:

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

Si desea habilitar la finalización de pestañas y deshabilitar la función de historial, puede adaptar el site.enablerlcompletercódigo. Escriba el siguiente código ~/.pythonrcy configúrelo export PYTHONSTARTUP=~/.pythonrcen su shell para habilitarlo.

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
fuente
0

Hasta que se solucione de alguna manera en Python, puede hacer esto en sistemas UNIX:

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

Después de eso obtendrás

Error en atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] es un directorio

cada vez que terminas un shell de python. El estado de salida seguirá siendo 0.

Tenga en cuenta que si lo deja como archivo, debe crear y hacer inmutable otro archivo, ~/.python_history

int_ua
fuente
0

Ponga lo siguiente en un archivo y configúrelo PYTHONSTARTUP(o llame al archivo sitecustomize.pyy haga que sea accesible desde el PYTHONPATH)

import readline
import atexit
import sys

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

De esta manera, todavía tendrá acceso a la finalización de pestañas y al historial anterior, pero los comandos que ingrese no se agregarán al archivo de historial.

berdario
fuente
Esto no parece funcionar (Python 3.5.1 en Arch Linux), el archivo de historial todavía se escribe al salir, incluso si PYTHONSTARTUPse ejecuta el script.
Lekensteyn
Acabo de probarlo en mi Arch Linux vm, y funciona bien: gist.github.com/berdario/640b3ab00b128fdf3338
berdario
0

Aquí está mi método (que resultó ser básicamente una versión más confiable y pitónica del método de berdario). Solo inhabilita la escritura .python_history, pero no la lectura si existe, o la adición de nuevas líneas al historial de la instancia actual. Recomiendo guardarlo como site-packages/sitecustomize.py, porque sitees el módulo en el que escribe .python_historye importa sitecustomizesi existe , aunque nombrarlo de otra manera y señalarlo también PYTHONSTARTUPfunciona.

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

actualización: lo que hice para 3.7, específico para mi sistema, no pep8:

import rlcompleter,readline as r,sys
def f():r.parse_and_bind('tab:complete');r.read_init_file()
sys.__interactivehook__=f
bebé de vertedero
fuente
Python 3.7.3. No funciona. El historial aún está registrado.
Boann
0

Mi solución actual (para versiones suficientemente recientes de Python 3) evita el uso predeterminado de ~ / .python_history pero deja la posibilidad de escribir explícitamente el historial en un archivo determinado (usando readline.write_history_file (nombre de archivo) o readline.append_history_file (... )) es tener lo siguiente en el archivo PYTHONSTARTUP:

import readline
import time

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

Tiene el efecto secundario agradable (para mí) de etiquetar cualquier historia escrita explícitamente con el tiempo de inicio del intérprete. Funciona debido a la corrección del error 5845 que se puede ver aquí .

Ron Kaminsky
fuente