Конфигурация инициализации Python

Добавлено в версии 3.8.

Структуры:

Функции:

Предварительная конфигурация (тип PyPreConfig) сохраняется в _PyRuntime.preconfig, а конфигурация (тип PyConfig) - в PyInterpreterState.config.

См. также Инициализация, финализация и потоки.

См.также

PEP 587 «Инициализация конфигурации Python».

PyWideStringList

PyWideStringList

Список wchar_t* строк.

Если length не равно нулю, items должен быть не-NULL, а все строки должны быть не-NULL.

Методы:

PyStatus PyWideStringList_Append(PyWideStringList *list, const wchar_t *item)

Добавить item к list.

Python вызовы этой функции необходимо предварительно инициализировать.

PyStatus PyWideStringList_Insert(PyWideStringList *list, Py_ssize_t index, const wchar_t *item)

Вставить item в list на index.

Если index больше или равно длине list, добавить item к list.

index должно быть больше или равно 0.

Python вызова этой функции необходимо предварительно инициализировать.

Поля структуры:

Py_ssize_t length

Длина списка.

wchar_t** items

Перечислить элементы.

PyStatus

PyStatus

Структура для хранения состояния функции инициализации: успех, ошибка или выход.

Для ошибки она может сохранить имя функции C, которая создала ошибку.

Поля структуры:

int exitcode

Выйти из кода. Аргумент передан exit().

const char *err_msg

Сообщение об ошибке.

const char *func

Имя функции, которая создала ошибку может быть NULL.

Функции для создания статуса:

PyStatus PyStatus_Ok(void)

Успех.

PyStatus PyStatus_Error(const char *err_msg)

Ошибка инициализации с сообщением.

PyStatus PyStatus_NoMemory(void)

Ошибка выделения памяти (недостаточно памяти).

PyStatus PyStatus_Exit(int exitcode)

Выход Python с указанным код выхода.

Функции для обработки статуса:

int PyStatus_Exception(PyStatus status)

Статус ошибки или выход? Если true, исключение должно быть обработано; путем вызова Py_ExitStatusException() например.

int PyStatus_IsError(PyStatus status)

Является ли результат ошибкой?

int PyStatus_IsExit(PyStatus status)

Результат - это выход?

void Py_ExitStatusException(PyStatus status)

Вызвать exit(exitcode), если status выход. Напечатать сообщение об ошибке и выйти с ненулевым кодом выхода, если status ошибка. Должен вызываться только в том случае, если PyStatus_Exception(status) не равна нулю.

Примечание

Внутри Python использует макросы, которые задают PyStatus.func, в то время как функции создают набор статусов, func NULL.

Пример:

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;
}

PyPreConfig

PyPreConfig

Используемые структуры для предварительной инициализации Python:

  • Установить распределитель памяти Python
  • Настроить локаль LC_CTYPE
  • Установить режим UTF-8

Функция инициализации предварительной конфигурации:

void PyPreConfig_InitPythonConfig(PyPreConfig *preconfig)

Инициализировать предварительную конфигурацию с помощью Конфигурации Python.

void PyPreConfig_InitIsolatedConfig(PyPreConfig *preconfig)

Инициализировать предварительную конфигурацию с помощью Изолированная конфигурация.

Поля структуры:

int allocator

Имя распределителя памяти:

  • 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 распределитель Python распределитель с хуками отладки

PYMEM_ALLOCATOR_PYMALLOC и PYMEM_ALLOCATOR_PYMALLOC_DEBUG не поддерживаются, если Python настроен с использованием --without-pymalloc

См. Управление памятью.

int configure_locale

Задать LC_CTYPE локаль для предпочтительной локали пользователя? Если значение равно 0, установить значение coerce_c_locale и coerce_c_locale_warn в значение 0.

int coerce_c_locale

Если равно 2, принудительно ввести C локаль; если равно 1, прочтать LC_CTYPE локаль, чтобы решить, следует ли его принудительно использовать.

