Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python 개선 제안 한국어 번역

PEP 587 – Python 초기화 구성

Author:
Victor Stinner <vstinner at python.org>, Alyssa Coghlan <ncoghlan at gmail.com>
BDFL-Delegate:
Thomas Wouters <thomas at python.org>
Discussions-To:
Python-Dev list
Status:
Final
Type:
Standards Track
Created:
27-Mar-2019
Python-Version:
3.8

Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

전체 구성을 더 세밀하게 제어하고 오류를 더 잘 보고할 수 있도록 Python 초기화를 구성하는 새로운 C API를 추가합니다.

구성을 읽은 다음, 구성이 적용되기 전에 계산된 일부 매개변수를 재정의할 수 있게 됩니다. 또한 Python이 모듈 검색 경로(sys.path)를 계산하는 방식을 완전히 재정의할 수도 있게 됩니다.

새로운 Isolated Configuration은 Python을 시스템으로부터 격리하기 위한 합리적인 기본값을 제공합니다. 예를 들어, Python을 애플리케이션에 내장하는 경우입니다. 이제 환경을 사용하는 것은 옵트아웃(opt-out) 옵션이 아니라 옵트인(opt-in) 옵션입니다. 예를 들어, 환경 변수, 명령줄 인자, 전역 구성 변수는 기본적으로 무시됩니다.

새로운 Py_RunMain() 함수를 사용하면 일반 Python처럼 동작하는 맞춤형 Python을 더 쉽게 빌드할 수 있습니다. 게다가 Python Configuration을 사용하면, 이제 PyConfig.argv 인자는 일반 Python이 명령줄 인자를 파싱하는 것과 같은 방식으로 파싱되며, PyConfig.xoptions는 -X opt 명령줄 옵션으로 처리됩니다.

이 PEP는 PEP 432 개발 및 리팩터링 작업에서 이제 공개해도 될 만큼 충분히 안정적이라고 여겨지는 API 설계의 일부를 추출한 것입니다(이를 통해 서드파티 내장 애플리케이션이 네이티브 CPython CLI가 현재 사용하는 것과 동일한 구성 API에 접근할 수 있습니다).

근거

Python은 매우 다양하게 구성할 수 있지만, 그 구성은 체계적인 설계 없이 유기적으로 발전해 왔습니다. 초기화 설정은 코드 곳곳에 흩어져 있으며 서로 다른 방식으로 설정됩니다: 전역 설정 변수(예: Py_IsolatedFlag), 환경 변수(예: PYTHONPATH), 명령줄 인자(예: -b), 설정 파일(예: pyvenv.cfg), 함수 호출(예: Py_SetProgramName()). Python을 구성하는 간단하고 신뢰할 수 있는 방법이 필요합니다.

일부 구성 매개변수는 C API에서 접근할 수 없거나, 접근하기가 쉽지 않습니다. 예를 들어, sys.executable의 기본값을 재정의하는 API가 없습니다.

PYTHONPATH 같은 일부 옵션은 환경 변수로만 설정할 수 있는데, 이 환경 변수를 제대로 해제하지 않으면 Python 자식 프로세스에 부작용이 생깁니다.

일부 옵션은 다른 옵션에 의존하기도 합니다: Priority and Rules를 참조하십시오. Python 3.7 API는 전체 구성에 대한 일관된 뷰를 제공하지 않습니다.

Python 3.7 초기화 C API는 wchar_t* 문자열을 입력으로 받지만, Python 파일 시스템 인코딩은 초기화 중에 설정되므로 문자 깨짐(mojibake)이 발생할 수 있습니다.

Py_Initialize() 같은 Python 3.7 API는 메모리 할당에 실패하면 프로세스를 중단하는데, 이는 Python을 내장한 경우에 불편합니다. 게다가 Py_Main()은 종료 코드를 반환하는 대신 프로세스를 직접 종료할 수 있었습니다. 제안된 새로운 API는 오류나 종료 코드를 호출자에게 보고하며, 호출자가 이를 어떻게 처리할지 결정할 수 있습니다.

Python 3.6에서는 PEP 540(UTF-8 모드)과 새로운 -X dev를 올바르게 구현하는 것이 거의 불가능했습니다. 부작용 없이 구성을 구조체로 읽어 들이도록 Python 3.7에서, 이어서 Python 3.8에서 코드 베이스를 대대적으로 재작업했습니다. 인코딩이 변경되면 구성을 지우고(메모리 해제) 구성을 다시 읽을 수 있게 됩니다. 이는 -X utf8 명령줄 옵션으로 인코딩을 변경하는 UTF-8 모드를 올바르게 구현하는 데 필요합니다. 내부적으로 바이트 argv 문자열은 파일 시스템 인코딩으로 디코딩됩니다. -X dev는 메모리 할당자를 변경하지만(PYTHONMALLOC=debug처럼 동작합니다), 명령줄 인자를 파싱하는 동안에는 메모리 할당을 변경할 수 없었습니다. 새로운 내부 구현 설계 덕분에 -X utf8과 -X dev를 올바르게 구현할 수 있었을 뿐만 아니라, 특히 이와 같은 코너 케이스에서 Python의 동작을 훨씬 더 쉽게 변경할 수 있고 구성이 일관되게 유지되도록 보장할 수 있습니다: Priority and Rules를 참조하십시오.

이 PEP는 전체 설계인 PEP 432의 부분 구현입니다. PEP 432의 구현을 마무리하기 위해 나중에 PyConfig 구조체에 새 필드를 추가할 수 있습니다(예: Python 객체를 사용하여 Python을 구성한 뒤 전체 초기화를 마무리할 수 있게 하는 새로운 부분 초기화 API를 추가하는 방식). 그러나 네이티브 CPython CLI조차 그런 방식으로 동작하지 않으므로 이러한 기능은 이 PEP에서 제외합니다. 이 PEP의 공개 API 제안은 네이티브 CPython CLI에서 사용하도록 이미 구현되어 비공개 API로 채택된 기능으로 한정됩니다.

Python 초기화 C API

이 PEP는 다음과 같은 새 구조체와 함수를 추가할 것을 제안합니다.

새 구조체:

  • PyConfig
  • PyPreConfig
  • PyStatus
  • PyWideStringList

새 함수:

  • PyConfig_Clear(config)
  • PyConfig_InitIsolatedConfig()
  • PyConfig_InitPythonConfig()
  • PyConfig_Read(config)
  • PyConfig_SetArgv(config, argc, argv)
  • PyConfig_SetBytesArgv(config, argc, argv)
  • PyConfig_SetBytesString(config, config_str, str)
  • PyConfig_SetString(config, config_str, str)
  • PyPreConfig_InitIsolatedConfig(preconfig)
  • PyPreConfig_InitPythonConfig(preconfig)
  • PyStatus_Error(err_msg)
  • PyStatus_Exception(status)
  • PyStatus_Exit(exitcode)
  • PyStatus_IsError(status)
  • PyStatus_IsExit(status)
  • PyStatus_NoMemory()
  • PyStatus_Ok()
  • PyWideStringList_Append(list, item)
  • PyWideStringList_Insert(list, index, item)
  • Py_BytesMain(argc, argv)
  • Py_ExitStatusException(status)
  • Py_InitializeFromConfig(config)
  • Py_PreInitialize(preconfig)
  • Py_PreInitializeFromArgs(preconfig, argc, argv)
  • Py_PreInitializeFromBytesArgs(preconfig, argc, argv)
  • Py_RunMain()

