Como posso desativar o novo recurso de histórico no Python 3.4?


10

Desde a atualização para o Python 3.4, todos os comandos interativos são registrados ~/.python_history. Não quero que o Python crie ou grave neste arquivo.

Criando um link simbólico para /dev/nullnão funciona, o Python remove o arquivo e o recria. A documentação sugere excluir sys.__interactivehook__, mas isso também remove o preenchimento de guias. O que deve ser feito para desativar a gravação desse arquivo de histórico, mas ainda preservar o preenchimento de guias?

Detalhes adicionais:


Você já tentou chowning para enraizar?
— 25414 goldilocks

@ goldilocks Eu não considero que uma solução aceitável, e nem está usando chattr. Estou procurando um único arquivo de configuração (usuário) ou variável de ambiente.
— Lekensteyn

Ok, mas você já sabe que não existe uma solução aceitável desde que examinou a documentação.
— Goldilocks

De fato, chmodé a solução sugerida pelos desenvolvedores python neste relatório de bug de algumas semanas atrás, embora também haja alguma menção a ~/.inputrcele (não existe man readline, BTW, exceto a função de biblioteca).
— 25814 goldilocks

@ goldilocks Sim, eu estava prestes a vincular esse relatório de erro. No inputrcentanto, eu não sei como usar e chmodtambém não funciona para mim; o arquivo é modificado de qualquer maneira (Arch Linux). Existe uma info inputrcpágina, mas geralmente não estou tão feliz com a leitura de páginas de informações, pois elas são difíceis de navegar.
— Lekensteyn

Respostas:


7

No Python 3.6, você pode usar o readline.set_auto_history para desativar isso:

import readline
readline.set_auto_history(False)

Isso é bom para o shell do Python, mas cuidado: ele não parece funcionar no ipython.
— z0r 2/09/19

Isso desativa completamente a história. Pessoalmente, estou bem com o histórico sendo preservado em minha sessão de intérprete, mas não quero que meu histórico seja gravado em disco e preservado em todas as sessões.
— jamesdlin

Não funciona Isso não impede que o arquivo seja salvo e, em vez disso, quebra o histórico durante a sessão. De qualquer forma, o Python silenciosamente ativa o "recurso" na próxima vez em que o executar.
— Boann

5

Isso funciona para mim.

Criando ~/.pythonrcarquivo:

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)

Em seguida, exporte-o:

export PYTHONSTARTUP=~/.pythonrc

Isso parece permitir a gravação de um arquivo de histórico em vez de desativá- lo se não me engano? A menos set_history_lengthque algo mágico? O preenchimento de tabulação é feito para funções, não para histórico.
— Lekensteyn

@Lekensteyn: sim, o tamanho do histórico é igual a zero, para que nada seja gravado no arquivo de histórico. Ah, acho que você deseja preservar o comando entre as sessões.
— cuonglm

2
Isso ainda faz ~/.python_historycom que seja gravado (verificado com PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Começo a pensar que não há como desativar isso, mas mantenha a conclusão da guia sem duplicar o código /usr/lib/python3.4/site.py.
— Lekensteyn

AFAIK, não há como realmente desabilitá-lo.
— cuonglm

2

Outra solução ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None

Não sei por que isso não é mais votado. Isso é simples e suprime diretamente a gravação do arquivo de histórico em vez de desabilitar o histórico completamente.
— jamesdlin

Essa foi a única correção que funcionou para mim. Obrigado.
— Boann

1

Para impedir a gravação do Python ~/.python_history, desative o gancho que ativa essa funcionalidade:

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

Se você deseja ativar o preenchimento de guias e desativar o recurso de histórico, pode adaptar o site.enablerlcompletercódigo. Escreva o código a seguir ~/.pythonrce defina export PYTHONSTARTUP=~/.pythonrcno seu shell para habilitá-lo.

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

Até que seja corrigido de alguma forma no próprio Python, você pode fazer isso nos sistemas UNIX:

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

Depois disso, você estará recebendo

Erro em atexit._run_exitfuncs:

IsADirectoryError: [Erro 21] É um diretório

toda vez que você encerra um shell python. O status de saída ainda será 0.

Observe que, se você o deixar como arquivo, precisará criar e tornar imutável outro arquivo, ~/.python_history


0

Coloque o seguinte em um arquivo e defina PYTHONSTARTUP-o (ou chame o arquivo sitecustomize.pye torne-o acessível a partir de PYTHONPATH)

import readline
import atexit
import sys

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

Dessa forma, você ainda terá acesso ao preenchimento de guias e ao histórico anterior, mas os comandos inseridos não serão adicionados ao arquivo do histórico.


Isso não parece funcionar (Python 3.5.1 no Arch Linux), o arquivo de histórico ainda é gravado na saída, mesmo que o PYTHONSTARTUPscript seja realmente executado.
— Lekensteyn

Acabei de testá-lo no meu Arch Linux vm e funciona bem: gist.github.com/berdario/640b3ab00b128fdf3338
— berdario

0

Aqui está o meu método (que acabou por ser basicamente uma versão mais confiável e pitônica do método de berdario). Desativa apenas gravar .python_history, mas não ler, se existir, ou anexar novas linhas ao histórico da instância atual. Eu recomendo salvá-lo como site-packages/sitecustomize.py, porque siteé o módulo que grava .python_historye importa, sitecustomizese existir , embora nomear outra coisa e apontar para ela PYTHONSTARTUPtambém funcione.

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

update: o que fiz para o 3.7, específico do meu sistema, não o 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. Não está funcionando. O histórico ainda está registrado.
— Boann

0

Minha solução atual (para versões suficientes do Python 3) impede o uso padrão de ~ / .python_history, mas deixa a possibilidade de gravação explícita do histórico em um determinado arquivo (usando readline.write_history_file (nome do arquivo) ou readline.append_history_file (... )) deve ter o seguinte no arquivo PYTHONSTARTUP:

import readline
import time

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

Tem o efeito colateral agradável (para mim) rotular qualquer histórico explicitamente escrito com o tempo de inicialização do intérprete. Ele funciona devido à correção do bug 5845, que pode ser vista aqui .

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.