Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3b69db2

Browse files
author
Kristján Valur Jónsson
committed
issue 9910
Add a Py_SetPath api to override magic path computations when starting up python.
1 parent 42ef4b1 commit 3b69db2

4 files changed

Lines changed: 68 additions & 2 deletions

File tree

Doc/c-api/init.rst

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ Initialization, Finalization, and Threads
2727

2828
Initialize the Python interpreter. In an application embedding Python, this
2929
should be called before using any other Python/C API functions; with the
30-
exception of :cfunc:`Py_SetProgramName`, :cfunc:`PyEval_InitThreads`,
31-
:cfunc:`PyEval_ReleaseLock`, and :cfunc:`PyEval_AcquireLock`. This initializes
30+
exception of :cfunc:`Py_SetProgramName`, :cfunc:`Py_SetPath`,
31+
:cfunc:`PyEval_InitThreads`, :cfunc:`PyEval_ReleaseLock`, and
32+
:cfunc:`PyEval_AcquireLock`. This initializes
3233
the table of loaded modules (``sys.modules``), and creates the fundamental
3334
modules :mod:`builtins`, :mod:`__main__` and :mod:`sys`. It also initializes
3435
the module search path (``sys.path``). It does not set ``sys.argv``; use
@@ -256,6 +257,7 @@ Initialization, Finalization, and Threads
256257
.. index::
257258
triple: module; search; path
258259
single: path (in module sys)
260+
single: Py_SetPath()
259261

260262
Return the default module search path; this is computed from the program name
261263
(set by :cfunc:`Py_SetProgramName` above) and some environment variables.
@@ -270,6 +272,25 @@ Initialization, Finalization, and Threads
270272
.. XXX should give the exact rules
271273
272274
275+
.. cfunction:: void Py_SetPath(const wchar_t *)
276+
277+
.. index::
278+
triple: module; search; path
279+
single: path (in module sys)
280+
single: Py_GetPath()
281+
282+
Set the default module search path. If this function is called before
283+
:cfunc: `Py_Initialize` then :cfunc: Py_GetPath won't attempt to compute
284+
a default serarch path but uses the provided one in stead. This is useful
285+
if Python is being embedded by an application that has full knowledge
286+
of the location of all modules. The path components should be separated
287+
by semicolons.
288+
289+
This also causes `sys.executable` to be set only to the raw program name
290+
(see :cfunc:`Py_SetProgramName`) and `for sys.prefix` and
291+
`sys.exec_prefix` to be empty. It is up to the caller to modify these if
292+
required after calling :cfunc: `Py_Initialize`.
293+
273294
.. cfunction:: const char* Py_GetVersion()
274295

275296
Return the version of this Python interpreter. This is a string that looks

Include/pythonrun.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
113113
PyAPI_FUNC(wchar_t *) Py_GetPrefix(void);
114114
PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
115115
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
116+
PyAPI_FUNC(void) Py_SetPath(const wchar_t *);
116117

117118
/* In their own files */
118119
PyAPI_FUNC(const char *) Py_GetVersion(void);

Modules/getpath.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@
9090
* known use of sys.prefix and sys.exec_prefix is for the ILU installation
9191
* process to find the installed Python tree.
9292
*
93+
* An embedding application can use Py_SetPath() to override all of
94+
* these authomatic path computations.
95+
*
9396
* NOTE: Windows MSVC builds use PC/getpathp.c instead!
9497
*/
9598

@@ -771,6 +774,23 @@ calculate_path(void)
771774

772775

773776
/* External interface */
777+
void
778+
Py_SetPath(const wchar_t *path)
779+
{
780+
if (module_search_path != NULL) {
781+
free(module_search_path);
782+
module_search_path = NULL;
783+
}
784+
if (path != NULL) {
785+
extern wchar_t *Py_GetProgramName(void);
786+
wchar_t *prog = Py_GetProgramName();
787+
wcsncpy(progpath, prog, MAXPATHLEN);
788+
exec_prefix[0] = prefix[0] = L'\0';
789+
module_search_path = malloc((wcslen(path) + 1) * sizeof(wchar_t));
790+
if (module_search_path != NULL)
791+
wcscpy(module_search_path, path);
792+
}
793+
}
774794

775795
wchar_t *
776796
Py_GetPath(void)

PC/getpathp.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
exe, some very strange installation setup) you get a path with
5252
some default, but relative, paths.
5353
54+
* An embedding application can use Py_SetPath() to override all of
55+
these authomatic path computations.
56+
5457
---------------------------------------------------------------- */
5558

5659

@@ -79,6 +82,9 @@
7982
* The approach is an adaptation for Windows of the strategy used in
8083
* ../Modules/getpath.c; it uses the Windows Registry as one of its
8184
* information sources.
85+
*
86+
* Py_SetPath() can be used to override this mechanism. Call Py_SetPath
87+
* with a semicolon separated path prior to calling Py_Initialize.
8288
*/
8389

8490
#ifndef LANDMARK
@@ -654,6 +660,24 @@ calculate_path(void)
654660

655661
/* External interface */
656662

663+
void
664+
Py_SetPath(const wchar_t *path)
665+
{
666+
if (module_search_path != NULL) {
667+
free(module_search_path);
668+
module_search_path = NULL;
669+
}
670+
if (path != NULL) {
671+
extern wchar_t *Py_GetProgramName(void);
672+
wchar_t *prog = Py_GetProgramName();
673+
wcsncpy(progpath, prog, MAXPATHLEN);
674+
prefix[0] = L'\0';
675+
module_search_path = malloc((wcslen(path) + 1) * sizeof(wchar_t));
676+
if (module_search_path != NULL)
677+
wcscpy(module_search_path, path);
678+
}
679+
}
680+
657681
wchar_t *
658682
Py_GetPath(void)
659683
{

0 commit comments

Comments
 (0)