int coerce_c_locale_warn

Если значение не равно нулю, выдать предупреждение, если локаль C по принуждению.

int dev_mode

См. PyConfig.dev_mode.

int isolated

См. PyConfig.isolated.

int legacy_windows_fs_encoding(только Windows)

Если отличный от нуля, отключить режим UTF-8, установить кодировку файловой системы Python в mbcs, установить ошибку файловой системы обработчик в replace.

Доступно только в Windows. #ifdef MS_WINDOWS макрос можно использовать для Windows са код .

int parse_argv

Если значение не равно нулю, Py_PreInitializeFromArgs() и Py_PreInitializeFromBytesArgs() анализируют свой аргумент argv так же, как обычные Python разбирают аргументы командной строки: см. Аргументы командной строки.

int use_environment

См. PyConfig.use_environment.

int utf8_mode

Если значение не равно нулю, включить режим UTF-8.

Предварительная инициализация с помощью PyPreConfig

Функции для предварительной инициализации Python:

PyStatus Py_PreInitialize(const PyPreConfig *preconfig)

Выполнить предварительную инициализацию Python из preconfig предварительной конфигурации.

PyStatus Py_PreInitializeFromBytesArgs(const PyPreConfig *preconfig, int argc, char * const *argv)

Предварительно инициализировать Python из предварительной конфигурации preconfig и аргументов командной строки (байт строки).

PyStatus Py_PreInitializeFromArgs(const PyPreConfig *preconfig, int argc, wchar_t * const * argv)

Предварительно инициализировать Python из предварительной конфигурирации preconfig и аргументов командной строки (широкие строки).

Вызывающий отвечает за обработку исключений (ошибка или выход) с помощью PyStatus_Exception() и Py_ExitStatusException().

Для Конфигурация Python (PyPreConfig_InitPythonConfig()), если Python инициализируется аргументами командной строки, аргументы командной строки также должны передаваться для предварительной инициализации Python, так как они влияют на предконфигурацию, например, кодировки. Например, параметр командной строки -X utf8 включает режим UTF-8.

PyMem_SetAllocator() можно вызвать после Py_PreInitialize() и до Py_InitializeFromConfig(), чтобы установить пользовательский распределитель памяти. Его можно вызвать перед Py_PreInitialize(), если для PyPreConfig.allocator установлено значение PYMEM_ALLOCATOR_NOT_SET.

Python функции выделения памяти, такие как PyMem_RawMalloc(), не должны быть использовать до предварительной инициализации Python, в то время как прямой вызов malloc() и free() всегда безопасен. Py_DecodeLocale() не должны вызываться до начала инициализации.

Пример использования предварительной инициализации для включения режима UTF-8:

PyStatus status;
PyPreConfig preconfig;
PyPreConfig_InitPythonConfig(&preconfig);

preconfig.utf8_mode = 1;

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

/* на этом этапе Python будет говорить в кодировке UTF-8 */

Py_Initialize();
/* ... используется Python API здесь ... */
Py_Finalize();

PyConfig

PyConfig

Структура, содержащая большинство параметров для настройки Python.

Методы структуры:

void PyConfig_InitPythonConfig(PyConfig *config)

Инициализировать конфигурацию с помощью конфигурации Python.

void PyConfig_InitIsolatedConfig(PyConfig *config)

Инициализировать конфигурацию с помощью изолированной конфигурации.

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)

Декодировать str с помощью Py_DecodeLocale() и установить результат в *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_SetWideStringList(PyConfig *config, PyWideStringList *list, Py_ssize_t length, wchar_t **items)

Установить список широких строк list length и items.

При необходимости выполнить предварительную инициализацию Python.

PyStatus PyConfig_Read(PyConfig *config)

Прочтить всю конфигурацию Python.

Поля, которые уже инициализированы, остаются без изменений.

