codeop — 파이썬 코드 컴파일
codeop — 파이썬 코드 컴파일
(소스: Lib/codeop.py)
codeop 모듈은 파이썬의 read-eval-print 루프(REPL)를 에뮬레이션할 수 있는 유틸리티를 제공해요.
code 모듈이 바로 그렇게 하고 있어요.
그래서 보통 이 모듈을 직접 쓰고 싶진 않을 거예요.
프로그램에 그런 루프를 포함하고 싶다면 code 모듈을 쓰는 게 더 좋아요.
이 작업에는 두 부분이 있어요.
하나는 입력 줄이 파이썬 문장을 완성하는지 판단하는 것, 즉 다음에 '>>>'(더 입력 필요 없음)를 출력할지 '...'(계속 입력 필요)를 출력할지를 아는 것이에요.
다른 하나는 사용자가 입력한 future 문을 기억해서 이후 입력을 그 효과가 적용된 상태로 컴파일하는 것이에요.
codeop 모듈은 각각을 하는 방법과 둘 다 하는 방법을 제공해요.
본문
함수
codeop.compile_command(source, filename='<input>', symbol='single') 함수가 전자를 처리해요.
source(파이썬 코드 문자열)를 컴파일해 보려고 하고, 유효한 파이썬 코드면 코드 객체를 반환해요.
이때 코드 객체의 filename 속성은 filename(기본 '')이 돼요.
source가 유효한 파이썬 코드는 아니지만 유효한 파이썬 코드의 접두사라면 — 즉 더 입력하면 완성될 수 있는 상태라면 — None을 반환해요.
source에 문제가 있으면 예외를 발생시켜요.
잘못된 파이썬 문법이면 SyntaxError, 잘못된 리터럴이면 OverflowError 또는 ValueError예요.
symbol 인자는 source를 문장('single', 기본), 문장 시퀀스('exec'), 또는 표현식('eval')으로 컴파일할지를 결정해요.
다른 값을 주면 ValueError가 발생해요.
참고로, 파서가 source 끝에 도달하기 전에 성공적으로 파싱을 멈추는 경우(드물지만)엔 끝부분 기호가 오류 대신 무시될 수 있어요.
클래스
class codeop.Compile 클래스의 인스턴스는 내장 함수 compile()과 시그니처가 동일한 __call__() 메서드를 가져요.
차이점은, 인스턴스가 __future__ 문을 포함한 프로그램 텍스트를 컴파일하면 그 문을 '기억' 하고, 이후 모든 프로그램 텍스트를 그 문이 적용된 상태로 컴파일한다는 것이에요.
즉 future import의 효과가 세션 동안 지속되도록 해 줘요.
class codeop.CommandCompiler 클래스는 compile_command()와 시그니처가 동일한 __call__() 메서드를 가져요.
Compile과 마찬가지로, 인스턴스가 __future__ 문을 포함한 프로그램 텍스트를 컴파일하면 그 문을 기억하고 이후 모든 입력을 그 문이 적용된 상태로 컴파일해요.
이 두 클래스와 compile_command() 함수는 REPL 같은 대화형 환경에서 "이 입력을 어떻게 처리할지"와 "이후 입력에 어떤 future 설정을 적용할지"를 관리하는 데 핵심적인 역할을 해요.