¿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:


¿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)

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

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

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

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


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.


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

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í .

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.