Как я могу отключить новую функцию истории в Python 3.4?

10

После обновления до Python 3.4 все интерактивные команды регистрируются в ~/.python_history. Я не хочу, чтобы Python создавал или записывал в этот файл.

Создание символической ссылки на /dev/nullне работает, Python удаляет файл и создает его заново. Документация предлагает удалить sys.__interactivehook__, но это также удаляет табуляции завершения. Что нужно сделать, чтобы отключить запись этого файла истории, но при этом сохранить завершение табуляции?

Дополнительные детали:

Lekensteyn
источник
Вы пробовали подавить это рут?
Златовласка
@goldilocks Я не считаю это приемлемым решением, и ни один не использует chattr. Я ищу один (пользовательский) файл конфигурации или переменную среды.
Лекенштейн
Хорошо, но вы уже знаете, что нет такого приемлемого решения, так как вы просмотрели документацию.
Златовласка
Фактически, chmodэто решение, предложенное разработчиками python в этом отчете об ошибках несколько недель назад, хотя там также есть упоминание ~/.inputrc(нет man readline, кстати, кроме функции библиотеки).
Златовласка
@goldilocks Да, я собирался дать ссылку на этот отчет об ошибке. Я не знаю, как использовать, inputrcи chmodу меня тоже не работает, файл все равно модифицируется (Arch Linux). Существует info inputrcстраница, но я, как правило, не очень доволен чтением информационных страниц, так как по ним сложно ориентироваться.
Лекенштейн

Ответы:

7

Начиная с Python 3.6, вы можете использовать readline.set_auto_history, чтобы отключить это:

import readline
readline.set_auto_history(False)
Колин Уотсон
источник
Это хорошо для оболочки Python, но будьте осторожны: похоже, она не работает в ipython.
z0r
Это полностью отключает историю. Лично я в порядке с историей, сохраняемой в моем сеансе интерпретатора, но я просто не хочу, чтобы моя история записывалась на диск и сохранялась между сеансами.
Джеймсдлин
Не работает Это не останавливает сохранение файла, а вместо этого разрушает историю во время сеанса. В любом случае, Python автоматически включит «функцию» при следующем запуске.
Boann
5

Это работает для меня.

Создание ~/.pythonrcфайла:

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)

Затем экспортируйте это:

export PYTHONSTARTUP=~/.pythonrc
cuonglm
источник
Кажется, это позволяет писать файл истории, а не отключать его, если я не ошибаюсь? Разве set_history_lengthчто-то волшебное? Завершение табуляции выполняется для функций, а не для истории.
Лекенштейн
@Lekensteyn: да, размер истории равен нулю, поэтому в файл истории ничего не записывается. О, я думаю, вы хотите сохранить команду между сессиями.
cuonglm
2
Это все еще заставляет ~/.python_historyбыть написанным (проверено с PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Я начинаю думать, что нет способа отключить это, но продолжаю табуляцию без дублирования кода /usr/lib/python3.4/site.py.
Лекенштейн
AFAIK, нет способа действительно отключить его.
cuonglm
2

Другое решение ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None
Waxrat
источник
Я не знаю, почему за это больше не голосуют. Это просто и напрямую подавляет запись файла истории вместо полного отключения истории.
Джеймсдлин
Это было единственное исправление, которое сработало для меня. Спасибо.
Boann
1

Чтобы запретить Python писать ~/.python_history, отключите хук, который активирует эту функцию:

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

Если вы хотите включить завершение табуляции и отключить функцию истории, вы можете адаптировать site.enablerlcompleterкод. Напишите следующий код ~/.pythonrcи установите его export PYTHONSTARTUP=~/.pythonrcв своей оболочке, чтобы включить его.

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
источник
0

Пока это не исправлено каким-либо образом в самом Python, вы можете делать это в системах UNIX:

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

После этого вы будете получать

Ошибка в atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] является каталогом

каждый раз, когда вы завершаете работу оболочки Python. Статус выхода все равно будет 0.

Обратите внимание, что если вы оставите его как файл, вам нужно создать и сделать неизменным другой файл, ~/.python_history

int_ua
источник
0

Поместите следующее в файл и установите PYTHONSTARTUPего (или вызовите файл sitecustomize.pyи сделайте его доступным из PYTHONPATH)

import readline
import atexit
import sys

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

Таким образом, вы по-прежнему будете иметь доступ к завершению табуляции и предыдущей истории, но введенные вами команды не будут добавлены в файл истории.

berdario
источник
Это не похоже на работу (Python 3.5.1 в Arch Linux), файл истории все еще записывается при выходе, даже если PYTHONSTARTUPскрипт действительно выполняется.
Лекенштейн
Я только что проверил его на моем Arch Linux vm, и он отлично работает: gist.github.com/berdario/640b3ab00b128fdf3338
berdario
0

Вот мой метод (который оказался в основном более надежной и питонной версией метода Бердарио). Он только запрещает запись в него .python_history, но не считывает его, если он существует, или добавляет новые строки в историю текущего экземпляра. Я рекомендую сохранить его как site-packages/sitecustomize.py, потому что siteэто модуль, который пишет .python_historyи импортирует, sitecustomizeесли он существует , хотя и называет его чем-то другим и указывает на него PYTHONSTARTUPтоже.

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

Обновление: что я сделал для 3.7, специфично для моей системы, а не для 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. Не работает. История все еще вошла.
Boann
0

Мое текущее решение (для достаточно недавних версий Python 3) предотвращает использование по умолчанию ~ / .python_history, но оставляет возможность явной записи истории в заданный файл (используя readline.write_history_file (имя файла) или readline.append_history_file (... )) в файле PYTHONSTARTUP должно быть следующее:

import readline
import time

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

У него есть приятный (для меня) побочный эффект, помечающий любую явно написанную историю временем запуска интерпретатора. Это работает из-за исправления ошибки 5845, которое можно увидеть здесь .

Рон Каминский
источник