`readline` — GNU readline 인터페이스

readline — GNU readline 인터페이스

readline 모듈은 Python 인터프리터에서 완성과 히스토리 파일의 읽기/쓰기를 돕는 여러 함수를 정의해요. 이 모듈은 직접 쓸 수도 있고, 인터랙티브 프롬프트에서 Python 식별자 완성을 지원하는 rlcompleter 모듈을 통해 쓸 수도 있어요. 이 모듈로 만든 설정은 인터프리터의 인터랙티브 프롬프트와 내장 input() 함수가 제공하는 프롬프트 양쪽의 동작에 영향을 줘요.

readline 키바인딩은 일반적으로 홈 디렉터리의 .inputrc 같은 초기화 파일로 설정할 수 있어요. 파일의 형식과 허용되는 구성, 그리고 Readline 라이브러리 전반의 기능에 대해서는 GNU Readline 매뉴얼의 "Readline Init File"을 참고하세요.

가용성: Android, iOS, WASI가 아님. 이 모듈은 모바일 플랫폼이나 WebAssembly 플랫폼에서 지원되지 않아요. 가용성: Unix. 이것은 선택 모듈이에요.

기본 Readline 라이브러리 API는 GNU readline 대신 editline(libedit) 라이브러리로 구현될 수 있어요. macOS에서 readline 모듈은 런타임에 어떤 라이브러리가 쓰이는지 감지해요. editline의 설정 파일은 GNU readline과 달라요. 프로그래밍 방식으로 설정 문자열을 불러온다면 backend로 어떤 라이브러리가 쓰이는지 판별할 수 있어요.

macOS에서 editline/libedit readline 에뮬레이션을 쓴다면, 홈 디렉터리의 초기화 파일은 .editrc라는 이름이에요. 예를 들어 ~/.editrc에 다음 내용이 있으면 vi 키바인딩과 TAB 완성을 켜요:

python:bind -v
python:bind ^I rl_complete

또한 서로 다른 라이브러리는 서로 다른 히스토리 파일 형식을 쓸 수 있다는 점도 기억하세요. 기본 라이브러리를 바꾸면 기존 히스토리 파일을 쓸 수 없게 될 수 있어요.

readline.backend

사용 중인 기본 Readline 라이브러리의 이름으로, "readline" 또는 "editline"이에요. 버전 3.13에서 추가됨.

출처: Python 표준 라이브러리

본문

초기화 파일 (Init file)

readline.parse_and_bind(*string*)

string 인자에 주어진 초기화 줄을 실행해요. 기본 라이브러리의 rl_parse_and_bind()를 호출해요.

readline.read_init_file([*filename*])

readline 초기화 파일을 실행해요. 기본 파일 이름은 마지막에 사용한 파일 이름이에요. 기본 라이브러리의 rl_read_init_file()을 호출해요. 주어진 파일 이름이 있으면 감사 이벤트 open을, 없으면 "<readline_init_file>"으로 그 이벤트를 발생시켜요(라이브러리가 실제로 어떤 파일을 해석하는지와 무관). 버전 3.14 변경: 감사 이벤트가 추가됨.

줄 버퍼 (Line buffer)

readline.get_line_buffer()

줄 버퍼의 현재 내용을 반환해요(기본 라이브러리의 rl_line_buffer).

readline.insert_text(*string*)

커서 위치의 줄 버퍼에 텍스트를 삽입해요. 기본 라이브러리의 rl_insert_text()를 호출하지만 반환 값은 무시해요.

readline.redisplay()

줄 버퍼의 현재 내용을 반영하도록 화면에 표시되는 것을 바꿔요. 기본 라이브러리의 rl_redisplay()를 호출해요.

히스토리 파일 (History file)

readline.read_history_file([*filename*])

readline 히스토리 파일을 불러와 히스토리 목록에 덧붙여요. 기본 파일 이름은 ~/.history예요. 기본 라이브러리의 read_history()를 호출하고, 파일 이름이 주어지면 그 이름으로, 아니면 "~/.history"로 감사 이벤트 open을 발생시켜요. 버전 3.14 변경: 감사 이벤트 추가.

readline.write_history_file([*filename*])

