Jak mogę wyłączyć nową funkcję historii w Pythonie 3.4?

10

Od czasu aktualizacji do Python 3.4 wszystkie interaktywne polecenia są logowane do ~/.python_history. Nie chcę, aby Python tworzył lub zapisywał w tym pliku.

Utworzenie dowiązania symbolicznego do /dev/nullnie działa, Python usuwa plik i odtwarza go. Dokumentacja sugeruje, aby usunąć sys.__interactivehook__, ale także usuwa kartę uzupełniania. Co należy zrobić, aby wyłączyć zapisywanie tego pliku historii, ale nadal zachować uzupełnianie tabulacji?

Dodatkowe Szczegóły:

Lekensteyn
źródło
Czy próbowałeś go zrootować?
goldilocks
@Goldilocks Nie uważam tego za akceptowalne rozwiązanie i żadne z nich nie korzysta chattr. Szukam pojedynczego pliku konfiguracyjnego (użytkownika) lub zmiennej środowiskowej.
Lekensteyn,
Okej, ale już wiesz, że nie ma takiego akceptowalnego rozwiązania, odkąd przejrzałeś dokumentację.
goldilocks
W rzeczywistości chmodjest to rozwiązanie sugerowane przez deweloperów python w tym raporcie o błędach sprzed kilku tygodni, chociaż jest tam również wzmianka o ~/.inputrcnich (nie ma man readlineBTW, z wyjątkiem funkcji biblioteki).
goldilocks
@Goldilocks Tak, miałem już link do tego raportu o błędzie. Nie wiem jednak, jak się posługiwać inputrci chmoddla mnie też nie działa, plik i tak zostaje zmodyfikowany (Arch Linux). Istnieje info inputrcstrona, ale ogólnie nie jestem zadowolony z czytania stron informacyjnych, ponieważ są one trudne w nawigacji.
Lekensteyn,

Odpowiedzi:

7

Począwszy od Pythona 3.6, możesz użyć readline.set_auto_history, aby wyłączyć to:

import readline
readline.set_auto_history(False)
Colin Watson
źródło
To jest dobre dla powłoki Pythona, ale uwaga: wydaje się, że nie działa w ipython.
z0r
To całkowicie wyłącza historię. Osobiście nie mam nic przeciwko zachowaniu historii w sesji tłumacza, ale po prostu nie chcę, aby moja historia była zapisywana na dysk i zachowywana między sesjami.
jamesdlin
Nie działa To nie zatrzymuje zapisywania pliku, a zamiast tego psuje historię podczas sesji. W każdym razie Python po cichu włącza „funkcję” przy następnym uruchomieniu.
Boann,
5

To działa dla mnie.

Tworzenie ~/.pythonrcpliku:

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)

Następnie wyeksportuj to:

export PYTHONSTARTUP=~/.pythonrc
Cuonglm
źródło
Wydaje się to umożliwić napisanie pliku historii zamiast wyłączając go, jeśli się nie mylę? Chyba set_history_lengthże coś magicznego? Uzupełnianie tabulatorów jest wykonywane dla funkcji, a nie dla historii.
Lekensteyn,
@ Lekensteyn: tak, sprawia, że ​​rozmiar historii wynosi zero, więc nic nie jest zapisywane w pliku historii. Och, myślałem, że chcesz zachować kontrolę między sesjami.
cuonglm
2
To wciąż powoduje, ~/.python_historyże zostanie napisane (zweryfikowane za pomocą PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Zaczynam myśleć, że nie ma sposobu, aby to wyłączyć, ale zachowaj uzupełnianie tabulatorów bez powielania kodu /usr/lib/python3.4/site.py.
Lekensteyn,
AFAIK, nie ma sposobu, aby to naprawdę wyłączyć.
cuonglm,
2

Inne rozwiązanie ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None
Woskrat
źródło
Nie wiem, dlaczego nie jest to już bardziej doceniane. Jest to proste i bezpośrednio pomija zapisywanie pliku historii zamiast całkowitego wyłączania historii.
jamesdlin
To była jedyna poprawka, która zadziałała dla mnie. Dzięki.
Boann,
1

Aby zapobiec pisaniu w Pythonie ~/.python_history, wyłącz zaczep, który aktywuje tę funkcję:

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

Jeśli chcesz włączyć uzupełnianie tabulatorów i wyłączyć funkcję historii, możesz dostosować site.enablerlcompleterkod. Napisz następujący kod ~/.pythonrci ustaw go export PYTHONSTARTUP=~/.pythonrcw swojej powłoce, aby go włączyć.

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
źródło
0

Dopóki nie zostanie to w jakiś sposób naprawione w samym Pythonie, możesz to zrobić w systemach UNIX:

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

Potem dostaniesz

Błąd w atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] To katalog

za każdym razem, gdy kończysz działanie powłoki Pythona. Status wyjścia będzie nadal wynosił 0.

Zauważ, że jeśli pozostawisz go jako plik, musisz utworzyć i uczynić niezmiennym innym plikiem, ~/.python_history

int_ua
źródło
0

Umieść następujące elementy w pliku i ustaw PYTHONSTARTUPgo (lub wywołaj plik sitecustomize.pyi udostępnij go w PYTHONPATH)

import readline
import atexit
import sys

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

W ten sposób nadal będziesz mieć dostęp do uzupełniania tabulatorów i poprzedniej historii, ale wprowadzone polecenia nie zostaną dodane do pliku historii.

berdario
źródło
Wydaje się, że to nie działa (Python 3.5.1 na Arch Linux), plik historii jest nadal zapisywany przy wyjściu, nawet jeśli PYTHONSTARTUPskrypt jest rzeczywiście wykonywany.
Lekensteyn,
Właśnie przetestowałem go na moim Arch Linux vm i działa dobrze: gist.github.com/berdario/640b3ab00b128fdf3338
berdario
0

Oto moja metoda (która okazała się zasadniczo bardziej niezawodną i pythoniczną wersją metody berdario). Wyłącza tylko zapisywanie .python_history, ale nie czytanie z niego, jeśli istnieje, ani dołączanie nowych wierszy do historii bieżącego wystąpienia. Zalecam zapisanie go jako site-packages/sitecustomize.py, ponieważ sitejest to moduł, który zarówno zapisuje, jak .python_historyi importuje, sitecustomizejeśli istnieje , chociaż nazywanie go czymś innym i wskazywanie go PYTHONSTARTUPrównież działa.

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

aktualizacja: co zrobiłem dla wersji 3.7, specyficznej dla mojego systemu, a nie pep8:

import rlcompleter,readline as r,sys
def f():r.parse_and_bind('tab:complete');r.read_init_file()
sys.__interactivehook__=f
składowisko dziecka
źródło
Python 3.7.3. Nie działa. Historia wciąż się loguje.
Boann,
0

Moje obecne rozwiązanie (dla wystarczającej liczby najnowszych wersji Pythona 3) uniemożliwia domyślne użycie ~ / .python_history, ale pozostawia możliwość wyraźnego zapisu historii do danego pliku (przy użyciu pliku readline.write_history_file (nazwa pliku) lub readline.append_history_file (... )) ma zawierać w pliku PYTHONSTARTUP:

import readline
import time

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

Ma przyjemny (jak dla mnie) efekt uboczny oznaczający dowolnie napisaną historię czasem uruchamiania tłumacza. Działa z powodu poprawki błędu 5845, którą można zobaczyć tutaj .

Ron Kaminsky
źródło