Index: Doc/c-api/init.rst =================================================================== --- Doc/c-api/init.rst (revision 84913) +++ Doc/c-api/init.rst (working copy) @@ -27,8 +27,9 @@ 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 :cfunc:`Py_SetProgramName`, :cfunc:`PyEval_InitThreads`, - :cfunc:`PyEval_ReleaseLock`, and :cfunc:`PyEval_AcquireLock`. This initializes + exception of :cfunc:`Py_SetProgramName`, :cfunc:`Py_SetPath`, + :cfunc:`PyEval_InitThreads`, :cfunc:`PyEval_ReleaseLock`, and + :cfunc:`PyEval_AcquireLock`. This initializes the table of loaded modules (``sys.modules``), and creates the fundamental modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. It also initializes the module search path (``sys.path``). It does not set ``sys.argv``; use @@ -256,6 +257,7 @@ .. index:: triple: module; search; path single: path (in module sys) + single: Py_SetPath() Return the default module search path; this is computed from the program name (set by :cfunc:`Py_SetProgramName` above) and some environment variables. @@ -270,6 +272,25 @@ .. XXX should give the exact rules +.. cfunction:: void Py_SetPath(const wchar_t *) + + .. index:: + triple: module; search; path + single: path (in module sys) + single: Py_GetPath() + + Set the default module search path. If this function is called before + :cfunc: `Py_Initialize` then :cfunc: Py_GetPath won't attempt to compute + a default serarch path but uses the provided one in stead. This is useful + if Python is being embedded by an application that has full knowledge + of the location of all modules. The path components should be separated + by semicolons. + + This also causes `sys.executable` to be set only to the raw program name + (see :cfunc:`Py_SetProgramName`) and `for sys.prefix` and + `sys.exec_prefix` to be empty. It is up to the caller to modify these if + required after calling :cfunc: `Py_Initialize`. + .. cfunction:: const char* Py_GetVersion() Return the version of this Python interpreter. This is a string that looks Index: Include/pythonrun.h =================================================================== --- Include/pythonrun.h (revision 84913) +++ Include/pythonrun.h (working copy) @@ -113,6 +113,7 @@ PyAPI_FUNC(wchar_t *) Py_GetPrefix(void); PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void); PyAPI_FUNC(wchar_t *) Py_GetPath(void); +PyAPI_FUNC(void) Py_SetPath(const wchar_t *); /* In their own files */ PyAPI_FUNC(const char *) Py_GetVersion(void); Index: Modules/getpath.c =================================================================== --- Modules/getpath.c (revision 84913) +++ Modules/getpath.c (working copy) @@ -90,6 +90,9 @@ * known use of sys.prefix and sys.exec_prefix is for the ILU installation * process to find the installed Python tree. * + * An embedding application can use Py_SetPath() to override all of + * these authomatic path computations. + * * NOTE: Windows MSVC builds use PC/getpathp.c instead! */ @@ -771,6 +774,23 @@ /* External interface */ +void +Py_SetPath(const wchar_t *path) +{ + if (module_search_path != NULL) { + free(module_search_path); + module_search_path = NULL; + } + if (path != NULL) { + extern wchar_t *Py_GetProgramName(void); + wchar_t *prog = Py_GetProgramName(); + wcsncpy(progpath, prog, MAXPATHLEN); + exec_prefix[0] = prefix[0] = L'\0'; + module_search_path = malloc((wcslen(path) + 1) * sizeof(wchar_t)); + if (module_search_path != NULL) + wcscpy(module_search_path, path); + } +} wchar_t * Py_GetPath(void) Index: PC/getpathp.c =================================================================== --- PC/getpathp.c (revision 84913) +++ PC/getpathp.c (working copy) @@ -51,6 +51,9 @@ exe, some very strange installation setup) you get a path with some default, but relative, paths. + * An embedding application can use Py_SetPath() to override all of + these authomatic path computations. + ---------------------------------------------------------------- */ @@ -79,6 +82,9 @@ * The approach is an adaptation for Windows of the strategy used in * ../Modules/getpath.c; it uses the Windows Registry as one of its * information sources. + * + * Py_SetPath() can be used to override this mechanism. Call Py_SetPath + * with a semicolon separated path prior to calling Py_Initialize. */ #ifndef LANDMARK @@ -654,6 +660,24 @@ /* External interface */ +void +Py_SetPath(const wchar_t *path) +{ + if (module_search_path != NULL) { + free(module_search_path); + module_search_path = NULL; + } + if (path != NULL) { + extern wchar_t *Py_GetProgramName(void); + wchar_t *prog = Py_GetProgramName(); + wcsncpy(progpath, prog, MAXPATHLEN); + prefix[0] = L'\0'; + module_search_path = malloc((wcslen(path) + 1) * sizeof(wchar_t)); + if (module_search_path != NULL) + wcscpy(module_search_path, path); + } +} + wchar_t * Py_GetPath(void) {