이 PEP는 또한 이 내부 구조체들에 _PyRuntimeState.preconfig (PyPreConfig 타입) 필드와 PyInterpreterState.config (PyConfig 타입) 필드를 추가합니다. PyInterpreterState.config는 전역 구성 변수와 기타 비공개 변수를 대체하는 새로운 기준 구성이 됩니다.

PyWideStringList

PyWideStringList는 wchar_t* 문자열의 리스트입니다.

PyWideStringList 구조체 필드:

  • length (Py_ssize_t)
  • items (wchar_t**)

메서드:

  • PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item): list에 item을 추가합니다.
  • PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item): list의 index 위치에 item을 삽입합니다. index가 list의 길이보다 크면 item을 list에 그냥 추가합니다.

length가 0이 아니면 items는 NULL이 아니어야 하며 모든 문자열도 NULL이 아니어야 합니다.

PyStatus

PyStatus는 초기화 함수의 상태(성공, 오류 또는 종료)를 저장하는 구조체입니다. 오류인 경우에는 오류를 생성한 C 함수의 이름을 저장할 수 있습니다.

예시:

PyStatus alloc(void **ptr, size_t size)
{
    *ptr = PyMem_RawMalloc(size);
    if (*ptr == NULL) {
        return PyStatus_NoMemory();
    }
    return PyStatus_Ok();
}

int main(int argc, char **argv)
{
    void *ptr;
    PyStatus status = alloc(&ptr, 16);
    if (PyStatus_Exception(status)) {
        Py_ExitStatusException(status);
    }
    PyMem_Free(ptr);
    return 0;
}

PyStatus 필드:

  • exitcode (int): exit()에 전달되는 인자입니다.
  • err_msg (const char*): 오류 메시지입니다.
  • func (const char *): 오류를 생성한 함수의 이름이며, NULL일 수 있습니다.
  • 비공개 _type 필드: 내부 용도로만 사용됩니다.

상태를 생성하는 함수:

  • PyStatus_Ok(): 성공입니다.
  • PyStatus_Error(err_msg): 메시지가 포함된 초기화 오류입니다.
  • PyStatus_NoMemory(): 메모리 할당 실패(메모리 부족)입니다.
  • PyStatus_Exit(exitcode): 지정된 종료 코드로 Python을 종료합니다.

상태를 처리하는 함수:

  • PyStatus_Exception(status): 결과가 오류입니까, 아니면 종료입니까? 참이면 예외를 처리해야 합니다. 예를 들어 Py_ExitStatusException(status)를 호출하여 처리합니다.
  • PyStatus_IsError(status): 결과가 오류입니까?
  • PyStatus_IsExit(status): 결과가 종료입니까?
  • Py_ExitStatusException(status): status가 종료이면 exit(exitcode)를 호출합니다. status가 오류이면 오류 메시지를 출력하고 0이 아닌 종료 코드로 종료합니다. PyStatus_Exception(status)가 참일 때만 호출해야 합니다.

Note

내부적으로 Python은 PyStatus.func를 설정하는 매크로를 사용하지만, 상태를 생성하는 함수는 func를 NULL로 설정합니다.

PyPreConfig를 사용한 사전 초기화

PyPreConfig 구조체는 Python을 사전 초기화하는 데 사용됩니다:

  • Python 메모리 할당자를 설정합니다
  • LC_CTYPE 로케일 구성
  • UTF-8 모드 설정

사전 초기화를 사용하여 UTF-8 모드를 활성화하는 예제:

PyStatus status;
PyPreConfig preconfig;

PyPreConfig_InitPythonConfig(&preconfig);

preconfig.utf8_mode = 1;

status = Py_PreInitialize(&preconfig);
if (PyStatus_Exception(status)) {
    Py_ExitStatusException(status);
}

/* at this point, Python will speak UTF-8 */

Py_Initialize();
/* ... use Python API here ... */
Py_Finalize();

사전 구성을 초기화하는 함수:

  • PyStatus PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)
  • PyStatus PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)

Python을 사전 초기화하는 함수:

  • PyStatus Py_PreInitialize(const PyPreConfig *preconfig)
  • PyStatus Py_PreInitializeFromBytesArgs(const PyPreConfig *preconfig, int argc, char * const *argv)
  • PyStatus Py_PreInitializeFromArgs(const PyPreConfig *preconfig, int argc, wchar_t * const * argv)

호출자는 PyStatus_Exception()과 Py_ExitStatusException()을 사용하여 예외(오류 또는 종료)를 처리할 책임이 있습니다.

Python Configuration (PyPreConfig_InitPythonConfig())의 경우, 파이썬을 명령줄 인자로 초기화한다면 파이썬을 사전 초기화할 때도 그 명령줄 인자를 전달해야 합니다. 명령줄 인자는 인코딩과 같은 사전 구성에 영향을 주기 때문입니다. 예를 들어, -X utf8 명령줄 옵션은 UTF-8 모드를 활성화합니다.

PyPreConfig 필드:

  • allocator (int): 메모리 할당자의 이름입니다(예: PYMEM_ALLOCATOR_MALLOC). 유효한 값:
    • PYMEM_ALLOCATOR_NOT_SET (0): 메모리 할당자를 변경하지 않습니다(기본값 사용).
    • PYMEM_ALLOCATOR_DEFAULT (1): 기본 메모리 할당자
    • PYMEM_ALLOCATOR_DEBUG (2): 디버그 훅이 있는 기본 메모리 할당자
    • PYMEM_ALLOCATOR_MALLOC (3): malloc() 사용을 강제합니다.
    • PYMEM_ALLOCATOR_MALLOC_DEBUG (4): 디버그 훅과 함께 malloc() 사용을 강제합니다.
    • PYMEM_ALLOCATOR_PYMALLOC (5): Python “pymalloc” 할당자
    • PYMEM_ALLOCATOR_PYMALLOC_DEBUG (6): 디버그 훅이 있는 Python “pymalloc” 할당자
    • 참고: Python이 --without-pymalloc을 사용하여 설정된 경우 PYMEM_ALLOCATOR_PYMALLOC와 PYMEM_ALLOCATOR_PYMALLOC_DEBUG는 지원되지 않습니다
  • configure_locale (int): LC_CTYPE 로케일을 사용자가 선호하는 로케일로 설정할지 여부입니다. 0이면 coerce_c_locale 및 coerce_c_locale_warn을 0으로 설정합니다.
  • coerce_c_locale (int): 2이면 C 로케일을 강제하고, 1이면 LC_CTYPE 로케일을 읽어 강제할지를 결정합니다.
  • coerce_c_locale_warn (int): 0이 아니면 C 로케일이 강제될 때 경고를 출력합니다.
  • dev_mode (int): PyConfig.dev_mode를 참조하십시오.
  • isolated (int): PyConfig.isolated를 참조하십시오.
  • legacy_windows_fs_encoding (int, Windows 전용): 0이 아니면 UTF-8 모드를 비활성화하고, Python 파일 시스템 인코딩을 mbcs로, 파일 시스템 오류 핸들러를 replace로 설정합니다.
  • parse_argv (int): 0이 아니면 Py_PreInitializeFromArgs()와 Py_PreInitializeFromBytesArgs()는 일반 Python이 명령줄 인자를 파싱하는 것과 같은 방식으로 argv 인자를 파싱합니다: Command Line Arguments를 참고하십시오.
  • use_environment (int): PyConfig.use_environment를 참조하십시오.
  • utf8_mode (int): 0이 아니면 UTF-8 모드를 활성화합니다.