При необходимости выполнить предварительную инициализацию Python.

void PyConfig_Clear(PyConfig *config)

Освободить память конфигурации.

Большинство PyConfig методов при необходимости инициализируют Python. В этом случае, конфигурация перед инициализацией Python в на основе PyConfig. Если настраиваются общие поля конфигурации с PyPreConfig , их необходимо установить перед вызовом метода PyConfig:

Кроме того, если используются PyConfig_SetArgv() или PyConfig_SetBytesArgv(), этот метод должен быть вызван сначала, перед другими методами, так как конфигурация преинициализации зависит от аргументов командной строки (если parse_argv не равно нулю).

Вызывающий этих методов отвечает за обработку исключений (ошибок или выхода) с помощью PyStatus_Exception() и Py_ExitStatusException().

Поля структуры:

PyWideStringList argv

Аргументы командной строки, sys.argv. См. parse_argv, чтобы разобрать argv тем же путем, как регулярный Python разбирает аргументы командной строки Python. Если argv пуст, добавляется пустая строка, чтобы гарантировать, что sys.argv всегда существует и никогда не пуст.

wchar_t* base_exec_prefix

sys.base_exec_prefix.

wchar_t* base_executable

sys._base_executable: __PYVENV_LAUNCHER__ значение переменной среды или копия PyConfig.executable.

wchar_t* base_prefix

sys.base_prefix.

int buffered_stdio

Если значение равно 0, активизировать режим без буферизации, делая потоки stdout и stderr не буферизованными.

stdin всегда открывается в буферном режиме.

int bytes_warning

Если значение равно 1, при сравнении bytes или bytearray с str или сравнении bytes с int выдается предупреждение. Если значение равно или больше 2, создается исключение BytesWarning.

wchar_t* check_hash_pycs_mode

Управление поведением проверки файлов .pyc на основе хэша (см. PEP 552): --check-hash-based-pycs параметр командной строки.

Допустимые значения: always, never и default.

По умолчанию используется значение: default.

int configure_c_stdio

Если значение не равно нулю, настраиваются стандартные потоки C (stdio, stdout, stdout). Например, установить для них режим O_BINARY в Windows.

int dev_mode

Режим разработки: см. -X dev.

int dump_refs

Если значение не равно нулю, дамп всех объекты, которые остаются живыми при выходе.

Требуется отладочная сборка Python (макрос Py_REF_DEBUG должен быть определен).

wchar_t* exec_prefix

sys.exec_prefix.

wchar_t* executable

sys.executable.

int faulthandler

Если значение не равно нулю, вызвать faulthandler.enable() при запуске.

wchar_t* filesystem_encoding

Кодировка файловой системы, sys.getfilesystemencoding().

wchar_t* filesystem_errors

Ошибка кодировки файловой системы, sys.getfilesystemencodeerrors().

unsigned long hash_seed
int use_hash_seed

Рандомизированное начальное число хеш-функции.

Если use_hash_seed равно нулю, начальное число выбирается случайным образом в Pythonstartup, и hash_seed игнорируется.

wchar_t* home

Домашний каталог Python.

Инициализировано из переменной среды PYTHONHOME значение по умолчанию.

int import_time

Если значение не равно нулю, время импорта профиля.

int inspect

Переход в интерактивный режим после выполнения сценария или команды.

int install_signal_handlers

Установить сигнал обработчика?

int interactive

Интерактивный режим.

int isolated

Если значение больше 0, включить изолированный режим:

  • sys.path не содержит ни каталога сценария (вычисленного из argv[0] или текущего каталога), ни каталога веб-пакетов пользователя.
  • Python REPL не импортирует readline и не включает конфигурацию readline по умолчанию в интерактивных подсказках.
  • Установить значение use_environment и user_site_directory равным 0.
int legacy_windows_stdio

Если значение не равно нулю, используется io.FileIO вместо io.WindowsConsoleIO для sys.stdin, sys.stdout и sys.stderr.