히스토리 목록을 readline 히스토리 파일에 저장해 기존 파일을 덮어써요. 기본 파일 이름은 ~/.history예요. 기본 라이브러리의 write_history()를 호출하고 감사 이벤트 open을 발생시켜요. 버전 3.14 변경: 감사 이벤트 추가.

readline.append_history_file(*nelements*[, *filename*])

히스토리의 마지막 nelements 항목을 파일에 덧붙여요. 기본 파일 이름은 ~/.history예요. 파일은 이미 존재해야 해요. 기본 라이브러리의 append_history()를 호출해요. 이 함수는 그것을 지원하는 버전의 라이브러리에 맞게 Python이 컴파일된 경우에만 존재해요. 감사 이벤트 open을 발생시켜요. 버전 3.5에서 추가, 버전 3.14 변경: 감사 이벤트 추가.

readline.get_history_length(), readline.set_history_length(*length*)

히스토리 파일에 저장할 원하는 줄 수를 설정하거나 반환해요. write_history_file() 함수는 기본 라이브러리의 history_truncate_file()을 호출해 이 값으로 히스토리 파일을 잘라요. 음수 값은 무제한 히스토리 파일 크기를 의미해요.

히스토리 목록 (History list)

readline.clear_history()

현재 히스토리를 지워요. 기본 라이브러리의 clear_history()를 호출해요. 이 Python 함수는 그것을 지원하는 버전의 라이브러리에 맞게 컴파일된 경우에만 존재해요.

readline.get_current_history_length()

현재 히스토리에 있는 항목 수를 반환해요. (히스토리 파일에 쓰이는 최대 줄 수를 반환하는 get_history_length()와는 달라요.)

readline.get_history_item(*index*)

index에 있는 히스토리 항목의 현재 내용을 반환해요. 항목 인덱스는 1부터 시작해요. 기본 라이브러리의 history_get()을 호출해요.

readline.remove_history_item(*pos*)

위치로 지정된 히스토리 항목을 히스토리에서 제거해요. 위치는 0부터 시작해요. 기본 라이브러리의 remove_history()를 호출해요.

readline.replace_history_item(*pos*, *line*)

위치로 지정된 히스토리 항목을 line으로 교체해요. 위치는 0부터 시작해요. 기본 라이브러리의 replace_history_entry()를 호출해요.

readline.add_history(*line*)

마지막으로 입력된 줄인 것처럼 line을 히스토리 버퍼에 덧붙여요. 기본 라이브러리의 add_history()를 호출해요.

readline.set_auto_history(*enabled*)

readline을 통해 입력을 읽을 때 add_history()의 자동 호출을 켜거나 꺼요. enabled 인자는 불리언 값이어야 하며, 참이면 자동 히스토리를 켜고 거짓이면 꺼요. 버전 3.6에서 추가됨.

CPython 구현 세부 사항: 자동 히스토리는 기본적으로 켜져 있고, 이에 대한 변경은 여러 세션에 걸쳐 지속되지 않아요.

시작 훅 (Startup hooks)

readline.set_startup_hook([*function*])

기본 라이브러리의 rl_startup_hook 콜백이 호출하는 함수를 설정하거나 제거해요. function이 지정되면 새 훅 함수로 쓰이고, 생략하거나 None이면 이미 설치된 함수를 제거해요. 이 훅은 readline이 첫 프롬프트를 출력하기 직전에 인자 없이 호출돼요.

readline.set_pre_input_hook([*function*])

기본 라이브러리의 rl_pre_input_hook 콜백이 호출하는 함수를 설정하거나 제거해요. 첫 프롬프트가 출력된 뒤, readline이 입력 문자를 읽기 직전에 인자 없이 호출돼요. 이 함수는 그것을 지원하는 버전의 라이브러리에 맞게 컴파일된 경우에만 존재해요.

완성 (Completion)

readline.set_completer([*function*])

완성기 함수를 설정하거나 제거해요. function이 지정되면 새 완성기 함수로 쓰이고, 생략하거나 None이면 이미 설치된 완성기 함수를 제거해요. 완성기 함수는 state0, 1, 2, …일 때 function(text, state)로 호출되다가 비문자열 값을 반환할 때까지 계속돼요. text로 시작하는 다음 가능한 완성을 반환해야 해요.