legacy_windows_fs_encoding 필드는 윈도우에서만 사용할 수 있습니다. 윈도우 전용 코드에는 #ifdef MS_WINDOWS 매크로를 사용할 수 있습니다.

내부 전용인 PyPreConfig 비공개 필드:

  • _config_init (int): PyConfig를 초기화하는 데 사용되는 함수로, 사전 초기화에 사용됩니다.

사용자 정의 메모리 할당자를 설치하기 위해 Py_PreInitialize() 이후, Py_InitializeFromConfig() 이전에 PyMem_SetAllocator()를 호출할 수 있습니다. allocator가 PYMEM_ALLOCATOR_NOT_SET (기본값)으로 설정된 경우에는 Py_PreInitialize() 이전에 호출할 수 있습니다.

PyMem_RawMalloc() 같은 Python 메모리 할당 함수는 Python 사전 초기화 전에 사용해서는 안 되지만, malloc()과 free()를 직접 호출하는 것은 항상 안전합니다. Py_DecodeLocale()은 사전 초기화 전에 호출해서는 안 됩니다.

PyConfig를 사용한 초기화

PyConfig 구조체는 Python 설정을 위한 대부분의 매개변수를 담고 있습니다.

프로그램 이름을 설정하는 예:

void init_python(void)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    /* Set the program name. Implicitly preinitialize Python. */
    status = PyConfig_SetString(&config, &config.program_name,
                                L"/path/to/my_program");
    if (PyStatus_Exception(status)) {
        goto fail;
    }

    status = Py_InitializeFromConfig(&config);
    if (PyStatus_Exception(status)) {
        goto fail;
    }
    PyConfig_Clear(&config);
    return;

fail:
    PyConfig_Clear(&config);
    Py_ExitStatusException(status);
}

PyConfig 메서드:

  • void PyConfig_InitPythonConfig(PyConfig *config) Python Configuration으로 구성을 초기화합니다.
  • void PyConfig_InitIsolatedConfig(PyConfig *config): Isolated Configuration으로 구성을 초기화합니다.
  • PyStatus PyConfig_SetString(PyConfig *config, wchar_t * const *config_str, const wchar_t *str): 와이드 문자열 str을 *config_str에 복사합니다. 필요하면 Python을 사전 초기화합니다.
  • PyStatus PyConfig_SetBytesString(PyConfig *config, wchar_t * const *config_str, const char *str): Py_DecodeLocale()을 사용하여 str을 디코딩하고 그 결과를 *config_str에 설정합니다. 필요하면 Python을 사전 초기화합니다.
  • PyStatus PyConfig_SetArgv(PyConfig *config, int argc, wchar_t * const *argv): 와이드 문자열로 명령줄 인자를 설정합니다. 필요하면 Python을 사전 초기화합니다.
  • PyStatus PyConfig_SetBytesArgv(PyConfig *config, int argc, char * const *argv): 명령줄 인자를 설정합니다. Py_DecodeLocale()를 사용하여 바이트열을 디코딩합니다. 필요하면 Python을 사전 초기화합니다.
  • PyStatus PyConfig_Read(PyConfig *config): 모든 Python 설정을 읽습니다. 이미 초기화된 필드는 변경하지 않고 그대로 둡니다. 필요하면 Python을 사전 초기화합니다.
  • void PyConfig_Clear(PyConfig *config): 구성 메모리를 해제합니다.

대부분의 PyConfig 메서드는 필요하면 Python을 사전 초기화합니다. 이 경우 Python 사전 초기화 설정은 PyConfig를 기반으로 합니다. PyPreConfig와 공통인 구성 필드를 조정하려면 PyConfig 메서드를 호출하기 전에 설정해야 합니다:

  • dev_mode
  • isolated
  • parse_argv
  • use_environment

또한 PyConfig_SetArgv()나 PyConfig_SetBytesArgv()를 사용하는 경우, 사전 초기화 구성이 명령줄 인자에 의존하므로(parse_argv가 0이 아닐 때) 이 메서드를 다른 메서드보다 먼저 호출해야 합니다.

Python을 초기화하는 함수:

  • PyStatus Py_InitializeFromConfig(const PyConfig *config): config 설정으로 Python을 초기화합니다.

이러한 메서드와 함수의 호출자는 PyStatus_Exception()과 Py_ExitStatusException()을 사용하여 예외(오류 또는 종료)를 처리할 책임이 있습니다.

