summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristján Valur Jónsson <kristjan@ccpgames.com>2010-09-27 05:32:54 (GMT)
committerKristján Valur Jónsson <kristjan@ccpgames.com>2010-09-27 05:32:54 (GMT)
commit3b69db27d70f05584b76ece61bb882c26ecfcc68 (patch)
treec02d068991fa7d393ec6a33ab4307d401a90c1f7
parent42ef4b1f4c8f07357f7c4e9cb8470f57365b0ffa (diff)
downloadcpython-3b69db27d70f05584b76ece61bb882c26ecfcc68.zip
cpython-3b69db27d70f05584b76ece61bb882c26ecfcc68.tar.gz
cpython-3b69db27d70f05584b76ece61bb882c26ecfcc68.tar.bz2
issue 9910
Add a Py_SetPath api to override magic path computations when starting up python.
-rw-r--r--Doc/c-api/init.rst25
-rw-r--r--Include/pythonrun.h1
-rw-r--r--Modules/getpath.c20
-rw-r--r--PC/getpathp.c24
4 files changed, 68 insertions, 2 deletions
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index ae5d028..52797f7 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -27,8 +27,9 @@ Initialization, Finalization, and Threads
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 @@ Initialization, Finalization, and Threads
.. 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 @@ Initialization, Finalization, and Threads
.. 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
diff --git a/Include/pythonrun.h b/Include/pythonrun.h
index b9da550..108b647 100644
--- a/Include/pythonrun.h
+++ b/Include/pythonrun.h
@@ -113,6 +113,7 @@ PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
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);
diff --git a/Modules/getpath.c b/Modules/getpath.c
index c55b3d7..6f2e537 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -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 @@ calculate_path(void)
/* 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)
diff --git a/PC/getpathp.c b/PC/getpathp.c
index 0fe04c7..3a87411 100644
--- a/PC/getpathp.c
+++ b/PC/getpathp.c
@@ -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 @@ calculate_path(void)
/* 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)
{