설치된 완성기 함수는 기본 라이브러리의 rl_completion_matches()에 넘겨진 entry_func 콜백이 호출해요. text 문자열은 기본 라이브러리의 rl_attempted_completion_function 콜백의 첫 번째 매개변수에서 옵니다.

readline.get_completer()

완성기 함수를 가져오거나, 설정된 완성기 함수가 없으면 None을 반환해요.

readline.get_completion_type()

시도 중인 완성의 유형을 가져와요. 기본 라이브러리의 rl_completion_type 변수를 정수로 반환해요.

readline.get_begidx(), readline.get_endidx()

완성 범위(scope)의 시작 또는 끝 인덱스를 가져와요. 이 인덱스들은 기본 라이브러리의 rl_attempted_completion_function 콜백에 넘겨지는 startend 인자예요. 같은 입력 편집 시나리오라도 기본 C readline 구현에 따라 값이 다를 수 있어요. 예: libedit은 libreadline과 다르게 동작하는 것으로 알려져 있어요.

readline.set_completer_delims(*string*), readline.get_completer_delims()

완성을 위한 단어 구분 기호를 설정하거나 가져와요. 이들은 완성을 고려할 단어의 시작(완성 범위)을 결정해요. 기본 라이브러리의 rl_completer_word_break_characters 변수에 접근해요.

readline.set_completion_display_matches_hook([*function*])

완성 표시 함수를 설정하거나 제거해요. 기본 라이브러리의 rl_completion_display_matches_hook 콜백을 설정하거나 지워요. 완성 표시 함수는 일치 목록을 표시해야 할 때마다 function(substitution, [matches], longest_match_length)로 한 번 호출돼요.

예시 (Example)

다음 예시는 readline 모듈의 히스토리 읽기·쓰기 함수를 사용해 사용자 홈 디렉터리의 .python_history라는 히스토리 파일을 자동으로 불러오고 저장하는 방법을 보여줘요. 아래 코드는 보통 인터랙티브 세션 중 사용자의 PYTHONSTARTUP 파일에서 자동으로 실행돼요.

import atexit
import os
import readline

histfile = os.path.join(os.path.expanduser("~"), ".python_history")
try:
    readline.read_history_file(histfile)
    # default history len is -1 (infinite), which may grow unruly
    readline.set_history_length(1000)
except FileNotFoundError:
    pass

atexit.register(readline.write_history_file, histfile)

이 코드는 실제로 Python이 인터랙티브 모드로 실행될 때 자동으로 실행돼요(Readline configuration 참고).

다음 예시는 새 히스토리만 덧붙임으로써 동시 인터랙티브 세션을 지원하면서도 같은 목표를 이뤄요.

import atexit
import os
import readline
histfile = os.path.join(os.path.expanduser("~"), ".python_history")

try:
    readline.read_history_file(histfile)
    h_len = readline.get_current_history_length()
except FileNotFoundError:
    open(histfile, 'wb').close()
    h_len = 0

def save(prev_h_len, histfile):
    new_h_len = readline.get_current_history_length()
    readline.set_history_length(1000)
    readline.append_history_file(new_h_len - prev_h_len, histfile)
atexit.register(save, h_len, histfile)

다음 예시는 code.InteractiveConsole 클래스를 확장해 히스토리 저장/복원을 지원하게 해요.

import atexit
import code
import os
import readline

class HistoryConsole(code.InteractiveConsole):
    def __init__(self, locals=None, filename="<console>",
                 histfile=os.path.expanduser("~/.console-history")):
        code.InteractiveConsole.__init__(self, locals, filename)
        self.init_history(histfile)

    def init_history(self, histfile):
        readline.parse_and_bind("tab: complete")
        if hasattr(readline, "read_history_file"):
            try:
                readline.read_history_file(histfile)
            except FileNotFoundError:
                pass
            atexit.register(self.save_history, histfile)

    def save_history(self, histfile):
        readline.set_history_length(1000)
        readline.write_history_file(histfile)

참고

버전 3.13에서 도입된 새 REPL은 readline을 지원하지 않아요. 하지만 PYTHON_BASIC_REPL 환경 변수를 설정하면 여전히 readline을 쓸 수 있어요.