PyConfig 필드:

  • argv (PyWideStringList): 명령줄 인자 sys.argv입니다. 일반 Python이 Python 명령줄 인자를 파싱하는 것과 같은 방식으로 argv를 파싱하려면 parse_argv를 참고하십시오. argv가 비어 있으면 sys.argv가 항상 존재하고 절대 비어 있지 않도록 빈 문자열이 추가됩니다.
  • base_exec_prefix (wchar_t*): sys.base_exec_prefix입니다.
  • base_prefix (wchar_t*): sys.base_prefix입니다.
  • buffered_stdio (int): 0이면 버퍼링하지 않는 모드를 활성화하여 stdout과 stderr 스트림을 버퍼링하지 않게 합니다.
  • bytes_warning (int): 1이면 bytes나 bytearray를 str과 비교하거나 bytes를 int와 비교할 때 경고를 발생시킵니다. 2 이상이면 BytesWarning 예외를 발생시킵니다.
  • check_hash_pycs_mode (wchar_t*): --check-hash-based-pycs 명령줄 옵션 값입니다(PEP 552 참조). 유효한 값은 always, never, default입니다. 기본값은 default입니다.
  • configure_c_stdio (int): 0이 아니면 C 표준 스트림(stdio, stdout, stdout)을 구성합니다. 예를 들어 Windows에서는 해당 스트림의 모드를 O_BINARY로 설정합니다.
  • dev_mode (int): 개발 모드입니다.
  • dump_refs (int): 0이 아니면 종료 시 아직 살아 있는 모든 객체를 덤프합니다. Py_REF_DEBUG 매크로가 정의된 특수 Python 빌드가 필요합니다.
  • exec_prefix (wchar_t*): sys.exec_prefix입니다.
  • executable (wchar_t*): sys.executable입니다.
  • faulthandler (int): 0이 아니면 faulthandler.enable()을 호출합니다.
  • filesystem_encoding (wchar_t*): 파일 시스템 인코딩, sys.getfilesystemencoding()입니다.
  • filesystem_errors (wchar_t*): 파일 시스템 인코딩 오류, sys.getfilesystemencodeerrors()입니다.
  • use_hash_seed (int), hash_seed (unsigned long): 무작위화된 해시 함수 시드입니다.
  • home (wchar_t*): Python 홈 디렉터리입니다.
  • import_time (int): 0이 아니면 임포트 시간을 프로파일링합니다.
  • inspect (int): 스크립트나 명령을 실행한 후 대화형 모드로 진입합니다.
  • install_signal_handlers (int): 시그널 핸들러를 설치합니까?
  • interactive (int): 대화형 모드입니다.
  • isolated (int): 0보다 크면 격리 모드를 활성화합니다:
    • sys.path에는 스크립트 디렉터리(argv[0] 또는 현재 디렉터리로부터 계산됨)도, 사용자의 사이트 패키지(site-packages) 디렉터리도 포함되지 않습니다.
    • Python REPL은 readline을 임포트하지 않으며 대화형 프롬프트에서 기본 readline 설정도 활성화하지 않습니다.
    • use_environment와 user_site_directory를 0으로 설정합니다.
  • legacy_windows_stdio (int, Windows 전용): 0이 아니면 sys.stdin, sys.stdout, sys.stderr에 WindowsConsoleIO 대신 io.FileIO를 사용합니다.
  • malloc_stats (int): 0이 아니면 종료 시 pymalloc 메모리 할당자에 대한 통계를 덤프합니다. Python이 --without-pymalloc을 사용하여 빌드된 경우 이 옵션은 무시됩니다.
  • pythonpath_env (wchar_t*): DELIM(보통 : 문자)으로 구분된 문자열 형태의 모듈 검색 경로입니다. 기본적으로 PYTHONPATH 환경 변수 값으로 초기화됩니다.
  • module_search_paths_set (int), module_search_paths (PyWideStringList): sys.path입니다. module_search_paths_set이 0이면 Path Configuration을 계산하는 함수가 module_search_paths를 덮어씁니다.
  • optimization_level (int): 컴파일 최적화 수준입니다:
    • 0: 핍홀 최적화기를 사용합니다(그리고 __debug__가 True로 설정됩니다).
    • 1: 어서션을 제거하고 __debug__를 False로 설정합니다.
    • 2: 독스트링을 제거합니다.
  • parse_argv (int): 0이 아니면 일반 Python 명령줄 인자와 같은 방식으로 argv를 파싱하고, argv에서 Python 인자를 제거합니다: Command Line Arguments를 참고하십시오.
  • parser_debug (int): 0이 아니면 파서 디버깅 출력을 켭니다(전문가 전용이며, 컴파일 옵션에 따라 다릅니다).
  • pathconfig_warnings (int): 0이면 경로 구성을 계산할 때 경고를 억제합니다(Unix 전용이며, Windows는 어떤 경고도 기록하지 않습니다). 그렇지 않으면 경고가 stderr에 기록됩니다.
  • prefix (wchar_t*): sys.prefix입니다.
  • program_name (wchar_t*): 프로그램 이름입니다.
  • pycache_prefix (wchar_t*): .pyc 캐시 접두사입니다.
  • quiet (int): 조용한 모드입니다. 예를 들어, 대화형 모드에서도 저작권 및 버전 메시지를 표시하지 않습니다.
  • run_command (wchar_t*): python3 -c COMMAND 인자입니다.
  • run_filename (wchar_t*): python3 FILENAME 인자입니다.
  • run_module (wchar_t*): python3 -m MODULE 인자입니다.
  • show_alloc_count (int): 종료 시 할당 횟수를 표시합니까? COUNT_ALLOCS 매크로가 정의된 특수 Python 빌드가 필요합니다.
  • show_ref_count (int): 종료 시 전체 참조 횟수를 표시합니까? Python 디버그 빌드가 필요합니다(Py_REF_DEBUG 매크로가 정의되어 있어야 합니다).
  • site_import (int): 시작 시 site 모듈을 임포트합니까?
  • skip_source_first_line (int): 소스의 첫 줄을 건너뜁니까?
  • stdio_encoding (wchar_t*), stdio_errors (wchar_t*): sys.stdin, sys.stdout 및 sys.stderr의 인코딩과 인코딩 에러 처리 방식입니다.
  • tracemalloc (int): 0이 아니면 tracemalloc.start(value)를 호출합니다.
  • user_site_directory (int): 0이 아니면 사용자 사이트 디렉터리를 sys.path에 추가합니다.
  • verbose (int): 0이 아니면 상세 모드를 활성화합니다.
  • warnoptions (PyWideStringList): 경고 필터를 만드는 데 사용하는 warnings 모듈의 옵션입니다.
  • write_bytecode (int): 0이 아니면 .pyc 파일을 기록합니다.
  • xoptions (PyWideStringList): sys._xoptions입니다.

legacy_windows_stdio 필드는 윈도우에서만 사용할 수 있습니다. 윈도우 전용 코드에는 #ifdef MS_WINDOWS 매크로를 사용할 수 있습니다.

parse_argv가 0이 아니면, argv 인자는 일반 Python이 명령줄 인자를 구문 분석하는 것과 같은 방식으로 구문 분석되고, Python 인자는 argv에서 제거됩니다. Command Line Arguments를 참조하십시오.

xoptions 옵션은 다른 옵션을 설정하기 위해 구문 분석됩니다: -X Options를 참조하십시오.

내부 전용인 PyConfig 비공개 필드:

  • _config_init (int): PyConfig를 초기화하는 데 사용되는 함수로, 사전 초기화에 사용됩니다.
  • _install_importlib (int): importlib를 설치합니까?
  • _init_main (int): 0과 같으면 “main” 단계 전에 Python 초기화를 중단합니다(PEP 432 참조).

기본 구성을 수정하고, 구성을 읽은 다음, 일부 매개변수를 재정의하는 더 완전한 예제입니다.:

PyStatus init_python(const char *program_name)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    /* Set the program name before reading the configuration
       (decode byte string from the locale encoding).

       Implicitly preinitialize Python. */
    status = PyConfig_SetBytesString(&config, &config.program_name,
                                  program_name);
    if (PyStatus_Exception(status)) {
        goto done;
    }

    /* Read all configuration at once */
    status = PyConfig_Read(&config);
    if (PyStatus_Exception(status)) {
        goto done;
    }

    /* Append our custom search path to sys.path */
    status = PyWideStringList_Append(&config.module_search_paths,
                                  L"/path/to/more/modules");
    if (PyStatus_Exception(status)) {
        goto done;
    }

    /* Override executable computed by PyConfig_Read() */
    status = PyConfig_SetString(&config, &config.executable,
                                L"/path/to/my_executable");
    if (PyStatus_Exception(status)) {
        goto done;
    }

    status = Py_InitializeFromConfig(&config);

done:
    PyConfig_Clear(&config);
    return status;
}

Note

PyImport_FrozenModules, PyImport_AppendInittab() 및 PyImport_ExtendInittab() 함수는 여전히 유효하며 이전과 같이 계속 동작합니다. 이들은 Python 사전 초기화 이후, Python 초기화 이전에 설정하거나 호출해야 합니다.

격리된 구성

PyPreConfig_InitIsolatedConfig() 및 PyConfig_InitIsolatedConfig() 함수는 Python을 시스템으로부터 격리하는 구성을 만듭니다. 예를 들어, 애플리케이션에 Python을 임베드하는 경우입니다.

이 구성은 전역 구성 변수, 환경 변수, 명령줄 인자를 무시합니다(argv는 구문 분석되지 않습니다). C 표준 스트림(예: stdout)과 LC_CTYPE 로케일은 기본적으로 변경되지 않습니다.

이 설정에서도 설정 파일은 여전히 사용됩니다. 이러한 설정 파일을 무시하고 함수가 기본 경로 설정을 계산하지 않도록 하려면 Path Configuration (“출력 필드”)을 설정하십시오.

Python 구성

PyPreConfig_InitPythonConfig() 및 PyConfig_InitPythonConfig() 함수는 일반 Python처럼 동작하는 사용자 정의 Python을 빌드하기 위한 구성을 만듭니다.

환경 변수와 명령줄 인자는 Python을 구성하는 데 사용되지만, 전역 구성 변수는 무시됩니다.

이 함수는 LC_CTYPE 로케일, PYTHONUTF8 및 PYTHONCOERCECLOCALE 환경 변수에 따라 C 로케일 강제 변환(PEP 538)과 UTF-8 모드(PEP 540)를 활성화합니다.

항상 격리 모드로 실행되는 사용자 정의 Python의 예:

