Python 실행의 구성 요소

Python 코드가 실행 가능한 상태에 도달하는 과정에 필요한 요소들입니다. 인터프리터가 실제로 파이썬 코드를 실행하려면 세 가지 요소가 필요합니다.

  • Module : 실행할 모듈
  • State : 변수 등을 저장할 상태
  • Config : 활성화된 옵션 등의 구성

Config/State?

Config는 크게 세 부분으로 나뉘어 집니다.

  1. PyPreConfig Dict 초기화 구성
    이 설정은 사용자 환경 또는 운영 체제와 관련된 구성입니다. UTF-8 모드, 메모리 할당자, LC_CTYPE과 같은 요소들이 설정될 수 있습니다.

  2. PyConfig 런타임 구성
    런타임에 필요한 값들을 구성하는 단계입니다. 우리가 흔히 알고 있는 Flag 들이 해당되기도 하고, 디버그나 최적화 같은 실행 모드 플래그들이 해당됩니다.

  • ex) python -m 'print("Hello World")'
  1. Cpython 인터프리터에 컴파일된 구성 (빌드 구성)
    빌드 과정에서 정의되는 구성으로 pyconfig.h 에서 정의됩니다. 대표적인 예시로 디버거, instrumentation 라이브러리, 메모리 할당자는 모두 컴파일이 결정되는 옵션입니다.

입력시 모듈 만들기

코드를 실행하려면 먼저 입력을 모듈로 컴파일 해야 합니다.

입력 방식에는 여러 가지가 있고, 이를 각각 컴파일하기 위해 cPython 코드의 많은 부분을 사용하고 있습니다.

  • 로컬 파일과 패키지
  • 메모리 파이프나 stdin 과 같은 I/O 스트림
  • 문자열

Python 문자열 실행하기

실행시 Python 문자열을 같이 넘길 수 있는데, 이 때 문자열을 파이썬 모듈로 컴파일하고 실행됩니다. 이 때 Python은 __main__ 진입점이 필요하기 때문에 임의로 진입점을 추가합니다.

# -c Command 
python -c "print('Hello World!')"

Python 모듈 실행하기

-m 플래그는 모듈 패키지의 진입점(__main__)을 실행하게 됩니다. 내부적으로는 runpy를 통해 실행시키는 것과 동일합니다.

runpy 또한 어떻게 보면 모듈일텐데, 이는 컴파일되는 과정에서 암묵적으로 실행되기 때문에 가능한 구조입니다.

# -m Module
python -m pytest 
 
# Same with..
python -m runpy pytest

runpy 모듈은 순수한 모듈로써 모듈을 찾아 실행하는 역할을 수행합니다.

  1. 제공된 이름을 __import__() 로 임포트합니다.
  2. __name____main__ 에 설정합니다.
  3. __main__ 공간에서 모듈을 실행합니다.

표준 입력 또는 스크립트 파일 실행

python을 실행할 때 첫 번째 인자가 파일명이라면, PyRun_SimpleFileExFlags() 를 통해 파일을 실행합니다. PyRun_SimpleFileExFlags() 내부적으로는 다음과 같이 라우팅 역할을 수행하는데요.

  1. pyc 파일이면 run_pyc_file()를 호출
  2. .py 파일 경로이면, PyRun_FileExFlags()를 호출
  3. <command> | python 처럼 경로가 stdin 이여도, 같은 파일로 취급하여 PyRun_FileExFlags()를 호출합니다.
python test.py 

PyConfig Flags

Python은 실행시에 여러가지 flag 를 주고 실행할 수 있다.

Runtime 플래그 확인하기

./python -X dev -q 

Token Parsing 정보 조회

python -e {python_file}
  • Python은 기본적으로 utf-8 인코딩을 붙여준다
    • 0,0-0,0 ENCODING 'utf-8'
  • Python은 기본적으로 파일의 끝에 newline 을 붙여준다.