Hi, First of all, I just found an old issue that we will solved by my PEP 587 :-)
Add Py_SetFatalErrorAbortFunc: Allow embedding program to handle fatal errors https://bugs.python.org/issue30560 I studied code of applications embedding Python. Most of them has to decode bytes strings to get wchar_t* to set home, argv, program name, etc. I'm not sure that they use the "correct" encoding, especially since Python 3.7 got UTF-8 Mode (PEP 540) and C locale coercion (PEP 538). I tried to convert the source code of each project into pseudo-code which looks like C code used in CPython. I removed all error handling code: look at each reference, the original code is usually way more complex. Some project has to wrap each function of the Python C API manually, which adds even more boilerplate code. Some project set/unset environment varaibles. Others prefer global configuration variables like Py_NoSiteFlag. It seems like Py_FrozenFlag is commonly used. Maybe I should make the flag public and try to find it a better name: /* If greater than 0, suppress _PyPathConfig_Calculate() warnings. If set to -1 (default), inherit Py_FrozenFlag value. */ int _frozen; About pyinstaller which changes C standard stream buffering: Py_Initialize() now also does that when buffered_stdio=0. See config_init_stdio() in Python/coreconfig.c. Moreover, this function now *always* set standard streams to O_BINARY mode on Windows. I'm not sure if it's correct or not. Blender ------- Pseudo-code of BPY_python_start:: BLI_strncpy_wchar_from_utf8(program_path_wchar, BKE_appdir_program_path()); Py_SetProgramName(program_path_wchar); PyImport_ExtendInittab(bpy_internal_modules); Py_SetPythonHome(py_path_bundle_wchar); Py_SetStandardStreamEncoding("utf-8", "surrogateescape"); Py_NoSiteFlag = 1; Py_FrozenFlag = 1; Py_Initialize(); Ref: https://git.blender.org/gitweb/gitweb.cgi/blender.git/blob/HEAD:/source/blender/python/intern/bpy_interface.c fontforge --------- Pseudo-code of fontforge when Python is used to run a script:: Py_Initialize() for init_file in init_files: PyRun_SimpleFileEx(init_file) exitcode = Py_Main(arg, argv) Py_Finalize() exit(exitcode) Ref: https://bugs.python.org/issue36204#msg337256 py2app ------ Pseudo-code:: unsetenv("PYTHONOPTIMIZE"); unsetenv("PYTHONDEBUG"); unsetenv("PYTHONDONTWRITEBYTECODE"); unsetenv("PYTHONIOENCODING"); unsetenv("PYTHONDUMPREFS"); unsetenv("PYTHONMALLOCSTATS"); setenv("PYTHONDONTWRITEBYTECODE", "1", 1); setenv("PYTHONUNBUFFERED", "1", 1); setenv("PYTHONPATH", build_python_path(), 1); setlocale(LC_ALL, "en_US.UTF-8"); mbstowcs(w_program, c_program, PATH_MAX+1); Py_SetProgramName(w_program); Py_Initialize() argv_new[0] = _Py_DecodeUTF8_surrogateescape(script, strlen(script)); ... PySys_SetArgv(argc, argv_new); PyRun_SimpleFile(fp, script); Py_Finalize(); Ref: https://bitbucket.org/ronaldoussoren/py2app/src/default/py2app/apptemplate/src/main.c See also: https://bitbucket.org/ronaldoussoren/py2app/src/default/py2app/bundletemplate/src/main.m OpenOffice ---------- Pseudo-code of ``PythonInit``:: mbstowcs(wide, home, PATH_MAX + 1); Py_SetPythonHome(wide); setenv("PYTHONPATH", getenv("PYTHONPATH") + ":" + path_bootstrap); PyImport_AppendInittab("pyuno", PyInit_pyuno); Py_DontWriteBytecodeFlag = 1; Py_Initialize(); Ref: pyuno/source/loader/pyuno_loader.cxx, see: https://docs.libreoffice.org/pyuno/html/pyuno__loader_8cxx_source.html vim --- Pseudo-code:: mbstowcs(py_home_buf, p_py3home); Py_SetPythonHome(py_home_buf); PyImport_AppendInittab("vim", Py3Init_vim); Py_Initialize(); Ref: https://github.com/vim/vim/blob/master/src/if_python3.c pyinstaller ----------- Pseudo-code:: pyi_locale_char2wchar(progname_w, status->archivename) SetProgramName(progname_w); pyi_locale_char2wchar(pyhome_w, status->mainpath) SetPythonHome(pyhome_w); pypath_w = build_path(); Py_SetPath(pypath_w); Py_NoSiteFlag = 1; Py_FrozenFlag = 1; Py_DontWriteBytecodeFlag = 1; Py_NoUserSiteDirectory = 1; Py_IgnoreEnvironmentFlag = 1; Py_VerboseFlag = 0; Py_OptimizeFlag = 1; if (unbuffered) { #ifdef _WIN32 _setmode(fileno(stdin), _O_BINARY); _setmode(fileno(stdout), _O_BINARY); #endif setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } Py_Initialize(); PySys_SetPath(pypath_w); PySys_SetArgvEx(argc, wargv, 0); Ref: https://github.com/pyinstaller/pyinstaller/blob/1844d69f5aa1d64d3feca912ed1698664a3faf3e/bootloader/src/pyi_pythonlib.c Victor _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com