int main(int argc, char **argv)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    config.isolated = 1;

    /* Decode command line arguments.
       Implicitly preinitialize Python (in isolated mode). */
    status = PyConfig_SetBytesArgv(&config, argc, argv);
    if (PyStatus_Exception(status)) {
        goto fail;
    }

    status = Py_InitializeFromConfig(&config);
    if (PyStatus_Exception(status)) {
        goto fail;
    }
    PyConfig_Clear(&config);

    return Py_RunMain();

fail:
    PyConfig_Clear(&config);
    if (PyStatus_IsExit(status)) {
        return status.exitcode;
    }
    /* Display the error message and exit the process with
       non-zero exit code */
    Py_ExitStatusException(status);
}

이 예는 PEP 432에서 논의된 “System Python Executable”의 기본 구현입니다.

경로 구성

PyConfig에는 경로 구성을 위한 여러 필드가 있습니다:

  • 경로 구성 입력 필드:
    • home
    • pythonpath_env
    • pathconfig_warnings
  • 경로 구성 출력 필드:
    • exec_prefix
    • executable
    • prefix
    • module_search_paths_set, module_search_paths

“출력 필드”가 하나라도 설정되지 않으면, Python은 경로 구성을 계산하여 설정되지 않은 필드를 채웁니다. module_search_paths_set이 0이면, module_search_paths가 재정의되고 module_search_paths_set은 1로 설정됩니다.

위에 나열된 모든 경로 구성 출력 필드를 명시적으로 설정하면 기본 경로 구성을 계산하는 함수를 완전히 무시할 수 있습니다. 문자열은 비어 있지 않더라도 설정된 것으로 간주됩니다. module_search_paths_set이 1로 설정되어 있으면 module_search_paths는 설정된 것으로 간주됩니다. 이 경우 경로 구성 입력 필드도 무시됩니다.

경로 구성을 계산할 때 경고를 표시하지 않으려면 pathconfig_warnings를 0으로 설정하십시오(Unix 전용이며, Windows는 경고를 기록하지 않습니다).

base_prefix 또는 base_exec_prefix 필드가 설정되지 않으면, 각각 prefix와 exec_prefix에서 값을 상속합니다.

Py_RunMain()과 Py_Main()은 sys.path를 수정합니다:

  • run_filename이 설정되어 있고 __main__.py 스크립트를 포함하는 디렉터리이면, run_filename을 sys.path 앞에 추가합니다.
  • isolated가 0이면:
    • run_module이 설정되어 있으면 현재 디렉터리를 sys.path 앞에 추가합니다. 현재 디렉터리를 읽을 수 없으면 아무것도 하지 않습니다.
    • run_filename이 설정되어 있으면 파일 이름의 디렉터리를 sys.path 앞에 추가합니다.
    • 그렇지 않으면 sys.path 앞에 빈 문자열을 추가합니다.

site_import가 0이 아니면 site 모듈이 sys.path를 수정할 수 있습니다. user_site_directory가 0이 아니고 사용자의 사이트 패키지(site-package) 디렉터리가 존재하면, site 모듈은 사용자의 사이트 패키지 디렉터리를 sys.path에 추가합니다.

경로 구성에서 사용하는 Configuration Files도 참조하십시오.

Py_BytesMain()

Python 3.7은 명령줄 인자를 wchar_t* 문자열로 전달해야 하는 고수준 Py_Main() 함수를 제공합니다. 올바른 인코딩을 사용하여 바이트열을 디코딩하는 것은 간단한 일이 아닙니다. Python에는 C 로케일 강제 변환 및 UTF-8 모드와 관련된 고유한 문제들이 있습니다.

이 PEP는 명령줄 인자를 바이트열로 받는 새로운 Py_BytesMain() 함수를 추가합니다:

int Py_BytesMain(int argc, char **argv)

Py_RunMain()

새로운 Py_RunMain() 함수는 명령줄이나 설정에 지정된 명령(PyConfig.run_command), 스크립트(PyConfig.run_filename) 또는 모듈(PyConfig.run_module)을 실행한 다음 Python을 종료 처리합니다. 이 함수는 exit() 함수에 전달할 수 있는 종료 상태를 반환합니다.

int Py_RunMain(void);

Py_RunMain()을 사용하여 항상 격리 모드로 실행되는 사용자 정의 파이썬의 예는 Python Configuration을 참조하십시오.

다단계 초기화 비공개 잠정 API

이 절은 PEP 432의 핵심 기능인 다단계 초기화를 도입하는 비공개 잠정 API입니다:

  • “Core” 초기화 단계, “최소한의 Python”:
    • 내장 타입;
    • 내장 예외;
    • 내장 모듈과 프로즌 모듈;
    • sys 모듈은 부분적으로만 초기화됩니다(예: sys.path가 아직 존재하지 않습니다);
  • “Main” 초기화 단계, Python이 완전히 초기화됩니다:
    • importlib을 설치하고 구성합니다;
    • Path Configuration을 적용합니다;
    • 시그널 핸들러를 설치합니다;
    • sys 모듈 초기화를 마칩니다(예: sys.stdout과 sys.path를 생성합니다);
    • faulthandler와 tracemalloc 같은 선택적 기능을 활성화합니다;
    • site 모듈을 임포트합니다;
    • 등.

비공개 임시 API:

  • PyConfig._init_main: 0으로 설정하면 Py_InitializeFromConfig()는 “Core” 초기화 단계에서 멈춥니다.
  • PyStatus _Py_InitializeMain(void): “Main” 초기화 단계로 이동하여 Python 초기화를 마칩니다.

“Core” 단계에서는 어떤 모듈도 임포트되지 않으며 importlib 모듈도 구성되지 않습니다: Path Configuration은 “Main” 단계에서만 적용됩니다. 이를 통해 Python 안에서 Python을 사용자 정의하여 Path Configuration을 재정의하거나 조정하고, 사용자 정의 sys.meta_path 임포터나 임포트 훅 등을 설치할 수 있을 것입니다.

Core 단계 이후, Main 단계 이전에 Python으로 Path Configuration을 계산하는 것이 가능해질 수도 있으며, 이는 PEP 432의 동기 중 하나입니다.

“Core” 단계는 제대로 정의되어 있지 않습니다: 이 단계에서 무엇을 사용할 수 있어야 하고 무엇을 사용할 수 없어야 하는지는 아직 명시되지 않았습니다. 이 API는 비공개 및 임시로 표시되어 있습니다: 적절한 공개 API가 설계될 때까지 이 API는 언제든지 수정되거나 심지어 제거될 수 있습니다.

“Core”와 “Main” 초기화 단계 사이에서 Python 코드를 실행하는 예:

void init_python(void)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    config._init_main = 0;

    /* ... customize 'config' configuration ... */

    status = Py_InitializeFromConfig(&config);
    PyConfig_Clear(&config);
    if (PyStatus_Exception(status)) {
        Py_ExitStatusException(status);
    }

    /* Use sys.stderr because sys.stdout is only created
       by _Py_InitializeMain() */
    int res = PyRun_SimpleString(
        "import sys; "
        "print('Run Python code before _Py_InitializeMain', "
               "file=sys.stderr)");
    if (res < 0) {
        exit(1);
    }

    /* ... put more configuration code here ... */

    status = _Py_InitializeMain();
    if (PyStatus_Exception(status)) {
        Py_ExitStatusException(status);
    }
}

하위 호환성

이 PEP는 새로운 API를 추가하기만 합니다: 기존 API는 변경하지 않으며 하위 호환성에 아무런 영향을 주지 않습니다.