Доступно только в Windows. #ifdef MS_WINDOWS макрос можно использовать для определенных код Windows.

int malloc_stats

Если значение не равно нулю, дамп статистики по распределению памяти Python pymalloc на выходе.

Параметр игнорируется, если Python собран с использованием --without-pymalloc.

wchar_t* pythonpath_env

Пути поиска модулей в виде строки, разделенных DELIM (os.path.pathsep).

Инициализировано из переменной среды PYTHONPATH значение по умолчанию.

PyWideStringList module_search_paths
int module_search_paths_set

sys.path. Если module_search_paths_set равно 0, module_search_paths переопределяется функцией, вычисляющей конфигурацию пути.

int optimization_level

Уровень оптимизации компиляции:

  • 0: Оптимизатор Peephole (и __debug__ устанавливается равным True)
  • 1: Удалить утверждения, установить для __debug__ значение False
  • 2: Стрип докстрингов
int parse_argv

Если отличный от нуля, парсинг argv тем же путем регулярные аргументы командной строки Python и стрип аргументов Python из argv: см. Аргументы командной строки.

int parser_debug

Если отличный от нуля, включить вывод отладки парсера (только для эксперта, в зависимости от вариантов компиляции).

int pathconfig_warnings

Если значение равно 0, подавление предупреждений при вычислении Конфигурации пути (только для Unix, Windows не регистрирует предупреждения). В противном случае предупреждения записываются в stderr.

wchar_t* prefix

sys.prefix.

wchar_t* program_name

Название программы. Используется для инициализации executable и в ранних сообщениях об ошибках.

wchar_t* pycache_prefix

sys.pycache_prefix: префикс .pyc кэша.

Если NULL, sys.pycache_prefix устанавливается равным None.

int quiet

Тихий режим. Например, не отображать сообщения об авторских правах и версии в интерактивном режиме.

wchar_t* run_command

python3 -c COMMAND аргумент. Используется Py_RunMain().

wchar_t* run_filename

python3 FILENAME аргумент. Используется Py_RunMain().

wchar_t* run_module

python3 -m MODULE аргумент. Используется Py_RunMain().

int show_alloc_count

Показать количество распределений на выходе?

Установить значение 1 -X showalloccount помощью параметра командной строки.

Требуется специальная сборка Python с COUNT_ALLOCS макросом.

int show_ref_count

Показать общее количество ссылок на выходе?

Установить значение 1 -X showrefcount помощью параметра командной строки.

Требуется отладочная сборка Python (макрос Py_REF_DEBUG должен быть определен).

int site_import

Импортировать модуль site при запуске?

int skip_source_first_line

Пропустить первую строку источника?

wchar_t* stdio_encoding
wchar_t* stdio_errors

Ошибки кодирования и кодировка sys.stdin, sys.stdout и sys.stderr.

int tracemalloc

Если значение не равно нулю, вызвать tracemalloc.start() при запуске.

int use_environment

Если больше 0, используется переменные среды.

int user_site_directory

Если значение не равно нулю, добавить каталог сайта пользователя в sys.path.

int verbose

Если значение не равно нулю, включить подробный режим.

PyWideStringList warnoptions

sys.warnoptions: параметры модуля warnings для построения фильтров предупреждений: от низшего до наивысшего приоритета.

Модуль warnings добавляет sys.warnoptions в обратном порядке: последний элемент PyConfig.warnoptions становится первым элементом warnings.filters, который проверяется первым (наивысший приоритет).

int write_bytecode

Если значение не равно нулю, записать .pyc файлы.

sys.dont_write_bytecode инициализируется в инвертированное значение write_bytecode.

PyWideStringList xoptions

sys._xoptions.

Если parse_argv не равно нулю, argv аргументы анализируются так же, как обычный Python разбирает аргументы командной строки, и Python аргументы удаляются из argv: см. Аргументы командной строки.

