int Py_FrozenMain(int argc, char **argv) { char *p; int n, sts; int inspect = 0; int unbuffered = 0; Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ Py_SetProgramName(argv[0]); Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif Py_Finalize(); return sts; }
char * Py_GetPythonHome(void) { char *home = default_home; if (home == NULL && !Py_IgnoreEnvironmentFlag) home = Py_GETENV("PYTHONHOME"); return home; }
wchar_t * Py_GetPythonHome(void) { wchar_t *home = default_home; if (home == NULL && !Py_IgnoreEnvironmentFlag) { char* chome = Py_GETENV("PYTHONHOME"); if (chome) { size_t size = Py_ARRAY_LENGTH(env_home); size_t r = mbstowcs(env_home, chome, size); if (r != (size_t)-1 && r < size) home = env_home; } } return home; }
void PyThread_init_thread(void) { #ifdef Py_DEBUG char *p = Py_GETENV("PYTHONTHREADDEBUG"); if (p) { if (*p) thread_debug = atoi(p); else thread_debug = 1; } #endif /* Py_DEBUG */ if (initialized) return; initialized = 1; dprintf(("PyThread_init_thread called\n")); PyThread__init_thread(); }
void setEncodingAndErrors() { // Adapted from pythonrun.c in CPython, with modifications for Pyston. char* p; char* icodeset = nullptr; char* codeset = nullptr; char* errors = nullptr; int free_codeset = 0; int overridden = 0; PyObject* sys_stream, *sys_isatty; char* saved_locale, *loc_codeset; if ((p = Py_GETENV("PYTHONIOENCODING")) && *p != '\0') { p = icodeset = codeset = strdup(p); free_codeset = 1; errors = strchr(p, ':'); if (errors) { *errors = '\0'; errors++; } overridden = 1; } #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) /* On Unix, set the file system encoding according to the user's preference, if the CODESET names a well-known Python codec, and Py_FileSystemDefaultEncoding isn't initialized by other means. Also set the encoding of stdin and stdout if these are terminals, unless overridden. */ if (!overridden || !Py_FileSystemDefaultEncoding) { saved_locale = strdup(setlocale(LC_CTYPE, NULL)); setlocale(LC_CTYPE, ""); loc_codeset = nl_langinfo(CODESET); if (loc_codeset && *loc_codeset) { PyObject* enc = PyCodec_Encoder(loc_codeset); if (enc) { loc_codeset = strdup(loc_codeset); Py_DECREF(enc); } else { if (PyErr_ExceptionMatches(PyExc_LookupError)) { PyErr_Clear(); loc_codeset = NULL; } else { PyErr_Print(); exit(1); } } } else loc_codeset = NULL; setlocale(LC_CTYPE, saved_locale); free(saved_locale); if (!overridden) { codeset = icodeset = loc_codeset; free_codeset = 1; } /* Initialize Py_FileSystemDefaultEncoding from locale even if PYTHONIOENCODING is set. */ if (!Py_FileSystemDefaultEncoding) { Py_FileSystemDefaultEncoding = loc_codeset; if (!overridden) free_codeset = 0; } } #endif #ifdef MS_WINDOWS if (!overridden) { icodeset = ibuf; codeset = buf; sprintf(ibuf, "cp%d", GetConsoleCP()); sprintf(buf, "cp%d", GetConsoleOutputCP()); } #endif if (codeset) { sys_stream = PySys_GetObject("stdin"); sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); if ((overridden || (sys_isatty && PyObject_IsTrue(sys_isatty))) && PyFile_Check(sys_stream)) { if (!PyFile_SetEncodingAndErrors(sys_stream, icodeset, errors)) Py_FatalError("Cannot set codeset of stdin"); } Py_XDECREF(sys_isatty); sys_stream = PySys_GetObject("stdout"); sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); if ((overridden || (sys_isatty && PyObject_IsTrue(sys_isatty))) && PyFile_Check(sys_stream)) { if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) Py_FatalError("Cannot set codeset of stdout"); } Py_XDECREF(sys_isatty); sys_stream = PySys_GetObject("stderr"); sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); if ((overridden || (sys_isatty && PyObject_IsTrue(sys_isatty))) && PyFile_Check(sys_stream)) { if (!PyFile_SetEncodingAndErrors(sys_stream, codeset, errors)) Py_FatalError("Cannot set codeset of stderr"); } Py_XDECREF(sys_isatty); if (free_codeset) free(codeset); } }
void Py_Finalize(void) { PyInterpreterState *interp; PyThreadState *tstate; if (!initialized) return; /* The interpreter is still entirely intact at this point, and the * exit funcs may be relying on that. In particular, if some thread * or exit func is still waiting to do an import, the import machinery * expects Py_IsInitialized() to return true. So don't say the * interpreter is uninitialized until after the exit funcs have run. * Note that Threading.py uses an exit func to do a join on all the * threads created thru it, so this also protects pending imports in * the threads created via Threading. */ call_sys_exitfunc(); initialized = 0; /* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET(); interp = tstate->interp; /* Disable signal handling */ PyOS_FiniInterrupts(); /* drop module references we saved */ Py_XDECREF(warnings_module); warnings_module = NULL; /* Collect garbage. This may call finalizers; it's nice to call these * before all modules are destroyed. * XXX If a __del__ or weakref callback is triggered here, and tries to * XXX import a module, bad things can happen, because Python no * XXX longer believes it's initialized. * XXX Fatal Python error: Interpreter not initialized (version mismatch?) * XXX is easy to provoke that way. I've also seen, e.g., * XXX Exception exceptions.ImportError: 'No module named sha' * XXX in <function callback at 0x008F5718> ignored * XXX but I'm unclear on exactly how that one happens. In any case, * XXX I haven't seen a real-life report of either of these. */ PyGC_Collect(); #ifdef COUNT_ALLOCS /* With COUNT_ALLOCS, it helps to run GC multiple times: each collection might release some types from the type list, so they become garbage. */ while (PyGC_Collect() > 0) /* nothing */; #endif /* Destroy all modules */ PyImport_Cleanup(); /* Collect final garbage. This disposes of cycles created by * new-style class definitions, for example. * XXX This is disabled because it caused too many problems. If * XXX a __del__ or weakref callback triggers here, Python code has * XXX a hard time running, because even the sys module has been * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). * XXX One symptom is a sequence of information-free messages * XXX coming from threads (if a __del__ or callback is invoked, * XXX other threads can execute too, and any exception they encounter * XXX triggers a comedy of errors as subsystem after subsystem * XXX fails to find what it *expects* to find in sys to help report * XXX the exception and consequent unexpected failures). I've also * XXX seen segfaults then, after adding print statements to the * XXX Python code getting called. */ #if 0 PyGC_Collect(); #endif /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ _PyImport_Fini(); /* Debugging stuff */ #ifdef COUNT_ALLOCS dump_counts(stdout); #endif PRINT_TOTAL_REFS(); #ifdef Py_TRACE_REFS /* Display all objects still alive -- this can invoke arbitrary * __repr__ overrides, so requires a mostly-intact interpreter. * Alas, a lot of stuff may still be alive now that will be cleaned * up later. */ if (Py_GETENV("PYTHONDUMPREFS")) _Py_PrintReferences(stderr); #endif /* Py_TRACE_REFS */ /* Cleanup auto-thread-state */ #ifdef WITH_THREAD _PyGILState_Fini(); #endif /* WITH_THREAD */ /* Clear interpreter state */ PyInterpreterState_Clear(interp); /* Now we decref the exception classes. After this point nothing can raise an exception. That's okay, because each Fini() method below has been checked to make sure no exceptions are ever raised. */ _PyExc_Fini(); /* Delete current thread */ PyThreadState_Swap(NULL); PyInterpreterState_Delete(interp); /* Sundry finalizers */ PyMethod_Fini(); PyFrame_Fini(); PyCFunction_Fini(); PyTuple_Fini(); PyList_Fini(); PySet_Fini(); PyString_Fini(); PyInt_Fini(); PyFloat_Fini(); #ifdef Py_USING_UNICODE /* Cleanup Unicode implementation */ _PyUnicode_Fini(); #endif /* XXX Still allocated: - various static ad-hoc pointers to interned strings - int and float free list blocks - whatever various modules and libraries allocate */ PyGrammar_RemoveAccelerators(&_PyParser_Grammar); #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. * An address can be used to find the repr of the object, printed * above by _Py_PrintReferences. */ if (Py_GETENV("PYTHONDUMPREFS")) _Py_PrintReferenceAddresses(stderr); #endif /* Py_TRACE_REFS */ #ifdef PYMALLOC_DEBUG if (Py_GETENV("PYTHONMALLOCSTATS")) _PyObject_DebugMallocStats(); #endif call_ll_exitfuncs(); }
void Py_InitializeEx(int install_sigs) { PyInterpreterState *interp; PyThreadState *tstate; PyObject *bimod, *sysmod; char *p; #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) char *codeset; char *saved_locale; PyObject *sys_stream, *sys_isatty; #endif extern void _Py_ReadyTypes(void); if (initialized) return; initialized = 1; if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') Py_DebugFlag = add_flag(Py_DebugFlag, p); if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') Py_VerboseFlag = add_flag(Py_VerboseFlag, p); if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); interp = PyInterpreterState_New(); if (interp == NULL) Py_FatalError("Py_Initialize: can't make first interpreter"); tstate = PyThreadState_New(interp); if (tstate == NULL) Py_FatalError("Py_Initialize: can't make first thread"); (void) PyThreadState_Swap(tstate); _Py_ReadyTypes(); if (!_PyFrame_Init()) Py_FatalError("Py_Initialize: can't init frames"); if (!_PyInt_Init()) Py_FatalError("Py_Initialize: can't init ints"); _PyFloat_Init(); interp->modules = PyDict_New(); if (interp->modules == NULL) Py_FatalError("Py_Initialize: can't make modules dictionary"); interp->modules_reloading = PyDict_New(); if (interp->modules_reloading == NULL) Py_FatalError("Py_Initialize: can't make modules_reloading dictionary"); #ifdef Py_USING_UNICODE /* Init Unicode implementation; relies on the codec registry */ _PyUnicode_Init(); #endif bimod = _PyBuiltin_Init(); if (bimod == NULL) Py_FatalError("Py_Initialize: can't initialize __builtin__"); interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) Py_FatalError("Py_Initialize: can't initialize builtins dict"); Py_INCREF(interp->builtins); sysmod = _PySys_Init(); if (sysmod == NULL) Py_FatalError("Py_Initialize: can't initialize sys"); interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) Py_FatalError("Py_Initialize: can't initialize sys dict"); Py_INCREF(interp->sysdict); _PyImport_FixupExtension("sys", "sys"); PySys_SetPath(Py_GetPath()); PyDict_SetItemString(interp->sysdict, "modules", interp->modules); _PyImport_Init(); /* initialize builtin exceptions */ _PyExc_Init(); _PyImport_FixupExtension("exceptions", "exceptions"); /* phase 2 of builtins */ _PyImport_FixupExtension("__builtin__", "__builtin__"); _PyImportHooks_Init(); if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ initmain(); /* Module __main__ */ if (!Py_NoSiteFlag) initsite(); /* Module site */ /* auto-thread-state API, if available */ #ifdef WITH_THREAD _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ warnings_module = PyImport_ImportModule("warnings"); if (!warnings_module) PyErr_Clear(); #if defined(Py_USING_UNICODE) && defined(HAVE_LANGINFO_H) && defined(CODESET) /* On Unix, set the file system encoding according to the user's preference, if the CODESET names a well-known Python codec, and Py_FileSystemDefaultEncoding isn't initialized by other means. Also set the encoding of stdin and stdout if these are terminals. */ saved_locale = strdup(setlocale(LC_CTYPE, NULL)); setlocale(LC_CTYPE, ""); codeset = nl_langinfo(CODESET); if (codeset && *codeset) { PyObject *enc = PyCodec_Encoder(codeset); if (enc) { codeset = strdup(codeset); Py_DECREF(enc); } else { codeset = NULL; PyErr_Clear(); } } else codeset = NULL; setlocale(LC_CTYPE, saved_locale); free(saved_locale); if (codeset) { sys_stream = PySys_GetObject("stdin"); sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); if(sys_isatty && PyObject_IsTrue(sys_isatty) && PyFile_Check(sys_stream)) { if (!PyFile_SetEncoding(sys_stream, codeset)) Py_FatalError("Cannot set codeset of stdin"); } Py_XDECREF(sys_isatty); sys_stream = PySys_GetObject("stdout"); sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); if(sys_isatty && PyObject_IsTrue(sys_isatty) && PyFile_Check(sys_stream)) { if (!PyFile_SetEncoding(sys_stream, codeset)) Py_FatalError("Cannot set codeset of stdout"); } Py_XDECREF(sys_isatty); sys_stream = PySys_GetObject("stderr"); sys_isatty = PyObject_CallMethod(sys_stream, "isatty", ""); if (!sys_isatty) PyErr_Clear(); if(sys_isatty && PyObject_IsTrue(sys_isatty) && PyFile_Check(sys_stream)) { if (!PyFile_SetEncoding(sys_stream, codeset)) Py_FatalError("Cannot set codeset of stderr"); } Py_XDECREF(sys_isatty); if (!Py_FileSystemDefaultEncoding) Py_FileSystemDefaultEncoding = codeset; else free(codeset); } #endif }
static void calculate_path (void) { extern char *Py_GetProgramName(void); static char delimiter[2] = {DELIM, '\0'}; char *rtpypath = Py_GETENV("PYTHONPATH"); char *path = getenv("PATH"); char *prog = Py_GetProgramName(); static char proc_exe_path[] = "/proc/self/exe"; char *xzip_path; char *buf; /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); else if (path) { while (1) { char *delim = strchr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; strncpy(progpath, path, len); *(progpath + len) = '\0'; } else strncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = '\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if (progpath[0] != SEP && progpath[0] != '\0') absolutize(progpath); /**** pts ****/ { int fd = open(proc_exe_path, O_RDONLY); /* fprintf(stderr, "progpath=(%s)\n", progpath); */ if (fd < 0) { /* If /proc is not avaialbe, e.g. in chroot */ xzip_path = progpath; /* Use argv[0] for the .zip filename */ } else { xzip_path = proc_exe_path; close(fd); } } /**** pts ****/ if (rtpypath == NULL || rtpypath[0] == '\0') { module_search_path = xzip_path; } else if (NULL == (buf = (char *)PyMem_Malloc( 2 + strlen(xzip_path) + strlen(rtpypath)))) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = xzip_path; } else { strcpy(buf, rtpypath); strcat(buf, delimiter); strcat(buf, xzip_path); module_search_path = buf; } }
static void calculate_path(void) { extern wchar_t *Py_GetProgramName(void); static wchar_t delimiter[2] = {DELIM, '\0'}; static wchar_t separator[2] = {SEP, '\0'}; char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */ wchar_t rtpypath[MAXPATHLEN+1]; wchar_t *home = Py_GetPythonHome(); char *_path = getenv("PATH"); wchar_t *path_buffer = NULL; wchar_t *path = NULL; wchar_t *prog = Py_GetProgramName(); wchar_t argv0_path[MAXPATHLEN+1]; wchar_t zip_path[MAXPATHLEN+1]; int pfound, efound; /* 1 if found; -1 if found build directory */ wchar_t *buf; size_t bufsz; size_t prefixsz; wchar_t *defpath; #ifdef WITH_NEXT_FRAMEWORK NSModule pythonModule; #endif #ifdef __APPLE__ #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 uint32_t nsexeclength = MAXPATHLEN; #else unsigned long nsexeclength = MAXPATHLEN; #endif char execpath[MAXPATHLEN+1]; #endif wchar_t *_pythonpath, *_prefix, *_exec_prefix; _pythonpath = _Py_char2wchar(PYTHONPATH, NULL); _prefix = _Py_char2wchar(PREFIX, NULL); _exec_prefix = _Py_char2wchar(EXEC_PREFIX, NULL); if (!_pythonpath || !_prefix || !_exec_prefix) { Py_FatalError( "Unable to decode path variables in getpath.c: " "memory error"); } if (_path) { path_buffer = _Py_char2wchar(_path, NULL); path = path_buffer; } /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (wcschr(prog, SEP)) wcsncpy(progpath, prog, MAXPATHLEN); #ifdef __APPLE__ /* On Mac OS X, if a script uses an interpreter of the form * "#!/opt/python2.3/bin/python", the kernel only passes "python" * as argv[0], which falls through to the $PATH search below. * If /opt/python2.3/bin isn't in your path, or is near the end, * this algorithm may incorrectly find /usr/bin/python. To work * around this, we can use _NSGetExecutablePath to get a better * hint of what the intended interpreter was, although this * will fail if a relative path was used. but in that case, * absolutize() should help us out below */ else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) && execpath[0] == SEP) { size_t r = mbstowcs(progpath, execpath, MAXPATHLEN+1); if (r == (size_t)-1 || r > MAXPATHLEN) { /* Could not convert execpath, or it's too long. */ progpath[0] = '\0'; } } #endif /* __APPLE__ */ else if (path) { while (1) { wchar_t *delim = wcschr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; wcsncpy(progpath, path, len); *(progpath + len) = '\0'; } else wcsncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = L'\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if (path_buffer != NULL) PyMem_Free(path_buffer); if (progpath[0] != SEP && progpath[0] != '\0') absolutize(progpath); wcsncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; #ifdef WITH_NEXT_FRAMEWORK /* On Mac OS X we have a special case if we're running from a framework. ** This is because the python home should be set relative to the library, ** which is in the framework, not relative to the executable, which may ** be outside of the framework. Except when we're in the build directory... */ pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); /* Use dylib functions to find out where the framework was loaded from */ buf = (wchar_t *)NSLibraryNameForModule(pythonModule); if (buf != NULL) { /* We're in a framework. */ /* See if we might be in the build directory. The framework in the ** build directory is incomplete, it only has the .dylib and a few ** needed symlinks, it doesn't have the Lib directories and such. ** If we're running with the framework from the build directory we must ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ wcsncpy(argv0_path, buf, MAXPATHLEN); reduce(argv0_path); joinpath(argv0_path, lib_python); joinpath(argv0_path, LANDMARK); if (!ismodule(argv0_path)) { /* We are in the build directory so use the name of the executable - we know that the absolute path is passed */ wcsncpy(argv0_path, progpath, MAXPATHLEN); } else { /* Use the location of the library as the progpath */ wcsncpy(argv0_path, buf, MAXPATHLEN); } } #endif #if HAVE_READLINK { wchar_t tmpbuffer[MAXPATHLEN+1]; int linklen = _Py_wreadlink(progpath, tmpbuffer, MAXPATHLEN); while (linklen != -1) { if (tmpbuffer[0] == SEP) /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ wcsncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { /* Interpret relative to progpath */ reduce(argv0_path); joinpath(argv0_path, tmpbuffer); } linklen = _Py_wreadlink(argv0_path, tmpbuffer, MAXPATHLEN); } } #endif /* HAVE_READLINK */ reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ if (!(pfound = search_for_prefix(argv0_path, home, _prefix))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); wcsncpy(prefix, _prefix, MAXPATHLEN); joinpath(prefix, lib_python); } else reduce(prefix); wcsncpy(zip_path, prefix, MAXPATHLEN); zip_path[MAXPATHLEN] = L'\0'; if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */ reduce(zip_path); reduce(zip_path); } else wcsncpy(zip_path, _prefix, MAXPATHLEN); joinpath(zip_path, L"lib/python00.zip"); bufsz = wcslen(zip_path); /* Replace "00" with version */ zip_path[bufsz - 6] = VERSION[0]; zip_path[bufsz - 5] = VERSION[2]; if (!(efound = search_for_exec_prefix(argv0_path, home, _exec_prefix))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); joinpath(exec_prefix, L"lib/lib-dynload"); } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ if ((!pfound || !efound) && !Py_FrozenFlag) fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); /* Calculate size of return buffer. */ bufsz = 0; if (_rtpypath) { size_t s = mbstowcs(rtpypath, _rtpypath, sizeof(rtpypath)/sizeof(wchar_t)); if (s == (size_t)-1 || s >=sizeof(rtpypath)) /* XXX deal with errors more gracefully */ _rtpypath = NULL; if (_rtpypath) bufsz += wcslen(rtpypath) + 1; } defpath = _pythonpath; prefixsz = wcslen(prefix) + 1; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += wcslen(defpath) + 1; break; } defpath = delim + 1; } bufsz += wcslen(zip_path) + 1; bufsz += wcslen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = (wchar_t *)PyMem_Malloc(bufsz*sizeof(wchar_t)); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = L"" PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (_rtpypath) { wcscpy(buf, rtpypath); wcscat(buf, delimiter); } else buf[0] = '\0'; /* Next is the default zip path */ wcscat(buf, zip_path); wcscat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = _pythonpath; while (1) { wchar_t *delim = wcschr(defpath, DELIM); if (defpath[0] != SEP) { wcscat(buf, prefix); wcscat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = wcslen(buf) + len; wcsncat(buf, defpath, len); *(buf + end) = '\0'; } else { wcscat(buf, defpath); break; } defpath = delim + 1; } wcscat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ wcscat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ if (pfound > 0) { reduce(prefix); reduce(prefix); /* The prefix is the root directory, but reduce() chopped * off the "/". */ if (!prefix[0]) wcscpy(prefix, separator); } else wcsncpy(prefix, _prefix, MAXPATHLEN); if (efound > 0) { reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); if (!exec_prefix[0]) wcscpy(exec_prefix, separator); } else wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); PyMem_Free(_pythonpath); PyMem_Free(_prefix); PyMem_Free(_exec_prefix); }
/* Initialize sys.stdin, stdout, stderr and builtins.open */ static int initstdio(void) { PyObject *iomod = NULL, *wrapper; PyObject *bimod = NULL; PyObject *m; PyObject *std = NULL; int status = 0, fd; PyObject * encoding_attr; char *pythonioencoding = NULL, *encoding, *errors; /* Hack to avoid a nasty recursion issue when Python is invoked in verbose mode: pre-import the Latin-1 and UTF-8 codecs */ if ((m = PyImport_ImportModule("encodings.utf_8")) == NULL) { goto error; } Py_DECREF(m); if (!(m = PyImport_ImportModule("encodings.latin_1"))) { goto error; } Py_DECREF(m); if (!(bimod = PyImport_ImportModule("builtins"))) { goto error; } if (!(iomod = PyImport_ImportModule("io"))) { goto error; } if (!(wrapper = PyObject_GetAttrString(iomod, "OpenWrapper"))) { goto error; } /* Set builtins.open */ if (PyObject_SetAttrString(bimod, "open", wrapper) == -1) { Py_DECREF(wrapper); goto error; } Py_DECREF(wrapper); encoding = _Py_StandardStreamEncoding; errors = _Py_StandardStreamErrors; if (!encoding || !errors) { pythonioencoding = Py_GETENV("PYTHONIOENCODING"); if (pythonioencoding) { char *err; pythonioencoding = _PyMem_Strdup(pythonioencoding); if (pythonioencoding == NULL) { PyErr_NoMemory(); goto error; } err = strchr(pythonioencoding, ':'); if (err) { *err = '\0'; err++; if (*err && !errors) { errors = err; } } if (*pythonioencoding && !encoding) { encoding = pythonioencoding; } } if (!errors && !(pythonioencoding && *pythonioencoding)) { /* When the LC_CTYPE locale is the POSIX locale ("C locale"), stdin and stdout use the surrogateescape error handler by default, instead of the strict error handler. */ char *loc = setlocale(LC_CTYPE, NULL); if (loc != NULL && strcmp(loc, "C") == 0) errors = "surrogateescape"; } } /* Set sys.stdin */ fd = fileno(stdin); /* Under some conditions stdin, stdout and stderr may not be connected * and fileno() may point to an invalid file descriptor. For example * GUI apps don't have valid standard streams by default. */ std = create_stdio(iomod, fd, 0, "<stdin>", encoding, errors); if (std == NULL) goto error; PySys_SetObject("__stdin__", std); _PySys_SetObjectId(&PyId_stdin, std); Py_DECREF(std); /* Set sys.stdout */ fd = fileno(stdout); std = create_stdio(iomod, fd, 1, "<stdout>", encoding, errors); if (std == NULL) goto error; PySys_SetObject("__stdout__", std); _PySys_SetObjectId(&PyId_stdout, std); Py_DECREF(std); #if 1 /* Disable this if you have trouble debugging bootstrap stuff */ /* Set sys.stderr, replaces the preliminary stderr */ fd = fileno(stderr); std = create_stdio(iomod, fd, 1, "<stderr>", encoding, "backslashreplace"); if (std == NULL) goto error; /* Same as hack above, pre-import stderr's codec to avoid recursion when import.c tries to write to stderr in verbose mode. */ encoding_attr = PyObject_GetAttrString(std, "encoding"); if (encoding_attr != NULL) { const char * std_encoding; std_encoding = _PyUnicode_AsString(encoding_attr); if (std_encoding != NULL) { PyObject *codec_info = _PyCodec_Lookup(std_encoding); Py_XDECREF(codec_info); } Py_DECREF(encoding_attr); } PyErr_Clear(); /* Not a fatal error if codec isn't available */ if (PySys_SetObject("__stderr__", std) < 0) { Py_DECREF(std); goto error; } if (_PySys_SetObjectId(&PyId_stderr, std) < 0) { Py_DECREF(std); goto error; } Py_DECREF(std); #endif if (0) { error: status = -1; } /* We won't need them anymore. */ if (_Py_StandardStreamEncoding) { PyMem_RawFree(_Py_StandardStreamEncoding); _Py_StandardStreamEncoding = NULL; } if (_Py_StandardStreamErrors) { PyMem_RawFree(_Py_StandardStreamErrors); _Py_StandardStreamErrors = NULL; } PyMem_Free(pythonioencoding); Py_XDECREF(bimod); Py_XDECREF(iomod); return status; }
PyObject* initializePython2(const std::vector<char*>& commandLineArgsUtf8) #endif { //See https://developer.blender.org/T31507 //Python will not load anything in site-packages if this is set //We are sure that nothing in system wide site-packages is loaded, for instance on OS X with Python installed //through macports on the system, the following printf show the following: /*Py_GetProgramName is /Applications/Natron.app/Contents/MacOS/Natron Py_GetPrefix is /Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7 Py_GetExecPrefix is /Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7 Py_GetProgramFullPath is /Applications/Natron.app/Contents/MacOS/Natron Py_GetPath is /Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7:/Applications/Natron.app/Contents/MacOS/../Plugins:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python27.zip:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7/:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-old:/Applications/Natron.app/Contents/MacOS/../Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload Py_GetPythonHome is ../Frameworks/Python.framework/Versions/2.7/lib Python library is in /Applications/Natron.app/Contents/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages*/ //Py_NoSiteFlag = 1; ///////////////////////////////////////// // Py_SetProgramName ///////////////////////////////////////// // // Must be done before Py_Initialize (see doc of Py_Initialize) // #if PY_MAJOR_VERSION >= 3 // Python 3 Py_SetProgramName(commandLineArgsWide[0]); #else // Python 2 printf( "Py_SetProgramName(\"%s\")\n", commandLineArgsUtf8[0] ); Py_SetProgramName(commandLineArgsUtf8[0]); #endif ///////////////////////////////////////// // Py_Initialize ///////////////////////////////////////// // // Initialize the Python interpreter. In an application embedding Python, this should be called before using any other Python/C API functions; with the exception of Py_SetProgramName(), Py_SetPythonHome() and Py_SetPath(). #if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) printf("Py_Initialize()\n"); #endif Py_Initialize(); // pythonHome must be const, so that the c_str() pointer is never invalidated ///////////////////////////////////////// // PySys_SetArgv ///////////////////////////////////////// // #if PY_MAJOR_VERSION >= 3 // Python 3 PySys_SetArgv( commandLineArgsWide.size(), const_cast<wchar_t**>(&commandLineArgsWide[0]) ); /// relative module import #else // Python 2 PySys_SetArgv( commandLineArgsUtf8.size(), const_cast<char**>(&commandLineArgsUtf8[0]) ); /// relative module import #endif PyObject* mainModule = PyImport_ImportModule("__main__"); //create main module , new ref //See http://wiki.blender.org/index.php/Dev:2.4/Source/Python/API/Threads //Python releases the GIL every 100 virtual Python instructions, we do not want that to happen in the middle of an expression. //_PyEval_SetSwitchInterval(LONG_MAX); //See answer for http://stackoverflow.com/questions/15470367/pyeval-initthreads-in-python-3-how-when-to-call-it-the-saga-continues-ad-naus PyEval_InitThreads(); ///Do as per http://wiki.blender.org/index.php/Dev:2.4/Source/Python/API/Threads ///All calls to the Python API should call PythonGILLocker beforehand. //_imp->mainThreadState = PyGILState_GetThisThreadState(); //PyEval_ReleaseThread(_imp->mainThreadState); std::string err; #if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG) /// print info about python lib { printf( "PATH is %s\n", Py_GETENV("PATH") ); printf( "PYTHONPATH is %s\n", Py_GETENV("PYTHONPATH") ); printf( "PYTHONHOME is %s\n", Py_GETENV("PYTHONHOME") ); printf( "Py_DebugFlag is %d\n", Py_DebugFlag ); printf( "Py_VerboseFlag is %d\n", Py_VerboseFlag ); printf( "Py_InteractiveFlag is %d\n", Py_InteractiveFlag ); printf( "Py_InspectFlag is %d\n", Py_InspectFlag ); printf( "Py_OptimizeFlag is %d\n", Py_OptimizeFlag ); printf( "Py_NoSiteFlag is %d\n", Py_NoSiteFlag ); printf( "Py_BytesWarningFlag is %d\n", Py_BytesWarningFlag ); printf( "Py_UseClassExceptionsFlag is %d\n", Py_UseClassExceptionsFlag ); printf( "Py_FrozenFlag is %d\n", Py_FrozenFlag ); printf( "Py_TabcheckFlag is %d\n", Py_TabcheckFlag ); printf( "Py_UnicodeFlag is %d\n", Py_UnicodeFlag ); printf( "Py_IgnoreEnvironmentFlag is %d\n", Py_IgnoreEnvironmentFlag ); printf( "Py_DivisionWarningFlag is %d\n", Py_DivisionWarningFlag ); printf( "Py_DontWriteBytecodeFlag is %d\n", Py_DontWriteBytecodeFlag ); printf( "Py_NoUserSiteDirectory is %d\n", Py_NoUserSiteDirectory ); printf( "Py_GetProgramName is %s\n", Py_GetProgramName() ); printf( "Py_GetPrefix is %s\n", Py_GetPrefix() ); printf( "Py_GetExecPrefix is %s\n", Py_GetPrefix() ); printf( "Py_GetProgramFullPath is %s\n", Py_GetProgramFullPath() ); printf( "Py_GetPath is %s\n", Py_GetPath() ); printf( "Py_GetPythonHome is %s\n", Py_GetPythonHome() ); PyObject* dict = PyModule_GetDict(mainModule); ///This is faster than PyRun_SimpleString since is doesn't call PyImport_AddModule("__main__") std::string script("from distutils.sysconfig import get_python_lib; print('Python library is in ' + get_python_lib())"); PyObject* v = PyRun_String(script.c_str(), Py_file_input, dict, 0); if (v) { Py_DECREF(v); } } #endif return mainModule; } // initializePython
int Py_FrozenMain(int argc, char **argv) { _PyInitError err = _PyRuntime_Initialize(); if (_Py_INIT_FAILED(err)) { fprintf(stderr, "Fatal Python error: %s\n", err.msg); fflush(stderr); exit(1); } const char *p; int i, n, sts = 1; int inspect = 0; int unbuffered = 0; char *oldloc = NULL; wchar_t **argv_copy = NULL; /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; if (argc > 0) { argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); goto error; } } _PyCoreConfig config = _PyCoreConfig_INIT; config._frozen = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); goto error; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = Py_DecodeLocale(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", i + 1); argc = i; goto error; } } setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); oldloc = NULL; #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ if (argc >= 1) Py_SetProgramName(argv_copy[0]); err = _Py_InitializeFromConfig(&config); /* No need to call _PyCoreConfig_Clear() since we didn't allocate any memory: program_name is a constant string. */ if (_Py_INIT_FAILED(err)) { _Py_FatalInitError(err); } #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv_copy); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif if (Py_FinalizeEx() < 0) { sts = 120; } error: PyMem_RawFree(argv_copy); if (argv_copy2) { for (i = 0; i < argc; i++) PyMem_RawFree(argv_copy2[i]); PyMem_RawFree(argv_copy2); } PyMem_RawFree(oldloc); return sts; }
int Py_FrozenMain(int argc, char **argv) { char *p; int i, n, sts; int inspect = 0; int unbuffered = 0; char *oldloc; wchar_t **argv_copy = PyMem_Malloc(sizeof(wchar_t*)*argc); /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = PyMem_Malloc(sizeof(wchar_t*)*argc); Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } if (!argv_copy) { fprintf(stderr, "out of memory\n"); return 1; } oldloc = setlocale(LC_ALL, NULL); setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { #ifdef HAVE_BROKEN_MBSTOWCS size_t argsize = strlen(argv[i]); #else size_t argsize = mbstowcs(NULL, argv[i], 0); #endif size_t count; if (argsize == (size_t)-1) { fprintf(stderr, "Could not convert argument %d to string\n", i); return 1; } argv_copy[i] = PyMem_Malloc((argsize+1)*sizeof(wchar_t)); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "out of memory\n"); return 1; } count = mbstowcs(argv_copy[i], argv[i], argsize+1); if (count == (size_t)-1) { fprintf(stderr, "Could not convert argument %d to string\n", i); return 1; } } setlocale(LC_ALL, oldloc); #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ Py_SetProgramName(argv_copy[0]); Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv_copy); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif Py_Finalize(); for (i = 0; i < argc; i++) { PyMem_Free(argv_copy2[i]); } PyMem_Free(argv_copy); PyMem_Free(argv_copy2); return sts; }
int Py_FrozenMain(int argc, char **argv) { char *p; int i, n, sts = 1; int inspect = 0; int unbuffered = 0; char *oldloc = NULL; wchar_t **argv_copy = NULL; /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; argv_copy = PyMem_RawMalloc(sizeof(wchar_t*) * argc); argv_copy2 = PyMem_RawMalloc(sizeof(wchar_t*) * argc); if (!argv_copy || !argv_copy2) { fprintf(stderr, "out of memory\n"); goto error; } Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } oldloc = _PyMem_RawStrdup(setlocale(LC_ALL, NULL)); if (!oldloc) { fprintf(stderr, "out of memory\n"); goto error; } setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = _Py_char2wchar(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", i + 1); argc = i; goto error; } } setlocale(LC_ALL, oldloc); PyMem_RawFree(oldloc); oldloc = NULL; #ifdef MS_WINDOWS PyInitFrozenExtensions(); #endif /* MS_WINDOWS */ Py_SetProgramName(argv_copy[0]); Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); PySys_SetArgv(argc, argv_copy); n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif Py_Finalize(); error: PyMem_RawFree(argv_copy); if (argv_copy2) { for (i = 0; i < argc; i++) PyMem_RawFree(argv_copy2[i]); PyMem_RawFree(argv_copy2); } PyMem_RawFree(oldloc); return sts; }
static void calculate_path(void) { extern char *Py_GetProgramName(void); static char delimiter[2] = {DELIM, '\0'}; static char separator[2] = {SEP, '\0'}; char *pythonpath = PYTHONPATH; char *rtpypath = Py_GETENV("PYTHONPATH"); char *home = Py_GetPythonHome(); char *path = getenv("PATH"); char *prog = Py_GetProgramName(); char argv0_path[MAXPATHLEN+1]; char zip_path[MAXPATHLEN+1]; int pfound, efound; /* 1 if found; -1 if found build directory */ char *buf; size_t bufsz; size_t prefixsz; char *defpath = pythonpath; #ifdef WITH_NEXT_FRAMEWORK NSModule pythonModule; #endif /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); else if (path) { while (1) { char *delim = strchr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; strncpy(progpath, path, len); *(progpath + len) = '\0'; } else strncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = '\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if (progpath[0] != SEP) absolutize(progpath); strncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; #ifdef WITH_NEXT_FRAMEWORK /* On Mac OS X we have a special case if we're running from a framework. ** This is because the python home should be set relative to the library, ** which is in the framework, not relative to the executable, which may ** be outside of the framework. Except when we're in the build directory... */ pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); /* Use dylib functions to find out where the framework was loaded from */ buf = (char *)NSLibraryNameForModule(pythonModule); if (buf != NULL) { /* We're in a framework. */ /* See if we might be in the build directory. The framework in the ** build directory is incomplete, it only has the .dylib and a few ** needed symlinks, it doesn't have the Lib directories and such. ** If we're running with the framework from the build directory we must ** be running the interpreter in the build directory, so we use the ** build-directory-specific logic to find Lib and such. */ strncpy(argv0_path, buf, MAXPATHLEN); reduce(argv0_path); joinpath(argv0_path, lib_python); joinpath(argv0_path, LANDMARK); if (!ismodule(argv0_path)) { /* We are in the build directory so use the name of the executable - we know that the absolute path is passed */ strncpy(argv0_path, prog, MAXPATHLEN); } else { /* Use the location of the library as the progpath */ strncpy(argv0_path, buf, MAXPATHLEN); } } #endif #if HAVE_READLINK { char tmpbuffer[MAXPATHLEN+1]; int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN); while (linklen != -1) { /* It's not null terminated! */ tmpbuffer[linklen] = '\0'; if (tmpbuffer[0] == SEP) /* tmpbuffer should never be longer than MAXPATHLEN, but extra check does not hurt */ strncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { /* Interpret relative to progpath */ reduce(argv0_path); joinpath(argv0_path, tmpbuffer); } linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN); } } #endif /* HAVE_READLINK */ reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ if (!(pfound = search_for_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform independent libraries <prefix>\n"); strncpy(prefix, PREFIX, MAXPATHLEN); joinpath(prefix, lib_python); } else reduce(prefix); strncpy(zip_path, prefix, MAXPATHLEN); zip_path[MAXPATHLEN] = '\0'; if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */ reduce(zip_path); reduce(zip_path); } else strncpy(zip_path, PREFIX, MAXPATHLEN); joinpath(zip_path, "lib/python00.zip"); bufsz = strlen(zip_path); /* Replace "00" with version */ zip_path[bufsz - 6] = VERSION[0]; zip_path[bufsz - 5] = VERSION[2]; if (!(efound = search_for_exec_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, "Could not find platform dependent libraries <exec_prefix>\n"); strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); joinpath(exec_prefix, "lib/lib-dynload"); } /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ if ((!pfound || !efound) && !Py_FrozenFlag) fprintf(stderr, "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); /* Calculate size of return buffer. */ bufsz = 0; if (rtpypath) bufsz += strlen(rtpypath) + 1; prefixsz = strlen(prefix) + 1; while (1) { char *delim = strchr(defpath, DELIM); if (defpath[0] != SEP) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += strlen(defpath) + 1; break; } defpath = delim + 1; } bufsz += strlen(zip_path) + 1; bufsz += strlen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = PyMem_Malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (rtpypath) { strcpy(buf, rtpypath); strcat(buf, delimiter); } else buf[0] = '\0'; /* Next is the default zip path */ strcat(buf, zip_path); strcat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = pythonpath; while (1) { char *delim = strchr(defpath, DELIM); if (defpath[0] != SEP) { strcat(buf, prefix); strcat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = strlen(buf) + len; strncat(buf, defpath, len); *(buf + end) = '\0'; } else { strcat(buf, defpath); break; } defpath = delim + 1; } strcat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ strcat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ if (pfound > 0) { reduce(prefix); reduce(prefix); } else strncpy(prefix, PREFIX, MAXPATHLEN); if (efound > 0) { reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); } else strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); }
static void calculate_path(void) { char argv0_path[MAXPATHLEN+1]; char *buf; size_t bufsz; char *pythonhome = Py_GetPythonHome(); char *envpath = Py_GETENV("PYTHONPATH"); #ifdef MS_WINDOWS int skiphome, skipdefault; char *machinepath = NULL; char *userpath = NULL; char zip_path[MAXPATHLEN+1]; size_t len; #endif get_progpath(); /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */ strcpy(argv0_path, progpath); reduce(argv0_path); if (pythonhome == NULL || *pythonhome == '\0') { if (search_for_prefix(argv0_path, LANDMARK)) pythonhome = prefix; else pythonhome = NULL; } else strncpy(prefix, pythonhome, MAXPATHLEN); if (envpath && *envpath == '\0') envpath = NULL; #ifdef MS_WINDOWS /* Calculate zip archive path */ if (dllpath[0]) /* use name of python DLL */ strncpy(zip_path, dllpath, MAXPATHLEN); else /* use name of executable program */ strncpy(zip_path, progpath, MAXPATHLEN); zip_path[MAXPATHLEN] = '\0'; len = strlen(zip_path); if (len > 4) { zip_path[len-3] = 'z'; /* change ending to "zip" */ zip_path[len-2] = 'i'; zip_path[len-1] = 'p'; } else { zip_path[0] = 0; } skiphome = pythonhome==NULL ? 0 : 1; #ifdef Py_ENABLE_SHARED machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome); userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome); #endif /* We only use the default relative PYTHONPATH if we havent anything better to use! */ skipdefault = envpath!=NULL || pythonhome!=NULL || \ machinepath!=NULL || userpath!=NULL; #endif /* We need to construct a path from the following parts. (1) the PYTHONPATH environment variable, if set; (2) for Win32, the zip archive file path; (3) for Win32, the machinepath and userpath, if set; (4) the PYTHONPATH config macro, with the leading "." of each component replaced with pythonhome, if set; (5) the directory containing the executable (argv0_path). The length calculation calculates #4 first. Extra rules: - If PYTHONHOME is set (in any way) item (3) is ignored. - If registry values are used, (4) and (5) are ignored. */ /* Calculate size of return buffer */ if (pythonhome != NULL) { char *p; bufsz = 1; for (p = PYTHONPATH; *p; p++) { if (*p == DELIM) bufsz++; /* number of DELIM plus one */ } bufsz *= strlen(pythonhome); } else bufsz = 0; bufsz += strlen(PYTHONPATH) + 1; bufsz += strlen(argv0_path) + 1; #ifdef MS_WINDOWS if (userpath) bufsz += strlen(userpath) + 1; if (machinepath) bufsz += strlen(machinepath) + 1; bufsz += strlen(zip_path) + 1; #endif if (envpath != NULL) bufsz += strlen(envpath) + 1; module_search_path = buf = malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n"); if (envpath) { fprintf(stderr, "Using environment $PYTHONPATH.\n"); module_search_path = envpath; } else { fprintf(stderr, "Using default static path.\n"); module_search_path = PYTHONPATH; } #ifdef MS_WINDOWS if (machinepath) free(machinepath); if (userpath) free(userpath); #endif /* MS_WINDOWS */ return; } if (envpath) { strcpy(buf, envpath); buf = strchr(buf, '\0'); *buf++ = DELIM; } #ifdef MS_WINDOWS if (zip_path[0]) { strcpy(buf, zip_path); buf = strchr(buf, '\0'); *buf++ = DELIM; } if (userpath) { strcpy(buf, userpath); buf = strchr(buf, '\0'); *buf++ = DELIM; free(userpath); } if (machinepath) { strcpy(buf, machinepath); buf = strchr(buf, '\0'); *buf++ = DELIM; free(machinepath); } if (pythonhome == NULL) { if (!skipdefault) { strcpy(buf, PYTHONPATH); buf = strchr(buf, '\0'); } } #else if (pythonhome == NULL) { strcpy(buf, PYTHONPATH); buf = strchr(buf, '\0'); } #endif /* MS_WINDOWS */ else { char *p = PYTHONPATH; char *q; size_t n; for (;;) { q = strchr(p, DELIM); if (q == NULL) n = strlen(p); else n = q-p; if (p[0] == '.' && is_sep(p[1])) { strcpy(buf, pythonhome); buf = strchr(buf, '\0'); p++; n--; } strncpy(buf, p, n); buf += n; if (q == NULL) break; *buf++ = DELIM; p = q+1; } } if (argv0_path) { *buf++ = DELIM; strcpy(buf, argv0_path); buf = strchr(buf, '\0'); } *buf = '\0'; /* Now to pull one last hack/trick. If sys.prefix is empty, then try and find it somewhere on the paths we calculated. We scan backwards, as our general policy is that Python core directories are at the *end* of sys.path. We assume that our "lib" directory is on the path, and that our 'prefix' directory is the parent of that. */ if (*prefix=='\0') { char lookBuf[MAXPATHLEN+1]; char *look = buf - 1; /* 'buf' is at the end of the buffer */ while (1) { Py_ssize_t nchars; char *lookEnd = look; /* 'look' will end up one character before the start of the path in question - even if this is one character before the start of the buffer */ while (look >= module_search_path && *look != DELIM) look--; nchars = lookEnd-look; strncpy(lookBuf, look+1, nchars); lookBuf[nchars] = '\0'; /* Up one level to the parent */ reduce(lookBuf); if (search_for_prefix(lookBuf, LANDMARK)) { break; } /* If we are out of paths to search - give up */ if (look < module_search_path) break; look--; } } }
void _Py_InitializeEx_Private(int install_sigs, int install_importlib) { PyInterpreterState *interp; PyThreadState *tstate; PyObject *bimod, *sysmod, *pstderr; char *p; extern void _Py_ReadyTypes(void); if (initialized) return; initialized = 1; _Py_Finalizing = NULL; #if defined(HAVE_LANGINFO_H) && defined(HAVE_SETLOCALE) /* Set up the LC_CTYPE locale, so we can obtain the locale's charset without having to switch locales. */ setlocale(LC_CTYPE, ""); #endif if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') Py_DebugFlag = add_flag(Py_DebugFlag, p); if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0') Py_VerboseFlag = add_flag(Py_VerboseFlag, p); if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0') Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); /* The variable is only tested for existence here; _PyRandom_Init will check its value further. */ if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0') Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p); _PyRandom_Init(); interp = PyInterpreterState_New(); if (interp == NULL) Py_FatalError("Py_Initialize: can't make first interpreter"); tstate = PyThreadState_New(interp); if (tstate == NULL) Py_FatalError("Py_Initialize: can't make first thread"); (void) PyThreadState_Swap(tstate); #ifdef WITH_THREAD /* We can't call _PyEval_FiniThreads() in Py_FinalizeEx because destroying the GIL might fail when it is being referenced from another running thread (see issue #9901). Instead we destroy the previously created GIL here, which ensures that we can call Py_Initialize / Py_FinalizeEx multiple times. */ _PyEval_FiniThreads(); /* Auto-thread-state API */ _PyGILState_Init(interp, tstate); #endif /* WITH_THREAD */ _Py_ReadyTypes(); if (!_PyFrame_Init()) Py_FatalError("Py_Initialize: can't init frames"); if (!_PyLong_Init()) Py_FatalError("Py_Initialize: can't init longs"); if (!PyByteArray_Init()) Py_FatalError("Py_Initialize: can't init bytearray"); if (!_PyFloat_Init()) Py_FatalError("Py_Initialize: can't init float"); interp->modules = PyDict_New(); if (interp->modules == NULL) Py_FatalError("Py_Initialize: can't make modules dictionary"); /* Init Unicode implementation; relies on the codec registry */ if (_PyUnicode_Init() < 0) Py_FatalError("Py_Initialize: can't initialize unicode"); if (_PyStructSequence_Init() < 0) Py_FatalError("Py_Initialize: can't initialize structseq"); bimod = _PyBuiltin_Init(); if (bimod == NULL) Py_FatalError("Py_Initialize: can't initialize builtins modules"); _PyImport_FixupBuiltin(bimod, "builtins"); interp->builtins = PyModule_GetDict(bimod); if (interp->builtins == NULL) Py_FatalError("Py_Initialize: can't initialize builtins dict"); Py_INCREF(interp->builtins); /* initialize builtin exceptions */ _PyExc_Init(bimod); sysmod = _PySys_Init(); if (sysmod == NULL) Py_FatalError("Py_Initialize: can't initialize sys"); interp->sysdict = PyModule_GetDict(sysmod); if (interp->sysdict == NULL) Py_FatalError("Py_Initialize: can't initialize sys dict"); Py_INCREF(interp->sysdict); _PyImport_FixupBuiltin(sysmod, "sys"); PySys_SetPath(Py_GetPath()); PyDict_SetItemString(interp->sysdict, "modules", interp->modules); /* Set up a preliminary stderr printer until we have enough infrastructure for the io module in place. */ pstderr = PyFile_NewStdPrinter(fileno(stderr)); if (pstderr == NULL) Py_FatalError("Py_Initialize: can't set preliminary stderr"); _PySys_SetObjectId(&PyId_stderr, pstderr); PySys_SetObject("__stderr__", pstderr); Py_DECREF(pstderr); _PyImport_Init(); _PyImportHooks_Init(); /* Initialize _warnings. */ _PyWarnings_Init(); if (!install_importlib) return; if (_PyTime_Init() < 0) Py_FatalError("Py_Initialize: can't initialize time"); import_init(interp, sysmod); /* initialize the faulthandler module */ if (_PyFaulthandler_Init()) Py_FatalError("Py_Initialize: can't initialize faulthandler"); if (initfsencoding(interp) < 0) Py_FatalError("Py_Initialize: unable to load the file system codec"); if (install_sigs) initsigs(); /* Signal handling stuff, including initintr() */ if (_PyTraceMalloc_Init() < 0) Py_FatalError("Py_Initialize: can't initialize tracemalloc"); initmain(interp); /* Module __main__ */ if (initstdio() < 0) Py_FatalError( "Py_Initialize: can't initialize sys standard streams"); /* Initialize warnings. */ if (PySys_HasWarnOptions()) { PyObject *warnings_module = PyImport_ImportModule("warnings"); if (warnings_module == NULL) { fprintf(stderr, "'import warnings' failed; traceback:\n"); PyErr_Print(); } Py_XDECREF(warnings_module); } if (!Py_NoSiteFlag) initsite(); /* Module site */ }
int Py_FinalizeEx(void) { PyInterpreterState *interp; PyThreadState *tstate; int status = 0; if (!initialized) return status; wait_for_thread_shutdown(); /* The interpreter is still entirely intact at this point, and the * exit funcs may be relying on that. In particular, if some thread * or exit func is still waiting to do an import, the import machinery * expects Py_IsInitialized() to return true. So don't say the * interpreter is uninitialized until after the exit funcs have run. * Note that Threading.py uses an exit func to do a join on all the * threads created thru it, so this also protects pending imports in * the threads created via Threading. */ call_py_exitfuncs(); /* Get current thread state and interpreter pointer */ tstate = PyThreadState_GET(); interp = tstate->interp; /* Remaining threads (e.g. daemon threads) will automatically exit after taking the GIL (in PyEval_RestoreThread()). */ _Py_Finalizing = tstate; initialized = 0; /* Flush sys.stdout and sys.stderr */ if (flush_std_files() < 0) { status = -1; } /* Disable signal handling */ PyOS_FiniInterrupts(); /* Collect garbage. This may call finalizers; it's nice to call these * before all modules are destroyed. * XXX If a __del__ or weakref callback is triggered here, and tries to * XXX import a module, bad things can happen, because Python no * XXX longer believes it's initialized. * XXX Fatal Python error: Interpreter not initialized (version mismatch?) * XXX is easy to provoke that way. I've also seen, e.g., * XXX Exception exceptions.ImportError: 'No module named sha' * XXX in <function callback at 0x008F5718> ignored * XXX but I'm unclear on exactly how that one happens. In any case, * XXX I haven't seen a real-life report of either of these. */ PyGC_Collect(); #ifdef COUNT_ALLOCS /* With COUNT_ALLOCS, it helps to run GC multiple times: each collection might release some types from the type list, so they become garbage. */ while (PyGC_Collect() > 0) /* nothing */; #endif /* Destroy all modules */ PyImport_Cleanup(); /* Flush sys.stdout and sys.stderr (again, in case more was printed) */ if (flush_std_files() < 0) { status = -1; } /* Collect final garbage. This disposes of cycles created by * class definitions, for example. * XXX This is disabled because it caused too many problems. If * XXX a __del__ or weakref callback triggers here, Python code has * XXX a hard time running, because even the sys module has been * XXX cleared out (sys.stdout is gone, sys.excepthook is gone, etc). * XXX One symptom is a sequence of information-free messages * XXX coming from threads (if a __del__ or callback is invoked, * XXX other threads can execute too, and any exception they encounter * XXX triggers a comedy of errors as subsystem after subsystem * XXX fails to find what it *expects* to find in sys to help report * XXX the exception and consequent unexpected failures). I've also * XXX seen segfaults then, after adding print statements to the * XXX Python code getting called. */ #if 0 PyGC_Collect(); #endif /* Disable tracemalloc after all Python objects have been destroyed, so it is possible to use tracemalloc in objects destructor. */ _PyTraceMalloc_Fini(); /* Destroy the database used by _PyImport_{Fixup,Find}Extension */ _PyImport_Fini(); /* Cleanup typeobject.c's internal caches. */ _PyType_Fini(); /* unload faulthandler module */ _PyFaulthandler_Fini(); /* Debugging stuff */ #ifdef COUNT_ALLOCS dump_counts(stderr); #endif /* dump hash stats */ _PyHash_Fini(); _PY_DEBUG_PRINT_TOTAL_REFS(); #ifdef Py_TRACE_REFS /* Display all objects still alive -- this can invoke arbitrary * __repr__ overrides, so requires a mostly-intact interpreter. * Alas, a lot of stuff may still be alive now that will be cleaned * up later. */ if (Py_GETENV("PYTHONDUMPREFS")) _Py_PrintReferences(stderr); #endif /* Py_TRACE_REFS */ /* Clear interpreter state and all thread states. */ PyInterpreterState_Clear(interp); /* Now we decref the exception classes. After this point nothing can raise an exception. That's okay, because each Fini() method below has been checked to make sure no exceptions are ever raised. */ _PyExc_Fini(); /* Sundry finalizers */ PyMethod_Fini(); PyFrame_Fini(); PyCFunction_Fini(); PyTuple_Fini(); PyList_Fini(); PySet_Fini(); PyBytes_Fini(); PyByteArray_Fini(); PyLong_Fini(); PyFloat_Fini(); PyDict_Fini(); PySlice_Fini(); _PyGC_Fini(); _PyRandom_Fini(); _PyArg_Fini(); /* Cleanup Unicode implementation */ _PyUnicode_Fini(); /* reset file system default encoding */ if (!Py_HasFileSystemDefaultEncoding && Py_FileSystemDefaultEncoding) { PyMem_RawFree((char*)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = NULL; } /* XXX Still allocated: - various static ad-hoc pointers to interned strings - int and float free list blocks - whatever various modules and libraries allocate */ PyGrammar_RemoveAccelerators(&_PyParser_Grammar); /* Cleanup auto-thread-state */ #ifdef WITH_THREAD _PyGILState_Fini(); #endif /* WITH_THREAD */ /* Delete current thread. After this, many C API calls become crashy. */ PyThreadState_Swap(NULL); PyInterpreterState_Delete(interp); #ifdef Py_TRACE_REFS /* Display addresses (& refcnts) of all objects still alive. * An address can be used to find the repr of the object, printed * above by _Py_PrintReferences. */ if (Py_GETENV("PYTHONDUMPREFS")) _Py_PrintReferenceAddresses(stderr); #endif /* Py_TRACE_REFS */ #ifdef WITH_PYMALLOC if (_PyMem_PymallocEnabled()) { char *opt = Py_GETENV("PYTHONMALLOCSTATS"); if (opt != NULL && *opt != '\0') _PyObject_DebugMallocStats(stderr); } #endif call_ll_exitfuncs(); return status; }
/** Determine paths. Two directories must be found, the platform independent directory (prefix), containing the common .py and .pyc files, and the platform dependent directory (exec_prefix), containing the shared library modules. Note that prefix and exec_prefix are the same directory for UEFI installations. Separate searches are carried out for prefix and exec_prefix. Each search tries a number of different locations until a ``landmark'' file or directory is found. If no prefix or exec_prefix is found, a warning message is issued and the preprocessor defined PREFIX and EXEC_PREFIX are used (even though they may not work); python carries on as best as is possible, but some imports may fail. Before any searches are done, the location of the executable is determined. If argv[0] has one or more slashes in it, it is used unchanged. Otherwise, it must have been invoked from the shell's path, so we search %PATH% for the named executable and use that. If the executable was not found on %PATH% (or there was no %PATH% environment variable), the original argv[0] string is used. Finally, argv0_path is set to the directory containing the executable (i.e. the last component is stripped). With argv0_path in hand, we perform a number of steps. The same steps are performed for prefix and for exec_prefix, but with a different landmark. The prefix landmark will always be lib/python.VERSION/os.py and the exec_prefix will always be lib/python.VERSION/dynaload, where VERSION is Python's version number as defined at the beginning of this file. First. See if the %PYTHONHOME% environment variable points to the installed location of the Python libraries. If %PYTHONHOME% is set, then it points to prefix and exec_prefix. %PYTHONHOME% can be a single directory, which is used for both, or the prefix and exec_prefix directories separated by the DELIM character. Next. Search the directories pointed to by the preprocessor variables PREFIX and EXEC_PREFIX. These paths are prefixed with the volume name extracted from argv0_path. The volume names correspond to the UEFI shell "map" names. That's it! Well, almost. Once we have determined prefix and exec_prefix, the preprocessor variable PYTHONPATH is used to construct a path. Each relative path on PYTHONPATH is prefixed with prefix. Then the directory containing the shared library modules is appended. The environment variable $PYTHONPATH is inserted in front of it all. Finally, the prefix and exec_prefix globals are tweaked so they reflect the values expected by other code, by stripping the "lib/python$VERSION/..." stuff off. This seems to make more sense given that currently the only known use of sys.prefix and sys.exec_prefix is for the ILU installation process to find the installed Python tree. The final, fully resolved, paths should look something like: fs0:/Efi/Tools/python.efi fs0:/Efi/StdLib/lib/python27 fs0:/Efi/StdLib/lib/python27/dynaload **/ static void calculate_path(void) { extern char *Py_GetProgramName(void); static char delimiter[2] = {DELIM, '\0'}; static char separator[2] = {SEP, '\0'}; char *pythonpath = PYTHONPATH; char *rtpypath = Py_GETENV("PYTHONPATH"); //char *home = Py_GetPythonHome(); char *path = getenv("path"); char *prog = Py_GetProgramName(); char argv0_path[MAXPATHLEN+1]; char zip_path[MAXPATHLEN+1]; char *buf; size_t bufsz; size_t prefixsz; char *defpath; /* ########################################################################### Determine path to the Python.efi binary. Produces progpath, argv0_path, and volume_name. ########################################################################### */ /* If there is no slash in the argv0 path, then we have to * assume python is on the user's $PATH, since there's no * other way to find a directory to start the search from. If * $PATH isn't exported, you lose. */ if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); else if (path) { while (1) { char *delim = strchr(path, DELIM); if (delim) { size_t len = delim - path; if (len > MAXPATHLEN) len = MAXPATHLEN; strncpy(progpath, path, len); *(progpath + len) = '\0'; } else strncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); if (isxfile(progpath)) break; if (!delim) { progpath[0] = '\0'; break; } path = delim + 1; } } else progpath[0] = '\0'; if ( (!is_absolute(progpath)) && (progpath[0] != '\0') ) absolutize(progpath); strncpy(argv0_path, progpath, MAXPATHLEN); argv0_path[MAXPATHLEN] = '\0'; set_volume(volume_name, argv0_path); reduce(argv0_path); /* At this point, argv0_path is guaranteed to be less than MAXPATHLEN bytes long. */ /* ########################################################################### Build the FULL prefix string, including volume name. This is the full path to the platform independent libraries. ########################################################################### */ strncpy(prefix, volume_name, MAXPATHLEN); joinpath(prefix, PREFIX); joinpath(prefix, lib_python); /* ########################################################################### Build the FULL path to the zipped-up Python library. ########################################################################### */ strncpy(zip_path, prefix, MAXPATHLEN); zip_path[MAXPATHLEN] = '\0'; reduce(zip_path); joinpath(zip_path, "python00.zip"); bufsz = strlen(zip_path); /* Replace "00" with version */ zip_path[bufsz - 6] = VERSION[0]; zip_path[bufsz - 5] = VERSION[1]; /* ########################################################################### Build the FULL path to dynamically loadable libraries. ########################################################################### */ strncpy(exec_prefix, volume_name, MAXPATHLEN); // "fs0:" joinpath(exec_prefix, EXEC_PREFIX); // "fs0:/Efi/StdLib" joinpath(exec_prefix, lib_python); // "fs0:/Efi/StdLib/lib/python.27" joinpath(exec_prefix, "lib-dynload"); // "fs0:/Efi/StdLib/lib/python.27/lib-dynload" /* ########################################################################### Build the module search path. ########################################################################### */ /* Reduce prefix and exec_prefix to their essence, * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. * If we're loading relative to the build directory, * return the compiled-in defaults instead. */ reduce(prefix); reduce(prefix); /* The prefix is the root directory, but reduce() chopped * off the "/". */ if (!prefix[0]) { strcpy(prefix, volume_name); } bufsz = strlen(prefix); if(prefix[bufsz-1] == ':') { // if prefix consists solely of a volume_name prefix[bufsz] = SEP; // then append SEP indicating the root directory prefix[bufsz+1] = 0; // and ensure the new string is terminated } /* Calculate size of return buffer. */ defpath = pythonpath; bufsz = 0; if (rtpypath) bufsz += strlen(rtpypath) + 1; prefixsz = strlen(prefix) + 1; while (1) { char *delim = strchr(defpath, DELIM); if (is_absolute(defpath) == 0) /* Paths are relative to prefix */ bufsz += prefixsz; if (delim) bufsz += delim - defpath + 1; else { bufsz += strlen(defpath) + 1; break; } defpath = delim + 1; } bufsz += strlen(zip_path) + 1; bufsz += strlen(exec_prefix) + 1; /* This is the only malloc call in this file */ buf = (char *)PyMem_Malloc(bufsz); if (buf == NULL) { /* We can't exit, so print a warning and limp along */ fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); fprintf(stderr, "Using default static PYTHONPATH.\n"); module_search_path = PYTHONPATH; } else { /* Run-time value of $PYTHONPATH goes first */ if (rtpypath) { strcpy(buf, rtpypath); strcat(buf, delimiter); } else buf[0] = '\0'; /* Next is the default zip path */ strcat(buf, zip_path); strcat(buf, delimiter); /* Next goes merge of compile-time $PYTHONPATH with * dynamically located prefix. */ defpath = pythonpath; while (1) { char *delim = strchr(defpath, DELIM); if (is_absolute(defpath) != 1) { strcat(buf, prefix); strcat(buf, separator); } if (delim) { size_t len = delim - defpath + 1; size_t end = strlen(buf) + len; strncat(buf, defpath, len); *(buf + end) = '\0'; } else { strcat(buf, defpath); break; } defpath = delim + 1; } strcat(buf, delimiter); /* Finally, on goes the directory for dynamic-load modules */ strcat(buf, exec_prefix); /* And publish the results */ module_search_path = buf; } /* At this point, exec_prefix is set to VOL:/Efi/StdLib/lib/python.27/dynalib. We want to get back to the root value, so we have to remove the final three segments to get VOL:/Efi/StdLib. Because we don't know what VOL is, and EXEC_PREFIX is also indeterminate, we just remove the three final segments. */ reduce(exec_prefix); reduce(exec_prefix); reduce(exec_prefix); if (!exec_prefix[0]) { strcpy(exec_prefix, volume_name); } bufsz = strlen(exec_prefix); if(exec_prefix[bufsz-1] == ':') { exec_prefix[bufsz] = SEP; exec_prefix[bufsz+1] = 0; } if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: module_search_path = \"%s\"\n", __func__, __LINE__, module_search_path); if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: prefix = \"%s\"\n", __func__, __LINE__, prefix); if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: exec_prefix = \"%s\"\n", __func__, __LINE__, exec_prefix); if (Py_VerboseFlag) PySys_WriteStderr("%s[%d]: progpath = \"%s\"\n", __func__, __LINE__, progpath); }
int Py_FrozenMain(int argc, char **argv) #endif { char *p; int n, sts = 1; int inspect = 0; int unbuffered = 0; #if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE) int i; char *oldloc; wchar_t **argv_copy = NULL; /* We need a second copies, as Python might modify the first one. */ wchar_t **argv_copy2 = NULL; if (argc > 0) { argv_copy = (wchar_t **)alloca(sizeof(wchar_t *) * argc); argv_copy2 = (wchar_t **)alloca(sizeof(wchar_t *) * argc); } #endif #if defined(MS_WINDOWS) && PY_VERSION_HEX >= 0x03040000 && PY_VERSION_HEX < 0x03060000 if (!supports_code_page(GetConsoleOutputCP()) || !supports_code_page(GetConsoleCP())) { /* Revert to the active codepage, and tell Python to use the 'mbcs' * encoding (which always uses the active codepage). In 99% of cases, * this will be the same thing anyway. */ UINT acp = GetACP(); SetConsoleCP(acp); SetConsoleOutputCP(acp); Py_SetStandardStreamEncoding("mbcs", NULL); } #endif Py_FrozenFlag = 1; /* Suppress errors from getpath.c */ Py_NoSiteFlag = 0; Py_NoUserSiteDirectory = 1; if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') inspect = 1; if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') unbuffered = 1; if (unbuffered) { setbuf(stdin, (char *)NULL); setbuf(stdout, (char *)NULL); setbuf(stderr, (char *)NULL); } #if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE) oldloc = setlocale(LC_ALL, NULL); setlocale(LC_ALL, ""); for (i = 0; i < argc; i++) { argv_copy[i] = Py_DecodeLocale(argv[i], NULL); argv_copy2[i] = argv_copy[i]; if (!argv_copy[i]) { fprintf(stderr, "Unable to decode the command line argument #%i\n", i + 1); argc = i; goto error; } } setlocale(LC_ALL, oldloc); #endif #ifdef MS_WINDOWS PyImport_ExtendInittab(extensions); #endif /* MS_WINDOWS */ if (argc >= 1) { #if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE) Py_SetProgramName(argv_copy[0]); #else Py_SetProgramName(argv[0]); #endif } Py_Initialize(); #ifdef MS_WINDOWS PyWinFreeze_ExeInit(); #endif #if defined(MS_WINDOWS) && PY_VERSION_HEX < 0x03040000 if (!supports_code_page(GetConsoleOutputCP()) || !supports_code_page(GetConsoleCP())) { /* Same hack as before except for Python 2.7, which doesn't seem to have * a way to set the encoding ahead of time, and setting PYTHONIOENCODING * doesn't seem to work. Fortunately, Python 2.7 doesn't usually start * causing codec errors until the first print statement. */ PyObject *sys_stream; UINT acp = GetACP(); SetConsoleCP(acp); SetConsoleOutputCP(acp); sys_stream = PySys_GetObject("stdin"); if (sys_stream && PyFile_Check(sys_stream)) { PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL); } sys_stream = PySys_GetObject("stdout"); if (sys_stream && PyFile_Check(sys_stream)) { PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL); } sys_stream = PySys_GetObject("stderr"); if (sys_stream && PyFile_Check(sys_stream)) { PyFile_SetEncodingAndErrors(sys_stream, "mbcs", NULL); } } #endif if (Py_VerboseFlag) fprintf(stderr, "Python %s\n%s\n", Py_GetVersion(), Py_GetCopyright()); #if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE) PySys_SetArgv(argc, argv_copy); #else PySys_SetArgv(argc, argv); #endif #ifdef MACOS_APP_BUNDLE // Add the Frameworks directory to sys.path. char buffer[PATH_MAX]; uint32_t bufsize = sizeof(buffer); if (_NSGetExecutablePath(buffer, &bufsize) != 0) { assert(false); return 1; } char resolved[PATH_MAX]; if (!realpath(buffer, resolved)) { perror("realpath"); return 1; } const char *dir = dirname(resolved); sprintf(buffer, "%s/../Frameworks", dir); PyObject *sys_path = PyList_New(1); #if PY_MAJOR_VERSION >= 3 PyList_SET_ITEM(sys_path, 0, PyUnicode_FromString(buffer)); #else PyList_SET_ITEM(sys_path, 0, PyString_FromString(buffer)); #endif PySys_SetObject("path", sys_path); Py_DECREF(sys_path); // Now, store a path to the Resources directory into the main_dir pointer, // for ConfigPageManager to read out and assign to MAIN_DIR. sprintf(buffer, "%s/../Resources", dir); set_main_dir(buffer); #endif n = PyImport_ImportFrozenModule("__main__"); if (n == 0) Py_FatalError("__main__ not frozen"); if (n < 0) { PyErr_Print(); sts = 1; } else sts = 0; if (inspect && isatty((int)fileno(stdin))) sts = PyRun_AnyFile(stdin, "<stdin>") != 0; #ifdef MS_WINDOWS PyWinFreeze_ExeTerm(); #endif Py_Finalize(); #if PY_MAJOR_VERSION >= 3 && !defined(WIN_UNICODE) error: if (argv_copy2) { for (i = 0; i < argc; i++) { #if PY_MINOR_VERSION >= 4 PyMem_RawFree(argv_copy2[i]); #else PyMem_Free(argv_copy2[i]); #endif } } #endif return sts; }