이제 Python 3.7의 Py_Initialize() 함수는 문자 깨짐(mojibake)을 방지하기 위해 C 로케일 강제 변환(PEP 538)과 UTF-8 모드(PEP 540)를 기본적으로 비활성화합니다. 이들을 자동으로 활성화하려면 Python Configuration을 사용하는 새로운 API가 필요합니다.

부록

Python 설정과 격리된 설정의 비교

PyPreConfig_InitPythonConfig()와 PyPreConfig_InitIsolatedConfig()의 차이점:

PyPreConfig Python 격리
coerce_c_locale_warn -1 0
coerce_c_locale -1 0
configure_locale 1 0
dev_mode -1 0
isolated 0 1
legacy_windows_fs_encoding -1 0
use_environment 0 0
parse_argv 1 0
utf8_mode -1 0

PyConfig_InitPythonConfig()와 PyConfig_InitIsolatedConfig()의 차이점:

PyConfig Python Isolated
configure_c_stdio 1 0
install_signal_handlers 1 0
isolated 0 1
parse_argv 1 0
pathconfig_warnings 1 0
use_environment 1 0
user_site_directory 1 0

우선순위와 규칙

구성 매개변수의 우선순위(높은 것부터 낮은 것 순서):

  • PyConfig
  • PyPreConfig
  • 설정 파일
  • 명령줄 옵션
  • 환경 변수
  • 전역 구성 변수