Параметры xoptions анализируются для установки других параметров: см. -X параметр.

Инициализация с помощью PyConfig

Функция инициализации Python:

PyStatus Py_InitializeFromConfig(const PyConfig *config)

Инициализировать Python из config конфигурации.

Вызывающий отвечает за обработку исключений (ошибка или выход) с помощью PyStatus_Exception() и Py_ExitStatusException().

Если PyImport_FrozenModules, PyImport_AppendInittab() или PyImport_ExtendInittab() - использовать, их нужно установить или назвать после предварительной инициализации Python и перед инициализацией Python.

Пример установки имени программы:

void init_python(void)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    /* Задать название программы. Неявно преинициализировать 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);
}

Более полный пример: изменение конфигурации по умолчанию, чтение конфигурации, а затем переопределение некоторых параметров:

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

    PyConfig config;
    PyConfig_InitPythonConfig(&config);

    /* Задать имя программы перед чтением конфигурации
       (декодировать байтовую строку из кодировки локали).

       Неявно преинициализировать Python. */
    status = PyConfig_SetBytesString(&config, &config.program_name,
                                  program_name);
    if (PyStatus_Exception(status)) {
        goto done;
    }

    /* Прочитать всю конфигурацию сразу */
    status = PyConfig_Read(&config);
    if (PyStatus_Exception(status)) {
        goto done;
    }

    /* Добавить наш собственный путь поиска в sys.path */
    status = PyWideStringList_Append(&config.module_search_paths,
                                     L"/path/to/more/modules");
    if (PyStatus_Exception(status)) {
        goto done;
    }

    /* Заменить исполняемый файл, вычисленный 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;
}

Изолированная конфигурация

Функции PyPreConfig_InitIsolatedConfig() и PyConfig_InitIsolatedConfig() создают конфигурацию для изоляции Python от системы. Например, для встраивания Python в приложение.

Эта конфигурация игнорирует глобальные переменные конфигурации, переменные среды, аргументы командной строки (PyConfig.argv не анализируется) и каталог сайта пользователя. Стандартные потоки C (например, stdout) и LC_CTYPE локаль остаются без изменений. Сигнальные обработчики не устанавливаются.

Файлы конфигурации по-прежнему используются с этой конфигурацией. Установить Конфигурация пути («поля вывода»), чтобы игнорировать эти файлы конфигурации и избежать функции, вычисляющей конфигурацию пути по умолчанию.

Python конфигурация

Функции PyPreConfig_InitPythonConfig() и PyConfig_InitPythonConfig() создают конфигурацию для построения настраиваемого Python, который ведет себя как обычный Python.

Переменные среды и аргументы командной строки используемые для настройки Python, тогда как переменные глобальной конфигурации игнорируются.

Эта функция включает C согласование локали (PEP 538) и UTF-8 режим (PEP 540) в зависимости от переменных среды LC_CTYPE locale, PYTHONUTF8 и PYTHONCOERCECLOCALE.

Пример настраиваемых Python, всегда работающих в изолированном режиме:

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

    PyConfig config;
    PyConfig_InitPythonConfig(&config);
    config.isolated = 1;

    /* Расшифровать аргументы командной строки.
       Неявно предварительно инициализировать Python (в изолированном режиме). */
    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;
    }
    /* Отобразить сообщение об ошибке и выйдите из процесса, передав
       ненулевой код выхода */
    Py_ExitStatusException(status);
}

Конфигурация пути

PyConfig содержит несколько полей для конфигурации пути:

Если хотя бы одно «поле вывода» не установлено, Python вычисляет конфигурацию пути для заполнения неснятых полей. Если module_search_paths_set равно 0, module_search_paths переопределяется, а module_search_paths_set устанавливается равным 1.

