PEP 762 – 기본 REPL 교체하기
- Author:
- Pablo Galindo Salgado <pablogsal at python.org>, Łukasz Langa <lukasz at python.org>, Lysandros Nikolaou <lisandrosnik at gmail.com>, Emily Morehouse-Valcarcel <emily at python.org>
- Sponsor:
- Pablo Galindo Salgado
- Status:
- Final
- Type:
- Informational
- Created:
- 11-Oct-2024
- Python-Version:
- 3.13
번역·라이선스 안내
이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain or CC0-1.0, whichever is more permissive 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판
초록
Python의 핵심 강점 중 하나는 대화형 모드입니다. 대화형 모드는 Read-Eval-Print Loop(REPL), Python 콘솔 또는 Python 셸이라고도 합니다. 이 PEP는 이 기능을 Python으로 새로 구현한 내용을 설명합니다. Python 3.13에서 출시된 새 REPL은 여러 줄 편집, 문법 강조, 사용자 정의 명령, 전반적으로 개선된 대화형 경험 등 오늘날 사용자가 기대하는 현대적인 기능을 제공하는 것을 목표로 합니다.
동기
Python 3.12까지 CPython의 대화형 셸은 파서의 특수 모드로서 C로 작성되었습니다. 그래서 유지 보수하고 확장하기가 어려웠습니다. 이 셸은 커서 이동이나 기록 추적 같은 기본 기능을 GNU readline(또는 그에 상응하는 라이브러리)의 존재에 의존했습니다. 이 라이브러리 없이 컴파일한 Python은 기능이 매우 제한된 대화형 모드만 제공했습니다. 반면 readline과 함께 컴파일한 Python은 사용자 입력에 관한 결정과 설정을 외부에 맡겼고, 그 방식 때문에 확장하기가 어려웠습니다.
이러한 복잡성 때문에 기여가 위축되었고 새로운 기능을 구현하기도 어려웠습니다. 그 결과 CPython 대화형 셸은 거의 바뀌지 않았고, 현대적인 대화형 셸에 대한 사용자의 기대에 뒤처지게 되었습니다.
사용자가 현대적인 REPL이라면 으레 갖추고 있으리라 기대하는 여러 기능이 이전 버전에는 없었습니다. 이러한 기능의 예로는 여러 줄 편집과 기록, 사용자 정의 명령, 문법 강조, 편리한 복사 및 붙여넣기 처리 등이 있습니다. 이런 기능이 없다는 점은 CPython을 사용하는 여러 사용자 집단의 사용자 경험에 큰 영향을 미치며, 특히 사용자가 의존성을 직접 관리하지 못하고 원하는 패키지를 설치할 수 없는 환경에서 그 영향이 큽니다. 이런 상황은 언어를 배우는 사용자와 교육자에게 특히 흔합니다.
C 구현으로 이러한 문제를 해결하려면 명령의 AST 매칭 같은 복잡한 우회 방법이 필요하며, 이는 코드베이스에 감당하기 어려울 만큼의 복잡성을 더하게 됩니다.
Python으로 작성한 새 REPL로 이러한 한계를 해결하는 동시에, CPython의 대화형 경험을 현대적인 기대와 기능 수준에 더 가깝게 맞추고 있습니다.
근거
새 REPL을 C가 아닌 Python으로 구현하면서 기여자의 진입 장벽이 크게 낮아졌습니다. 이 변화로 REPL을 테스트하고 검증하고 수정하기가 쉬워졌고, 그 결과 커뮤니티 참여가 늘고 기능 개발 속도가 빨라졌습니다. 코드베이스의 접근성이 좋아졌으므로 REPL이 더 빠르게 발전하고 사용자 요구에 더 잘 대응하게 될 것으로 기대합니다.
Python REPL을 처음부터 새로 작성하는 대신, PyREPL을 기반으로 새 REPL을 구현하기로 결정했습니다. 이 결정에는 몇 가지 핵심 요인이 작용했습니다. 무엇보다도, 여러 운영 체제와 터미널 에뮬레이터에서 일관되게 동작하는 터미널 애플리케이션을 개발하는 일은 복잡한 작업입니다. PyPy 프로젝트에서 실전 검증을 거친 PyREPL을 채택하면 처음부터 시작하지 않고 이미 검증된 기존 코드를 활용할 수 있습니다.
REPL 구현을 위해 PyPy와 코드베이스를 공유하면 두 프로젝트 모두에 이익이 됩니다. 이를 통해 유지보수 노력을 공유하고, 버그 수정과 기능 개선을 더 빠르게 진행하여 CPython과 PyPy 양쪽의 사용자 모두에게 도움이 될 수 있습니다. 이러한 협력은 Python 생태계 전체를 위한 더 견고하고 기능이 풍부한 REPL로 이어질 수 있습니다.
C로 작성된 이전 REPL은 탐색, 히스토리 보존 및 불러오기, 자동 완성, 설정 가능한 키보드 동작 같은 기능을 제공하려고 “readline” 또는 “editline” 라이브러리를 백엔드로 사용했습니다. PyREPL은 이 라이브러리들을 사용하지 않으며, 나머지 기능 대부분을 셸의 일부로 직접 구현합니다. 새 아키텍처의 이점이 주로 빠지는 기능(입력 설정 기능)보다 더 큽니다. 이 라이브러리들의 설정 파일(예: inputrc)은 복잡합니다. 또한 PyREPL이 구현할 계획이 없는 기능도 들어 있으므로, 새 셸에서 이 파일들을 투명하게 지원하는 것은 현실적으로 불가능합니다. PyREPL에서 “readline”이나 “editline”을 사용하면 여러 줄 편집 처리와 다중 플랫폼 지원 때문에 감당할 수 없을 만큼 복잡해집니다.
이 때문에 기존 readline/editline 설정은 PyREPL과 호환되지 않습니다. 그러나 향상된 기능과 개선된 확장성을 고려하면 전체적으로 이득이라고 생각합니다. 사용자 정의 워크플로에 대한 지속적인 지원에 관한 논의는 “하위 호환성”을 참조하십시오.
이전 REPL에서는 사용자 정의 명령을 제대로 구현하기가 어려웠는데, 사용자 정의 명령은 대화형 셸에서 매우 흔한 기능입니다. 예를 들어 exit 명령은 전역 네임스페이스에 주입된 사용자 정의 객체의 메서드 호출로 구현되었습니다. 그래서 사용자가 exit만 입력하면 인터프리터는 올바른 사용법이라며 exit()를 안내했고, 이처럼 직관적이지 않은 동작이 사용자를 자주 혼란스럽게 했습니다.
명세
PyREPL은 _pyrepl이라는 새로운 비공개 Python 모듈로 구현되며, 현재의 C 구현과 함께 존재합니다. 첫 구현에서는 다음과 같은 주요 기능을 도입합니다:
- 여러 줄 히스토리와 편집: 사용자는 여러 줄에 걸친 명령 히스토리를 탐색하고 편집할 수 있으므로, 복잡한 코드 블록을 다듬고 재사용하기가 더 쉬워집니다.
여러 줄 블록을 편집할 때는 공백 네 칸으로 자동 들여쓰기를 하며, 이는 PEP 8 권고와 일치합니다. 콜론으로 끝나는 줄이 나오면, 들여쓰기가 들어간 첫 번째 줄에서 추론한 들여쓰기 패턴에 따라 다음 줄을 자동으로 들여씁니다. 줄은 공백 네 칸으로 들여쓰며, 탭은 공백으로 변환됩니다.
사용자는 up 및 down 화살표로 명령 히스토리에 접근할 수 있습니다. 여러 줄로 된 항목 안에서는 화살표 키가 블록 안을 한 줄씩 이동한 뒤에 다음 히스토리 항목으로 넘어갑니다. down 화살표는 반대 방향으로 동작하여, 오래된 항목에서 가장 최근 항목 쪽으로 이동합니다.
히스토리는 사용자가 지정한 부분 문자열로 정방향(Ctrl+S 사용) 및 역방향(Ctrl+R 사용)으로 검색할 수 있습니다. 셸 줄에 접두사를 입력한 뒤 PageUp 및 PageDown 키를 사용하여 접두사로 검색할 수도 있습니다.
- 복사 및 붙여넣기: 브래킷 붙여넣기(bracketed paste)를 지원하는 터미널 에뮬레이터에서는 PyREPL이 이 기능을 감지하여 사용합니다. 이 기능을 사용하면 코드 블록을 투명하게 붙여넣을 수 있으며, 코드가 즉시 실행되거나 자동 들여쓰기가 잘못 적용되지 않습니다.
이 모드를 지원하지 않는 터미널 에뮬레이터를 위해 전용 붙여넣기 모드가 구현되어 있습니다. 이 모드에서는 여러 줄 코드 조각을 쉽게 삽입할 수 있으며, 코드가 즉시 실행되거나 들여쓰기 문제가 생기지 않습니다.
사용자는 F3 키를 눌러 수동 붙여넣기 모드에 들어갑니다. 프롬프트가
>>>에서(paste)로 바뀌며, 이 상태에서 사용자는 클립보드의 내용을 붙여넣거나 원하는 대로 직접 입력할 수 있습니다. 내용이 준비되면 F3을 눌러 붙여넣기 모드를 빠져나옵니다. 그런 다음 Enter를 누르면 블록이 실행됩니다.붙여넣기 모드를 사용하면 한 번의 입력으로 여러 명령을 입력할 수 있어, 다른 곳의 코드를 붙여넣을 때 도움이 됩니다.
앞에 붙는 명령 프롬프트와 명령의 출력 없이 코드 블록을 복사하려면 F2 키를 눌러 히스토리 보기로 들어가면 됩니다. 이 모드는 페이저를 사용하여 실행한 명령의 히스토리를 프롬프트와 출력 없이 보여 줍니다.
- 도움말은 F1로 볼 수 있습니다.
표준 Help 모듈은 사용자 정의 명령
help(아래 참조)나 F1 키를 통해 사용할 수 있습니다. 도움말 모드로 들어가려면 F1 키를 누르십시오. 사용을 마치면 F1 키를 누르거나 표준 명령(q,quit또는exit)을 입력하여 빠져나오십시오.대화형 도움말을 탐색하는 동안에는 명령 기록이 유지되지 않습니다.
- 사용자 정의 명령: REPL에서는
exit같은 사용자 정의 명령을 더 자연스럽고 사용자 친화적인 방식으로 구현할 수 있습니다. 따라서 현재처럼 함수 호출로 우회할 필요가 없습니다.초기 사용자 정의 명령 목록은 다음과 같습니다:
exitquitcopyrighthelpclear
도달 가능한 스코프의 변수와 이름이 충돌하지 않는 한 명령을 사용할 수 있습니다. 예를 들어
exit = 1을 대입하면 그 변수가 PyREPL 명령보다 우선합니다. 이 경우del exit로 충돌을 없애면 명령이 다시 함수로서 동작합니다. - 색상: 이제 프롬프트뿐 아니라 예외 트레이스백 같은 출력의 일부 요소에도 색상이 표시됩니다. 색상은 표준
NO_COLOR환경 변수로 끌 수 있고, 표준FORCE_COLOR환경 변수로 강제로 켤 수 있습니다. Python 전용 환경 변수인PYTHON_COLORS도 사용할 수 있습니다. Python 3.13의 초기 구현에서는 색상 테마를 사용자 정의할 수 없습니다.
이러한 기능은 대화형 Python 경험을 크게 향상하며, 현대적인 개발 환경과 사용자의 기대에 더 부합하게 만듭니다. 이 구현은 Python으로 작성되었으며, 그에 따라 여러 가지 이점이 있습니다:
- 더 쉬운 테스트와 검증: Python 코드의 테스트는 C 코드보다 작성하기가 훨씬 간단하고 수월하므로, 기존 기능과 오래된 기능 전체를 더 폭넓게 테스트할 수 있습니다.
- 더 낮은 기여 장벽: Python은 C보다 접근하기 쉬워서 커뮤니티의 기여가 늘어나고 있으며, 그 결과 기능 개발과 버그 수정이 더 빨라지고 있습니다.
- 유연성: Python 구현은 확장하고 수정하기가 더 쉬우므로, 코어 개발자와 기여자 모두가 새로운 기능과 개선 사항을 더 빠르게 개발할 수 있습니다.
하위 호환성
PyREPL 구현은 기존 Python 코드와의 완전한 하위 호환성을 유지하도록 설계되었습니다. 기존의 기본 REPL을 대체 수단으로 보존하므로, 사용자 정의 워크플로에 필요하면 언제든지 이를 사용할 수 있습니다. 환경적 제약이나 다른 문제로 새 REPL을 사용할 수 없는 경우에도 기존 REPL이 사용됩니다. 사용자는 환경 변수 PYTHON_BASIC_REPL의 값을 1로 설정하여 기존의 기본 REPL을 명시적으로 선택할 수 있습니다. 따라서 사용자는 원하거나 새 구현에서 문제가 생기면 익숙한 인터페이스와 기능을 계속 사용할 수 있습니다.
PyREPL을 도입해도 기존 기능은 하나도 제거되지 않는다는 점을 강조해 둡니다. 기존 기본 REPL의 기능 중 PyREPL에서 사용할 수 없는 기능은 모두 기존 기본 REPL에 보존되고 유지됩니다. 사용자는 이 REPL을 대체 수단으로 사용할 수 있습니다.
특히 inputrc 또는 editrc 파일의 사용자 정의 입력 설정을 계속 사용하려는 사용자는 기존의 기본 REPL을 계속 사용할 수 있습니다.
저자들은 PyREPL의 기능이 기존의 기본 REPL로 이식될 것으로 예상하지 않습니다. 마찬가지로 PyREPL에서 inputrc와 editrc 지원은 명시적으로 계획하지 않습니다. 이 설정 파일들은 “readline” 및 “editline” 라이브러리가 제공하고 해석하며, 그 기능 범위는 PyREPL이 목표로 하는 기능과 일치하지 않습니다.
원활한 전환을 돕기 위해 PyREPL과 기존의 기본 REPL 사이를 전환하는 방법에 대한 명확한 문서가 제공됩니다.
이 접근 방식은 새 REPL로 상당한 개선을 도입하면서도, 현재 구현에 의존하는 사용자에게 즉각적인 변경을 강요하지 않도록 보장합니다. 대체 메커니즘과 사용자 선택 옵션은 기존의 모든 기능을 유지하면서 새 REPL을 점진적으로 도입할 수 있게 하는 안전망을 제공합니다.
보안 영향
이 제안으로 인한 보안 영향은 없습니다.
교육 방법
PyREPL의 도입에는 문서와 튜토리얼이 함께 제공됩니다. 교육에서 중점을 둘 주요 영역은 다음과 같습니다.
- 여러 줄 편집, 붙여넣기 모드 및 기타 새로운 기능의 사용법에 대한 자세한 설명.
- 사용자 정의 명령(기존 명령과 새 명령).
- 이전의 readline/editline 기반 설정과의 차이점을 포함하여, 새 REPL로 전환하는 방법.
기각된 아이디어
여러 대안적 접근 방식이 검토되었으나 최종적으로 기각되었습니다.
- 현재의 C 구현 확장: 이 방법은 하위 호환성을 최대한 유지할 수 있지만, 지나치게 복잡하고 앞서 설명한 근본적인 한계를 해결하지 못할 것으로 판단되었습니다.
- 새 REPL을 처음부터 개발: 이 접근 방식은 크로스 플랫폼 터미널 애플리케이션을 만드는 일의 복잡성과, 이미 검증된 기존 코드를 활용하려는 바람 때문에 기각되었습니다.
- 다른 기존 REPL 구현 사용: 저자들은 IPython, bpython, ptpython, xonsh와 같은 여러 대안을 살펴보았습니다. 위의 프로젝트들은 모두 인상적이지만, 결국 성숙도, 기능 구성, 추가 의존성이 없다는 점을 종합적으로 고려하여 PyREPL이 선택되었습니다. 또 다른 핵심 요인은 PyPy 구현과의 일관성이었습니다.
감사의 글
이 PEP의 초안에 피드백을 제공해 주신 Diego Russo 님께 감사드립니다.
Copyright
This document is placed in the public domain or under the CC0-1.0-Universal license, whichever is more permissive.