경고 옵션의 우선순위(높은 것부터 낮은 것 순서):

  • PyConfig.warnoptions
  • PySys_AddWarnOption()
  • PyConfig.bytes_warning (1보다 크면 "error::BytesWarning" 필터를 추가하고, 1이면 "default::BytesWarning 필터를 추가합니다)
  • -W opt 명령줄 인자
  • PYTHONWARNINGS 환경 변수
  • PyConfig.dev_mode ("default" 필터를 추가합니다)

PyConfig 매개변수에 대한 규칙:

  • isolated가 0이 아니면 use_environment와 user_site_directory가 0으로 설정됩니다.
  • dev_mode가 0이 아니면 allocator가 "debug"로 설정되고, faulthandler가 1로 설정되며, warnoptions에 "default" 필터가 추가됩니다. 하지만 메모리 할당자를 설정할 때는 PYTHONMALLOC 환경 변수가 dev_mode보다 우선합니다.
  • base_prefix가 설정되지 않으면 prefix 값을 상속합니다.
  • base_exec_prefix가 설정되지 않으면 exec_prefix 값을 상속합니다.
  • python._pth 설정 파일이 존재하면 isolated는 1로, site_import는 0으로 설정됩니다. 단, python._pth에 import site가 포함되어 있으면 site_import는 1로 설정됩니다.

PyConfig와 PyPreConfig 매개변수에 대한 규칙:

  • PyPreConfig.legacy_windows_fs_encoding이 0이 아니면 PyPreConfig.utf8_mode를 0으로 설정하고, PyConfig.filesystem_encoding을 mbcs로, PyConfig.filesystem_errors를 replace로 설정합니다.

설정 파일

Path Configuration이 사용하는 Python 설정 파일:

  • pyvenv.cfg
  • python._pth (Windows 전용)
  • pybuilddir.txt (Unix 전용)

전역 구성 변수

PyPreConfig 필드에 매핑되는 전역 구성 변수:

변수 필드
Py_IgnoreEnvironmentFlag use_environment (NOT)
Py_IsolatedFlag isolated
Py_LegacyWindowsFSEncodingFlag legacy_windows_fs_encoding
Py_UTF8Mode utf8_mode

(NOT)은 PyPreConfig 값이 전역 구성 변수 값의 반대라는 뜻입니다. Py_LegacyWindowsFSEncodingFlag는 윈도우에서만 사용할 수 있습니다.

PyConfig 필드에 매핑되는 전역 구성 변수:

변수 필드
Py_BytesWarningFlag bytes_warning
Py_DebugFlag parser_debug
Py_DontWriteBytecodeFlag write_bytecode (NOT)
Py_FileSystemDefaultEncodeErrors filesystem_errors
Py_FileSystemDefaultEncoding filesystem_encoding
Py_FrozenFlag pathconfig_warnings (NOT)
Py_HasFileSystemDefaultEncoding filesystem_encoding
Py_HashRandomizationFlag use_hash_seed, hash_seed
Py_IgnoreEnvironmentFlag use_environment (NOT)
Py_InspectFlag inspect
Py_InteractiveFlag interactive
Py_IsolatedFlag isolated
Py_LegacyWindowsStdioFlag legacy_windows_stdio
Py_NoSiteFlag site_import (NOT)
Py_NoUserSiteDirectory user_site_directory (NOT)
Py_OptimizeFlag optimization_level
Py_QuietFlag quiet
Py_UnbufferedStdioFlag buffered_stdio (NOT)
Py_VerboseFlag verbose
_Py_HasFileSystemDefaultEncodeErrors filesystem_errors

(NOT)은 PyConfig 값이 전역 구성 변수 값의 반대라는 뜻입니다. Py_LegacyWindowsStdioFlag는 Windows에서만 사용할 수 있습니다.

명령줄 인자

사용법:

python3 [options]
python3 [options] -c COMMAND
python3 [options] -m MODULE
python3 [options] SCRIPT

PyPreConfig 필드에 대한 의사 동작(pseudo-action)으로 매핑되는 명령줄 옵션:

옵션 PyConfig 필드
-E use_environment = 0
-I isolated = 1
-X dev dev_mode = 1
-X utf8 utf8_mode = 1
-X utf8=VALUE utf8_mode = VALUE

PyConfig 필드에 대한 의사 동작으로 매핑되는 명령줄 옵션:

옵션 PyConfig 필드
-b bytes_warning++
-B write_bytecode = 0
-c COMMAND run_command = COMMAND
--check-hash-based-pycs=MODE check_hash_pycs_mode = MODE
-d parser_debug++
-E use_environment = 0
-i inspect++ 및 interactive++
-I isolated = 1
-m MODULE run_module = MODULE
-O optimization_level++
-q quiet++
-R use_hash_seed = 0
-s user_site_directory = 0
-S site_import
-t 무시됩니다(하위 호환성을 위해 유지됩니다).
-u buffered_stdio = 0
-v verbose++
-W WARNING WARNING을 warnoptions에 추가합니다.
-x skip_source_first_line = 1
-X OPTION OPTION을 xoptions에 추가합니다.

-h, -?, -V 옵션은 PyConfig 없이 처리됩니다.

-X 옵션

PyConfig 필드에 대한 의사 동작으로 매핑되는 -X 옵션은 다음과 같습니다:

옵션 PyConfig 필드
-X dev dev_mode = 1
-X faulthandler faulthandler = 1
-X importtime import_time = 1
-X pycache_prefix=PREFIX pycache_prefix = PREFIX
-X showalloccount show_alloc_count = 1
-X showrefcount show_ref_count = 1
-X tracemalloc=N tracemalloc = N

환경 변수

PyPreConfig 필드에 매핑되는 환경 변수:

변수 PyPreConfig 필드
PYTHONCOERCECLOCALE coerce_c_locale, coerce_c_locale_warn
PYTHONDEVMODE dev_mode
PYTHONLEGACYWINDOWSFSENCODING legacy_windows_fs_encoding
PYTHONMALLOC allocator
PYTHONUTF8 utf8_mode

PyConfig 필드에 매핑되는 환경 변수:

변수 PyConfig 필드
PYTHONDEBUG parser_debug
PYTHONDEVMODE dev_mode
PYTHONDONTWRITEBYTECODE write_bytecode
PYTHONDUMPREFS dump_refs
PYTHONEXECUTABLE program_name
PYTHONFAULTHANDLER faulthandler
PYTHONHASHSEED use_hash_seed, hash_seed
PYTHONHOME home
PYTHONINSPECT inspect
PYTHONIOENCODING stdio_encoding, stdio_errors
PYTHONLEGACYWINDOWSSTDIO legacy_windows_stdio
PYTHONMALLOCSTATS malloc_stats
PYTHONNOUSERSITE user_site_directory
PYTHONOPTIMIZE optimization_level
PYTHONPATH pythonpath_env
PYTHONPROFILEIMPORTTIME import_time
PYTHONPYCACHEPREFIX, pycache_prefix
PYTHONTRACEMALLOC tracemalloc
PYTHONUNBUFFERED buffered_stdio
PYTHONVERBOSE verbose
PYTHONWARNINGS warnoptions

PYTHONLEGACYWINDOWSFSENCODING 및 PYTHONLEGACYWINDOWSSTDIO는 Windows 전용입니다.

기본 Python 설정

PyPreConfig_InitPythonConfig():

  • allocator = PYMEM_ALLOCATOR_NOT_SET
  • coerce_c_locale_warn = -1
  • coerce_c_locale = -1
  • configure_locale = 1
  • dev_mode = -1
  • isolated = 0
  • legacy_windows_fs_encoding = -1
  • use_environment = 1
  • utf8_mode = -1

PyConfig_InitPythonConfig():

  • argv = []
  • base_exec_prefix = NULL
  • base_prefix = NULL
  • buffered_stdio = 1
  • bytes_warning = 0
  • check_hash_pycs_mode = NULL
  • configure_c_stdio = 1
  • dev_mode = 0
  • dump_refs = 0
  • exec_prefix = NULL
  • executable = NULL
  • faulthandler = 0
  • filesystem_encoding = NULL
  • filesystem_errors = NULL
  • hash_seed = 0
  • home = NULL
  • import_time = 0
  • inspect = 0
  • install_signal_handlers = 1
  • interactive = 0
  • isolated = 0
  • malloc_stats = 0
  • module_search_path_env = NULL
  • module_search_paths = []
  • optimization_level = 0
  • parse_argv = 1
  • parser_debug = 0
  • pathconfig_warnings = 1
  • prefix = NULL
  • program_name = NULL
  • pycache_prefix = NULL
  • quiet = 0
  • run_command = NULL
  • run_filename = NULL
  • run_module = NULL
  • show_alloc_count = 0
  • show_ref_count = 0
  • site_import = 1
  • skip_source_first_line = 0
  • stdio_encoding = NULL
  • stdio_errors = NULL
  • tracemalloc = 0
  • use_environment = 1
  • use_hash_seed = 0
  • user_site_directory = 1
  • verbose = 0
  • warnoptions = []
  • write_bytecode = 1
  • xoptions = []
  • _init_main = 1
  • _install_importlib = 1

기본 격리 구성

PyPreConfig_InitIsolatedConfig():

  • allocator = PYMEM_ALLOCATOR_NOT_SET
  • coerce_c_locale_warn = 0
  • coerce_c_locale = 0
  • configure_locale = 0
  • dev_mode = 0
  • isolated = 1
  • legacy_windows_fs_encoding = 0
  • use_environment = 0
  • utf8_mode = 0

PyConfig_InitIsolatedConfig():

  • argv = []
  • base_exec_prefix = NULL
  • base_prefix = NULL
  • buffered_stdio = 1
  • bytes_warning = 0
  • check_hash_pycs_mode = NULL
  • configure_c_stdio = 0
  • dev_mode = 0
  • dump_refs = 0
  • exec_prefix = NULL
  • executable = NULL
  • faulthandler = 0
  • filesystem_encoding = NULL
  • filesystem_errors = NULL
  • hash_seed = 0
  • home = NULL
  • import_time = 0
  • inspect = 0
  • install_signal_handlers = 0
  • interactive = 0
  • isolated = 1
  • malloc_stats = 0
  • module_search_path_env = NULL
  • module_search_paths = []
  • optimization_level = 0
  • parse_argv = 0
  • parser_debug = 0
  • pathconfig_warnings = 0
  • prefix = NULL
  • program_name = NULL
  • pycache_prefix = NULL
  • quiet = 0
  • run_command = NULL
  • run_filename = NULL
  • run_module = NULL
  • show_alloc_count = 0
  • show_ref_count = 0
  • site_import = 1
  • skip_source_first_line = 0
  • stdio_encoding = NULL
  • stdio_errors = NULL
  • tracemalloc = 0
  • use_environment = 0
  • use_hash_seed = 0
  • user_site_directory = 0
  • verbose = 0
  • warnoptions = []
  • write_bytecode = 1
  • xoptions = []
  • _init_main = 1
  • _install_importlib = 1

Python 3.7 API

Python 3.7의 C API에는 Python을 초기화하고 종료 처리하는 함수가 4개 있습니다:

  • Py_Initialize(), Py_InitializeEx(): Python을 초기화합니다
  • Py_Finalize(), Py_FinalizeEx(): Python을 종료 처리합니다

Python 3.7은 Global Configuration Variables, Environment Variables 및 다음 함수를 사용하여 설정할 수 있습니다:

  • PyImport_AppendInittab()
  • PyImport_ExtendInittab()
  • PyMem_SetAllocator()
  • PyMem_SetupDebugHooks()
  • PyObject_SetArenaAllocator()
  • Py_SetPath()
  • Py_SetProgramName()
  • Py_SetPythonHome()
  • Py_SetStandardStreamEncoding()
  • PySys_AddWarnOption()
  • PySys_AddXOption()
  • PySys_ResetWarnOptions()

재정의할 수 있는 고수준 Py_Main() 함수와 PyImport_FrozenModules 변수도 있습니다.

Initialization, Finalization, and Threads 문서를 참조하십시오.

Python 이슈

이 PEP로 직접 또는 간접적으로 해결될 이슈는 다음과 같습니다:

  • bpo-1195571: “Py_FatalError를 위한 간단한 콜백 시스템”
  • bpo-11320: “API 메서드 Py_SetPath를 사용하면 Py_Initialize()에서 오류가 발생함 (Posix 전용)”
  • bpo-13533: “Py_Initialize가 호스트 앱과 원활하게 동작하기를 바람”
  • bpo-14956: “사용자 지정 PYTHONPATH가 파이썬을 임베드하는 앱을 망가뜨릴 수 있음”
  • bpo-19983: “시작 중에 인터럽트되면 파이썬은 abort()가 아니라 exit()를 호출해야 함”
  • bpo-22213: “파이썬을 임베드할 때 pyvenv 스타일 가상 환경을 더 쉽게 구성할 수 있도록 함”.
  • bpo-29778: “임베더가 Py_SetPath로 모듈 경로를 설정하면 _Py_CheckPython3가 초기화되지 않은 dllpath를 사용함”
  • bpo-30560: “Py_SetFatalErrorAbortFunc를 추가합니다: 임베딩 프로그램이 치명적 오류를 처리할 수 있도록 합니다”.
  • bpo-31745: “”Py_GetPath” 오버로딩이 동작하지 않습니다”
  • bpo-32573: “임베디드 환경에서도 모든 sys 속성(.argv, …)이 존재해야 합니다”.
  • bpo-33135: “다양한 구성 구조체의 필드 접두사를 정의합니다”. 이제 이 PEP는 경고 옵션을 처리하는 방식을 명확하게 정의합니다.
  • bpo-34725: “Windows에서 Py_GetProgramFullPath()가 이상하게 동작합니다”
  • bpo-36204: “Py_Initialize() 이후의 Py_Main() 호출을 폐지해야 합니까? Py_InitializeFromArgv()를 추가해야 합니까?”

PEP 구현 관련 이슈:

  • bpo-16961: “-E 및 개별 환경 변수에 대한 회귀 테스트가 없습니다”
  • bpo-20361: “-W 명령줄 옵션과 PYTHONWARNINGS 환경 변수가 -b / -bb 명령줄 옵션을 덮어써서는 안 됩니다”
  • bpo-26122: “격리 모드가 PYTHONHASHSEED를 무시하지 않습니다”
  • bpo-29818: “Py_SetStandardStreamEncoding이 디버그 모드에서 메모리 오류를 일으킵니다”
  • bpo-31845: “PYTHONDONTWRITEBYTECODE와 PYTHONOPTIMIZE가 아무 효과가 없습니다”
  • bpo-32030: “PEP 432: Py_Main()을 다시 작성합니다”
  • bpo-32124: “Py_Initialize() 전에 호출해도 안전한 함수를 문서화합니다”
  • bpo-33042: “새로운 3.7 시작 시퀀스로 인해 PyInstaller가 충돌합니다”
  • bpo-33932: “이제 Py_Initialize()를 두 번 호출하면 치명적 오류가 발생합니다(Python 3.7)”
  • bpo-34008: “Py_Initialize() 이후의 Py_Main() 호출을 지원합니까?”
  • bpo-34170: “Py_Initialize(): 경로 구성 계산에 부작용이 있어서는 안 됩니다(PEP 432)”
  • bpo-34589: “Py_Initialize()와 Py_Main()은 C 로케일 강제 변환을 활성화해서는 안 됩니다”
  • bpo-34639: “-E 또는 -I 옵션을 사용하면 PYTHONCOERCECLOCALE이 무시됩니다”
  • bpo-36142: “메모리 할당자와 인코딩을 설정하도록 Python 초기화에 새로운 _PyPreConfig 단계를 추가합니다”
  • bpo-36202: “_PyPreConfig_Write() 전에 Py_DecodeLocale()을 호출하면 모지바케가 발생할 수 있습니다”
  • bpo-36301: “_Py_PreInitialize() 함수를 추가합니다”
  • bpo-36443: “_PyPreConfig에서 coerce_c_locale과 utf8_mode를 기본적으로 비활성화해야 합니까?”
  • bpo-36444: “Python 초기화: _PyMainInterpreterConfig를 제거합니다”
  • bpo-36471: “PEP 432, PEP 587: _Py_RunMain()을 추가합니다”
  • bpo-36763: “PEP 587: PEP의 두 번째 버전을 준비하기 위해 초기화 API를 재작업합니다”
  • bpo-36775: “파일 시스템 코덱 구현을 재작업합니다”
  • bpo-36900: “전역 구성 변수 대신 _PyCoreConfig를 사용합니다”

이 PEP와 관련된 이슈:

  • bpo-12598: “sys 변수 초기화를 import.c에서 sysmodule.c로 옮깁니다”
  • bpo-15577: “임베드된 인터프리터의 실제 argc와 argv”
  • bpo-16202: “sys.path[0] 보안 문제”
  • bpo-18309: “python을 조금 더 재배치 가능하게 만듭니다”
  • bpo-22257: “PEP 432: 인터프리터 시작 시퀀스를 재설계합니다”
  • bpo-25631: “임베드된 Python에서 잘못된 유니코드 명령줄 인자로 인한 세그멘테이션 폴트”
  • bpo-26007: “실행 파일에 표준 라이브러리를 임베드하는 기능을 지원합니다”
  • bpo-31210: “sys.prefix에 DELIM이 포함되어 있으면 모듈을 임포트할 수 없습니다”.
  • bpo-31349: “임베드 초기화가 Py_SetProgramName()을 무시합니다”
  • bpo-33919: “_PyCoreConfig 구조체를 Python에 노출합니다”
  • bpo-35173: “이미 존재하는 기능을 재사용하여 Python 2.7.x(임베드된 경우와 독립 실행형 모두)가 공유 라이브러리를 기준으로 모듈 경로를 찾을 수 있도록 합니다”

논의

버전 이력

  • 버전 5:
    • PyInitError의 이름을 PyStatus로 변경합니다
    • PyInitError_Failed()의 이름을 PyStatus_Exception()으로 변경합니다
    • Py_ExitInitError()의 이름을 Py_ExitStatusException()으로 변경합니다
    • PyPreConfig._config_init 비공개 필드를 추가합니다.
    • Python 구성의 기본값을 -1 대신 isolated=0, use_environment=1로 수정합니다.
    • “Multi-Phase Initialization Private Provisional API” 및 “Discussions” 섹션을 추가합니다.
  • 버전 4:
    • 더 명확하게 정의된 “Python Configuration”과 “Isolated Configuration”을 도입합니다. 모든 매크로를 함수로 대체합니다.
    • PyPreConfig_INIT 및 PyConfig_INIT 매크로를 다음 함수로 대체합니다:
      • PyPreConfig_InitIsolatedConfig(), PyConfig_InitIsolatedConfig()
      • PyPreConfig_InitPythonConfig(), PyConfig_InitPythonConfig()
    • PyPreConfig는 더 이상 동적 메모리를 사용하지 않으며, allocator 필드의 타입은 int가 되고, configure_locale 및 parse_argv 필드를 추가합니다.
    • PyConfig: module_search_path_env를 pythonpath_env로, use_module_search_paths를 module_search_paths_set으로 이름을 변경하고, program과 dll_path를 제거합니다.
    • Py_INIT_xxx() 매크로를 PyInitError_xxx() 함수로 대체합니다.
    • “상수 PyConfig(Constant PyConfig)” 섹션을 제거합니다. Py_InitializeFromArgs() 및 Py_InitializeFromBytesArgs() 함수를 제거합니다.
  • 버전 3:
    • PyConfig: configure_c_stdio와 parse_argv를 추가하고, _frozen을 pathconfig_warnings로 이름을 변경합니다.
    • 바이트 문자열과 와이드 문자 문자열을 사용하는 함수의 이름을 변경합니다. 예를 들어, Py_PreInitializeFromWideArgs()는 Py_PreInitializeFromArgs()가 되고, PyConfig_SetArgv()는 PyConfig_SetBytesArgv()가 됩니다.
    • PyWideStringList_Insert() 함수를 추가합니다.
    • “Path configuration”, “Isolate Python”, “Python Issues”, “Version History” 섹션을 새로 추가합니다.
    • 이제 PyConfig_SetString()과 PyConfig_SetBytesString()은 첫 번째 인자로 구성(configuration)을 요구합니다.
    • Py_UnixMain()을 Py_BytesMain()으로 이름을 변경합니다.
  • 버전 2: PyConfig 메서드(예: PyConfig_Read())를 추가하고, PyWideStringList_Append()를 추가하며, PyWideCharList를 PyWideStringList로 이름을 변경합니다.
  • 버전 1: 최초 버전입니다.

수락

PEP 587은 2019년 5월 26일 Thomas Wouters가 승인했습니다.