Можно полностью игнорировать функцию вычисления конфигурации пути по умолчанию, задав явно все поля вывода конфигурации пути, перечисленные выше. Строка считается установленной, даже если она не пуста. module_search_paths считается установленной, если module_search_paths_set имеет значение 1. В этом случае поля ввода конфигурации пути также игнорируются.

Установить для 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 равно нулю:
    • Если run_module установлен, добавить текущий каталог к sys.path. Ничего не делать, если текущий каталог не может быть прочитан.
    • Если run_filename установлено, добавить каталог с именем файла к sys.path.
    • В противном случае добавить пустой строка к sys.path.

Если site_import ненулевое, sys.path может быть изменен модулем site. Если user_site_directory не равно нулю, и каталог сайта-пакета пользователя существует, модуль site добавляет к sys.path каталог сайта-пакета пользователя.

Конфигурация пути используя следующие файлы конфигурации:

  • pyvenv.cfg
  • python._pth (только Windows)
  • pybuilddir.txt (только Unix)

Переменная среды __PYVENV_LAUNCHER__ использовать для установки PyConfig.base_executable

Py_RunMain()

int Py_RunMain(void)

Выполнить команду (PyConfig.run_command), сценарий (PyConfig.run_filename) или модуль (PyConfig.run_module), указанный в командной строке или в конфигурации.

По умолчанию и при -i использовать опции выполнить команду REPL.

Наконец, завершает Python и возвращает статус выхода, который может быть передан функции exit().

Пример настраиваемых Конфигураций Python, всегда работающих в изолированном режиме с использованием Python, см. в разделе Py_RunMain().

Предварительный частный API многофазной инициализации

Этот раздел является частным временным API, вводящим многофазную инициализацию, основную функцию PEP 432:

  • Фаза инициализации «Ядра», «минимальный Python»:
    • Встроенные типы;
    • Встроенные исключения;
    • Встроенные и замороженные модули;
    • Модуль sys инициализирован только частично (например, sys.path еще не существует).
  • «Основная» фаза инициализации, Python полностью инициализирована:
    • Установить и настроить importlib;
    • Применить Конфигурацию пути;
    • Установить обработчики сигналов;
    • Завершение инициализации модуля sys (например, создание sys.stdout и sys.path);
    • Включите дополнительные функции, такие как faulthandler и tracemalloc;
    • Импортировать модуль site;
    • и т.д.

Частный предварительный API:

  • PyConfig._init_main: если установлено значение 0, Py_InitializeFromConfig() останавливается на фазе инициализации «Ядро».
PyStatus _Py_InitializeMain(void)

Перейдите к фазе инициализации «Основная», завершить инициализацию Python.

На этапе «Ядро» модуль не импортируется, а importlib модуль не конфигурируется: Конфигурация пути применяется только на этапе «Основная». Это может позволить настроить Python в Python для переопределения или настройки Конфигурация пути, может быть, установить пользовательский импортер sys.meta_path или хук импорта и т.д.

Возможно вычисление Конфигурации пути в Python, после основной фазы и перед основной фазой, что является одной из PEP 432 мотиваций.

Этап «Ядро» не определен должным образом: что должно быть, а что не должно быть доступно на этом этапе, пока не указано. API помечен как частный и временный: API может быть изменен или даже удален в любое время, пока не будет разработан соответствующий публичный API.

Пример выполнения Python кода между фазами инициализации «Ядро» и «Основное»:

void init_python(void)
{
    PyStatus status;

    PyConfig config;
    PyConfig_InitPythonConfig(&config);
    config._init_main = 0;

    /* ... настроить 'config' конфигурацию  ... */

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

    /* Использовать sys.stderr, потому что sys.stdout создается только
       _Py_InitializeMain() */
    int res = PyRun_SimpleString(
        "import sys; "
        "print('Run Python code before _Py_InitializeMain', "
               "file=sys.stderr)");
    if (res < 0) {
        exit(1);
    }

    /* ... поместить сюда дополнительный код конфигурации ... */

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