Changes pyvenv.cfg trick into an actual sys.path file.
This commit is contained in:
parent
783c9ef84d
commit
4db86bc1b4
|
@ -29,13 +29,13 @@ Supported Versions
|
||||||
|
|
||||||
As specified in :pep:`11`, a Python release only supports a Windows platform
|
As specified in :pep:`11`, a Python release only supports a Windows platform
|
||||||
while Microsoft considers the platform under extended support. This means that
|
while Microsoft considers the platform under extended support. This means that
|
||||||
Python 3.5 supports Windows Vista and newer. If you require Windows XP support
|
Python 3.6 supports Windows Vista and newer. If you require Windows XP support
|
||||||
then please install Python 3.4.
|
then please install Python 3.4.
|
||||||
|
|
||||||
Installation Steps
|
Installation Steps
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
Four Python 3.5 installers are available for download - two each for the 32-bit
|
Four Python 3.6 installers are available for download - two each for the 32-bit
|
||||||
and 64-bit versions of the interpreter. The *web installer* is a small initial
|
and 64-bit versions of the interpreter. The *web installer* is a small initial
|
||||||
download, and it will automatically download the required components as
|
download, and it will automatically download the required components as
|
||||||
necessary. The *offline installer* includes the components necessary for a
|
necessary. The *offline installer* includes the components necessary for a
|
||||||
|
@ -193,13 +193,13 @@ of available options is shown below.
|
||||||
For example, to silently install a default, system-wide Python installation,
|
For example, to silently install a default, system-wide Python installation,
|
||||||
you could use the following command (from an elevated command prompt)::
|
you could use the following command (from an elevated command prompt)::
|
||||||
|
|
||||||
python-3.5.0.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0
|
python-3.6.0.exe /quiet InstallAllUsers=1 PrependPath=1 Include_test=0
|
||||||
|
|
||||||
To allow users to easily install a personal copy of Python without the test
|
To allow users to easily install a personal copy of Python without the test
|
||||||
suite, you could provide a shortcut with the following command. This will
|
suite, you could provide a shortcut with the following command. This will
|
||||||
display a simplified initial page and disallow customization::
|
display a simplified initial page and disallow customization::
|
||||||
|
|
||||||
python-3.5.0.exe InstallAllUsers=0 Include_launcher=0 Include_test=0
|
python-3.6.0.exe InstallAllUsers=0 Include_launcher=0 Include_test=0
|
||||||
SimpleInstall=1 SimpleInstallDescription="Just for me, no test suite."
|
SimpleInstall=1 SimpleInstallDescription="Just for me, no test suite."
|
||||||
|
|
||||||
(Note that omitting the launcher also omits file associations, and is only
|
(Note that omitting the launcher also omits file associations, and is only
|
||||||
|
@ -234,13 +234,13 @@ where a large number of installations are going to be performed it is very
|
||||||
useful to have a locally cached copy.
|
useful to have a locally cached copy.
|
||||||
|
|
||||||
Execute the following command from Command Prompt to download all possible
|
Execute the following command from Command Prompt to download all possible
|
||||||
required files. Remember to substitute ``python-3.5.0.exe`` for the actual
|
required files. Remember to substitute ``python-3.6.0.exe`` for the actual
|
||||||
name of your installer, and to create layouts in their own directories to
|
name of your installer, and to create layouts in their own directories to
|
||||||
avoid collisions between files with the same name.
|
avoid collisions between files with the same name.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
python-3.5.0.exe /layout [optional target directory]
|
python-3.6.0.exe /layout [optional target directory]
|
||||||
|
|
||||||
You may also specify the ``/quiet`` option to hide the progress display.
|
You may also specify the ``/quiet`` option to hide the progress display.
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ User level and the System level, or temporarily in a command prompt.
|
||||||
To temporarily set environment variables, open Command Prompt and use the
|
To temporarily set environment variables, open Command Prompt and use the
|
||||||
:command:`set` command::
|
:command:`set` command::
|
||||||
|
|
||||||
C:\>set PATH=C:\Program Files\Python 3.5;%PATH%
|
C:\>set PATH=C:\Program Files\Python 3.6;%PATH%
|
||||||
C:\>set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib
|
C:\>set PYTHONPATH=%PYTHONPATH%;C:\My_python_lib
|
||||||
C:\>python
|
C:\>python
|
||||||
|
|
||||||
|
@ -401,10 +401,10 @@ Finding the Python executable
|
||||||
|
|
||||||
Besides using the automatically created start menu entry for the Python
|
Besides using the automatically created start menu entry for the Python
|
||||||
interpreter, you might want to start Python in the command prompt. The
|
interpreter, you might want to start Python in the command prompt. The
|
||||||
installer for Python 3.5 and later has an option to set that up for you.
|
installer for Python 3.6 has an option to set that up for you.
|
||||||
|
|
||||||
On the first page of the installer, an option labelled "Add Python 3.5 to
|
On the first page of the installer, an option labelled "Add Python to PATH"
|
||||||
PATH" can be selected to have the installer add the install location into the
|
may be selected to have the installer add the install location into the
|
||||||
:envvar:`PATH`. The location of the :file:`Scripts\\` folder is also added.
|
:envvar:`PATH`. The location of the :file:`Scripts\\` folder is also added.
|
||||||
This allows you to type :command:`python` to run the interpreter, and
|
This allows you to type :command:`python` to run the interpreter, and
|
||||||
:command:`pip` for the package installer. Thus, you can also execute your
|
:command:`pip` for the package installer. Thus, you can also execute your
|
||||||
|
@ -418,7 +418,7 @@ of your Python installation, delimited by a semicolon from other entries. An
|
||||||
example variable could look like this (assuming the first two entries already
|
example variable could look like this (assuming the first two entries already
|
||||||
existed)::
|
existed)::
|
||||||
|
|
||||||
C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Python 3.5
|
C:\WINDOWS\system32;C:\WINDOWS;C:\Program Files\Python 3.6
|
||||||
|
|
||||||
.. _launcher:
|
.. _launcher:
|
||||||
|
|
||||||
|
@ -720,7 +720,15 @@ installation directory. So, if you had installed Python to
|
||||||
:file:`C:\\Python\\Lib\\` and third-party modules should be stored in
|
:file:`C:\\Python\\Lib\\` and third-party modules should be stored in
|
||||||
:file:`C:\\Python\\Lib\\site-packages\\`.
|
:file:`C:\\Python\\Lib\\site-packages\\`.
|
||||||
|
|
||||||
This is how :data:`sys.path` is populated on Windows:
|
To completely override :data:`sys.path`, create a text file named ``'sys.path'``
|
||||||
|
containing a list of paths alongside the Python executable. This will ignore all
|
||||||
|
registry settings and environment variables, enable isolated mode, disable
|
||||||
|
importing :mod:`site`, and fill :data:`sys.path` with exactly the paths listed
|
||||||
|
in the file. Paths may be absolute or relative to the directory containing the
|
||||||
|
file.
|
||||||
|
|
||||||
|
When the ``'sys.path'`` file is missing, this is how :data:`sys.path` is
|
||||||
|
populated on Windows:
|
||||||
|
|
||||||
* An empty entry is added at the start, which corresponds to the current
|
* An empty entry is added at the start, which corresponds to the current
|
||||||
directory.
|
directory.
|
||||||
|
@ -755,10 +763,6 @@ directory one level above the executable, the following variations apply:
|
||||||
path is used instead of the path to the main executable when deducing the
|
path is used instead of the path to the main executable when deducing the
|
||||||
home location.
|
home location.
|
||||||
|
|
||||||
* If ``applocal`` is set to true, the ``home`` property or the main executable
|
|
||||||
is always used as the home path, and all environment variables or registry
|
|
||||||
values affecting the path are ignored. The landmark file is not checked.
|
|
||||||
|
|
||||||
The end result of all this is:
|
The end result of all this is:
|
||||||
|
|
||||||
* When running :file:`python.exe`, or any other .exe in the main Python
|
* When running :file:`python.exe`, or any other .exe in the main Python
|
||||||
|
@ -777,13 +781,11 @@ The end result of all this is:
|
||||||
For those who want to bundle Python into their application or distribution, the
|
For those who want to bundle Python into their application or distribution, the
|
||||||
following advice will prevent conflicts with other installations:
|
following advice will prevent conflicts with other installations:
|
||||||
|
|
||||||
* Include a ``pyvenv.cfg`` file alongside your executable containing
|
* Include a ``sys.path`` file alongside your executable containing the
|
||||||
``applocal = true``. This will ensure that your own directory will be used to
|
directories to include. This will ignore user site-packages and other paths
|
||||||
resolve paths even if you have included the standard library in a ZIP file.
|
listed in the registry or in environment variables.
|
||||||
It will also ignore user site-packages and other paths listed in the
|
|
||||||
registry.
|
|
||||||
|
|
||||||
* If you are loading :file:`python3.dll` or :file:`python35.dll` in your own
|
* If you are loading :file:`python3.dll` or :file:`python36.dll` in your own
|
||||||
executable, explicitly call :c:func:`Py_SetPath` or (at least)
|
executable, explicitly call :c:func:`Py_SetPath` or (at least)
|
||||||
:c:func:`Py_SetProgramName` before :c:func:`Py_Initialize`.
|
:c:func:`Py_SetProgramName` before :c:func:`Py_Initialize`.
|
||||||
|
|
||||||
|
@ -801,6 +803,11 @@ Otherwise, your users may experience problems using your application. Note that
|
||||||
the first suggestion is the best, as the other may still be susceptible to
|
the first suggestion is the best, as the other may still be susceptible to
|
||||||
non-standard paths in the registry and user site-packages.
|
non-standard paths in the registry and user site-packages.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.6
|
||||||
|
|
||||||
|
Adds ``sys.path`` file support and removes ``applocal`` option from
|
||||||
|
``pyvenv.cfg``.
|
||||||
|
|
||||||
Additional modules
|
Additional modules
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
@ -900,7 +907,7 @@ directly accessed by end-users.
|
||||||
When extracted, the embedded distribution is (almost) fully isolated from the
|
When extracted, the embedded distribution is (almost) fully isolated from the
|
||||||
user's system, including environment variables, system registry settings, and
|
user's system, including environment variables, system registry settings, and
|
||||||
installed packages. The standard library is included as pre-compiled and
|
installed packages. The standard library is included as pre-compiled and
|
||||||
optimized ``.pyc`` files in a ZIP, and ``python3.dll``, ``python35.dll``,
|
optimized ``.pyc`` files in a ZIP, and ``python3.dll``, ``python36.dll``,
|
||||||
``python.exe`` and ``pythonw.exe`` are all provided. Tcl/tk (including all
|
``python.exe`` and ``pythonw.exe`` are all provided. Tcl/tk (including all
|
||||||
dependants, such as Idle), pip and the Python documentation are not included.
|
dependants, such as Idle), pip and the Python documentation are not included.
|
||||||
|
|
||||||
|
|
|
@ -463,12 +463,6 @@ def venv(known_paths):
|
||||||
system_site = value.lower()
|
system_site = value.lower()
|
||||||
elif key == 'home':
|
elif key == 'home':
|
||||||
sys._home = value
|
sys._home = value
|
||||||
elif key == 'applocal' and value.lower() == 'true':
|
|
||||||
# App-local installs use the exe_dir as prefix,
|
|
||||||
# not one level higher, and do not use system
|
|
||||||
# site packages.
|
|
||||||
site_prefix = exe_dir
|
|
||||||
system_site = 'false'
|
|
||||||
|
|
||||||
sys.prefix = sys.exec_prefix = site_prefix
|
sys.prefix = sys.exec_prefix = site_prefix
|
||||||
|
|
||||||
|
|
181
PC/getpathp.c
181
PC/getpathp.c
|
@ -6,7 +6,8 @@
|
||||||
PATH RULES FOR WINDOWS:
|
PATH RULES FOR WINDOWS:
|
||||||
This describes how sys.path is formed on Windows. It describes the
|
This describes how sys.path is formed on Windows. It describes the
|
||||||
functionality, not the implementation (ie, the order in which these
|
functionality, not the implementation (ie, the order in which these
|
||||||
are actually fetched is different)
|
are actually fetched is different). The presence of a sys.path file
|
||||||
|
alongside the program overrides these rules - see below.
|
||||||
|
|
||||||
* Python always adds an empty entry at the start, which corresponds
|
* Python always adds an empty entry at the start, which corresponds
|
||||||
to the current directory.
|
to the current directory.
|
||||||
|
@ -36,6 +37,12 @@
|
||||||
used (eg. .\Lib;.\plat-win, etc)
|
used (eg. .\Lib;.\plat-win, etc)
|
||||||
|
|
||||||
|
|
||||||
|
If a sys.path file exists adjacent to python.exe, it must contain a
|
||||||
|
list of paths to add to sys.path, one per line (like a .pth file but without
|
||||||
|
the ability to execute arbitrary code). Each path is relative to the
|
||||||
|
directory containing the file. No other paths are added to the search path,
|
||||||
|
and the registry finder is not enabled.
|
||||||
|
|
||||||
The end result of all this is:
|
The end result of all this is:
|
||||||
* When running python.exe, or any other .exe in the main Python directory
|
* When running python.exe, or any other .exe in the main Python directory
|
||||||
(either an installed version, or directly from the PCbuild directory),
|
(either an installed version, or directly from the PCbuild directory),
|
||||||
|
@ -52,7 +59,10 @@
|
||||||
some default, but relative, paths.
|
some default, but relative, paths.
|
||||||
|
|
||||||
* An embedding application can use Py_SetPath() to override all of
|
* An embedding application can use Py_SetPath() to override all of
|
||||||
these authomatic path computations.
|
these automatic path computations.
|
||||||
|
|
||||||
|
* An isolation install of Python can disable all implicit paths by
|
||||||
|
providing a sys.path file.
|
||||||
|
|
||||||
---------------------------------------------------------------- */
|
---------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -61,10 +71,13 @@
|
||||||
#include "osdefs.h"
|
#include "osdefs.h"
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifndef MS_WINDOWS
|
||||||
#include <windows.h>
|
#error getpathp.c should only be built on Windows
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif /* HAVE_SYS_TYPES_H */
|
#endif /* HAVE_SYS_TYPES_H */
|
||||||
|
@ -163,24 +176,30 @@ ismodule(wchar_t *filename, int update_filename) /* Is module -- check for .pyc/
|
||||||
than MAXPATHLEN characters at exit. If stuff is too long, only as much of
|
than MAXPATHLEN characters at exit. If stuff is too long, only as much of
|
||||||
stuff as fits will be appended.
|
stuff as fits will be appended.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static int _PathCchCombineEx_Initialized = 0;
|
||||||
|
typedef HRESULT(__stdcall *PPathCchCombineEx)(PWSTR pszPathOut, size_t cchPathOut, PCWSTR pszPathIn, PCWSTR pszMore, unsigned long dwFlags);
|
||||||
|
static PPathCchCombineEx _PathCchCombineEx;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
join(wchar_t *buffer, const wchar_t *stuff)
|
join(wchar_t *buffer, const wchar_t *stuff)
|
||||||
{
|
{
|
||||||
size_t n;
|
if (_PathCchCombineEx_Initialized == 0) {
|
||||||
if (is_sep(stuff[0]) ||
|
HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
|
||||||
(wcsnlen_s(stuff, 4) >= 3 && stuff[1] == ':' && is_sep(stuff[2]))) {
|
if (pathapi)
|
||||||
if (wcscpy_s(buffer, MAXPATHLEN+1, stuff) != 0)
|
_PathCchCombineEx = (PPathCchCombineEx)GetProcAddress(pathapi, "PathCchCombineEx");
|
||||||
Py_FatalError("buffer overflow in getpathp.c's join()");
|
else
|
||||||
return;
|
_PathCchCombineEx = NULL;
|
||||||
|
_PathCchCombineEx_Initialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = wcsnlen_s(buffer, MAXPATHLEN+1);
|
if (_PathCchCombineEx) {
|
||||||
if (n > 0 && !is_sep(buffer[n - 1]) && n < MAXPATHLEN) {
|
if (FAILED(_PathCchCombineEx(buffer, MAXPATHLEN+1, buffer, stuff, 0)))
|
||||||
buffer[n] = SEP;
|
Py_FatalError("buffer overflow in getpathp.c's join()");
|
||||||
buffer[n + 1] = '\0';
|
} else {
|
||||||
|
if (!PathCombineW(buffer, NULL, stuff))
|
||||||
|
Py_FatalError("buffer overflow in getpathp.c's join()");
|
||||||
}
|
}
|
||||||
if (wcscat_s(buffer, MAXPATHLEN+1, stuff) != 0)
|
|
||||||
Py_FatalError("buffer overflow in getpathp.c's join()");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gotlandmark only called by search_for_prefix, which ensures
|
/* gotlandmark only called by search_for_prefix, which ensures
|
||||||
|
@ -214,7 +233,6 @@ search_for_prefix(wchar_t *argv0_path, wchar_t *landmark)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
#ifdef Py_ENABLE_SHARED
|
#ifdef Py_ENABLE_SHARED
|
||||||
|
|
||||||
/* a string loaded from the DLL at startup.*/
|
/* a string loaded from the DLL at startup.*/
|
||||||
|
@ -369,7 +387,6 @@ done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#endif /* Py_ENABLE_SHARED */
|
#endif /* Py_ENABLE_SHARED */
|
||||||
#endif /* MS_WINDOWS */
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_progpath(void)
|
get_progpath(void)
|
||||||
|
@ -378,7 +395,6 @@ get_progpath(void)
|
||||||
wchar_t *path = _wgetenv(L"PATH");
|
wchar_t *path = _wgetenv(L"PATH");
|
||||||
wchar_t *prog = Py_GetProgramName();
|
wchar_t *prog = Py_GetProgramName();
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
#ifdef Py_ENABLE_SHARED
|
#ifdef Py_ENABLE_SHARED
|
||||||
extern HANDLE PyWin_DLLhModule;
|
extern HANDLE PyWin_DLLhModule;
|
||||||
/* static init of progpath ensures final char remains \0 */
|
/* static init of progpath ensures final char remains \0 */
|
||||||
|
@ -390,7 +406,6 @@ get_progpath(void)
|
||||||
#endif
|
#endif
|
||||||
if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN))
|
if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN))
|
||||||
return;
|
return;
|
||||||
#endif
|
|
||||||
if (prog == NULL || *prog == '\0')
|
if (prog == NULL || *prog == '\0')
|
||||||
prog = L"python";
|
prog = L"python";
|
||||||
|
|
||||||
|
@ -483,6 +498,67 @@ find_env_config_value(FILE * env_file, const wchar_t * key, wchar_t * value)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_sys_path_file(const wchar_t *path, const wchar_t *prefix)
|
||||||
|
{
|
||||||
|
FILE *sp_file = _Py_wfopen(path, L"r");
|
||||||
|
if (sp_file == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
size_t bufsiz = MAXPATHLEN;
|
||||||
|
size_t prefixlen = wcslen(prefix);
|
||||||
|
|
||||||
|
wchar_t *buf = (wchar_t*)PyMem_RawMalloc(bufsiz * sizeof(wchar_t));
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
while (!feof(sp_file)) {
|
||||||
|
char line[MAXPATHLEN + 1];
|
||||||
|
char *p = fgets(line, MAXPATHLEN + 1, sp_file);
|
||||||
|
if (!p)
|
||||||
|
break;
|
||||||
|
|
||||||
|
DWORD n = strlen(line);
|
||||||
|
if (n == 0 || p[n - 1] != '\n')
|
||||||
|
break;
|
||||||
|
if (n > 2 && p[n - 1] == '\r')
|
||||||
|
--n;
|
||||||
|
|
||||||
|
DWORD wn = MultiByteToWideChar(CP_UTF8, 0, line, n - 1, NULL, 0);
|
||||||
|
wchar_t *wline = (wchar_t*)PyMem_RawMalloc((wn + 1) * sizeof(wchar_t));
|
||||||
|
wn = MultiByteToWideChar(CP_UTF8, 0, line, n - 1, wline, wn);
|
||||||
|
wline[wn] = '\0';
|
||||||
|
|
||||||
|
while (wn + prefixlen + 4 > bufsiz) {
|
||||||
|
bufsiz += MAXPATHLEN;
|
||||||
|
buf = (wchar_t*)PyMem_RawRealloc(buf, (bufsiz + 1) * sizeof(wchar_t));
|
||||||
|
if (!buf) {
|
||||||
|
PyMem_RawFree(wline);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buf[0])
|
||||||
|
wcscat_s(buf, bufsiz, L";");
|
||||||
|
wchar_t *b = &buf[wcslen(buf)];
|
||||||
|
|
||||||
|
wcscat_s(buf, bufsiz, prefix);
|
||||||
|
join(b, wline);
|
||||||
|
|
||||||
|
PyMem_RawFree(wline);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_search_path = buf;
|
||||||
|
|
||||||
|
fclose(sp_file);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
PyMem_RawFree(buf);
|
||||||
|
fclose(sp_file);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
calculate_path(void)
|
calculate_path(void)
|
||||||
{
|
{
|
||||||
|
@ -492,32 +568,34 @@ calculate_path(void)
|
||||||
wchar_t *pythonhome = Py_GetPythonHome();
|
wchar_t *pythonhome = Py_GetPythonHome();
|
||||||
wchar_t *envpath = NULL;
|
wchar_t *envpath = NULL;
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
int skiphome, skipdefault;
|
int skiphome, skipdefault;
|
||||||
wchar_t *machinepath = NULL;
|
wchar_t *machinepath = NULL;
|
||||||
wchar_t *userpath = NULL;
|
wchar_t *userpath = NULL;
|
||||||
wchar_t zip_path[MAXPATHLEN+1];
|
wchar_t zip_path[MAXPATHLEN+1];
|
||||||
int applocal = 0;
|
|
||||||
|
|
||||||
if (!Py_IgnoreEnvironmentFlag) {
|
if (!Py_IgnoreEnvironmentFlag) {
|
||||||
envpath = _wgetenv(L"PYTHONPATH");
|
envpath = _wgetenv(L"PYTHONPATH");
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
char *_envpath = Py_GETENV("PYTHONPATH");
|
|
||||||
wchar_t wenvpath[MAXPATHLEN+1];
|
|
||||||
if (_envpath) {
|
|
||||||
size_t r = mbstowcs(wenvpath, _envpath, MAXPATHLEN+1);
|
|
||||||
envpath = wenvpath;
|
|
||||||
if (r == (size_t)-1 || r >= MAXPATHLEN)
|
|
||||||
envpath = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
get_progpath();
|
get_progpath();
|
||||||
/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
|
/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
|
||||||
wcscpy_s(argv0_path, MAXPATHLEN+1, progpath);
|
wcscpy_s(argv0_path, MAXPATHLEN+1, progpath);
|
||||||
reduce(argv0_path);
|
reduce(argv0_path);
|
||||||
|
|
||||||
|
/* Search for a sys.path file */
|
||||||
|
{
|
||||||
|
wchar_t spbuffer[MAXPATHLEN+1];
|
||||||
|
|
||||||
|
wcscpy_s(spbuffer, MAXPATHLEN+1, argv0_path);
|
||||||
|
join(spbuffer, L"sys.path");
|
||||||
|
if (exists(spbuffer) && read_sys_path_file(spbuffer, argv0_path) == 0) {
|
||||||
|
wcscpy_s(prefix, MAXPATHLEN + 1, argv0_path);
|
||||||
|
Py_IsolatedFlag = 1;
|
||||||
|
Py_NoSiteFlag = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Search for an environment configuration file, first in the
|
/* Search for an environment configuration file, first in the
|
||||||
executable's directory and then in the parent directory.
|
executable's directory and then in the parent directory.
|
||||||
If found, open it for use when searching for prefixes.
|
If found, open it for use when searching for prefixes.
|
||||||
|
@ -543,17 +621,6 @@ calculate_path(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (env_file != NULL) {
|
if (env_file != NULL) {
|
||||||
/* Look for an 'applocal' variable and, if true, ignore all registry
|
|
||||||
* keys and environment variables, but retain the default paths
|
|
||||||
* (DLLs, Lib) and the zip file. Setting pythonhome here suppresses
|
|
||||||
* the search for LANDMARK below and overrides %PYTHONHOME%.
|
|
||||||
*/
|
|
||||||
if (find_env_config_value(env_file, L"applocal", tmpbuffer) &&
|
|
||||||
(applocal = (wcsicmp(tmpbuffer, L"true") == 0))) {
|
|
||||||
envpath = NULL;
|
|
||||||
pythonhome = argv0_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Look for a 'home' variable and set argv0_path to it, if found */
|
/* Look for a 'home' variable and set argv0_path to it, if found */
|
||||||
if (find_env_config_value(env_file, L"home", tmpbuffer)) {
|
if (find_env_config_value(env_file, L"home", tmpbuffer)) {
|
||||||
wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer);
|
wcscpy_s(argv0_path, MAXPATHLEN+1, tmpbuffer);
|
||||||
|
@ -576,7 +643,6 @@ calculate_path(void)
|
||||||
envpath = NULL;
|
envpath = NULL;
|
||||||
|
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
/* Calculate zip archive path from DLL or exe path */
|
/* Calculate zip archive path from DLL or exe path */
|
||||||
if (wcscpy_s(zip_path, MAXPATHLEN+1, dllpath[0] ? dllpath : progpath))
|
if (wcscpy_s(zip_path, MAXPATHLEN+1, dllpath[0] ? dllpath : progpath))
|
||||||
/* exceeded buffer length - ignore zip_path */
|
/* exceeded buffer length - ignore zip_path */
|
||||||
|
@ -590,16 +656,13 @@ calculate_path(void)
|
||||||
|
|
||||||
skiphome = pythonhome==NULL ? 0 : 1;
|
skiphome = pythonhome==NULL ? 0 : 1;
|
||||||
#ifdef Py_ENABLE_SHARED
|
#ifdef Py_ENABLE_SHARED
|
||||||
if (!applocal) {
|
machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
|
||||||
machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, skiphome);
|
userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
|
||||||
userpath = getpythonregpath(HKEY_CURRENT_USER, skiphome);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
/* We only use the default relative PYTHONPATH if we havent
|
/* We only use the default relative PYTHONPATH if we havent
|
||||||
anything better to use! */
|
anything better to use! */
|
||||||
skipdefault = envpath!=NULL || pythonhome!=NULL || \
|
skipdefault = envpath!=NULL || pythonhome!=NULL || \
|
||||||
machinepath!=NULL || userpath!=NULL;
|
machinepath!=NULL || userpath!=NULL;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We need to construct a path from the following parts.
|
/* We need to construct a path from the following parts.
|
||||||
(1) the PYTHONPATH environment variable, if set;
|
(1) the PYTHONPATH environment variable, if set;
|
||||||
|
@ -612,7 +675,6 @@ calculate_path(void)
|
||||||
Extra rules:
|
Extra rules:
|
||||||
- If PYTHONHOME is set (in any way) item (3) is ignored.
|
- If PYTHONHOME is set (in any way) item (3) is ignored.
|
||||||
- If registry values are used, (4) and (5) are ignored.
|
- If registry values are used, (4) and (5) are ignored.
|
||||||
- If applocal is set, (1), (3), and registry values are ignored
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Calculate size of return buffer */
|
/* Calculate size of return buffer */
|
||||||
|
@ -629,13 +691,11 @@ calculate_path(void)
|
||||||
bufsz = 0;
|
bufsz = 0;
|
||||||
bufsz += wcslen(PYTHONPATH) + 1;
|
bufsz += wcslen(PYTHONPATH) + 1;
|
||||||
bufsz += wcslen(argv0_path) + 1;
|
bufsz += wcslen(argv0_path) + 1;
|
||||||
#ifdef MS_WINDOWS
|
if (userpath)
|
||||||
if (!applocal && userpath)
|
|
||||||
bufsz += wcslen(userpath) + 1;
|
bufsz += wcslen(userpath) + 1;
|
||||||
if (!applocal && machinepath)
|
if (machinepath)
|
||||||
bufsz += wcslen(machinepath) + 1;
|
bufsz += wcslen(machinepath) + 1;
|
||||||
bufsz += wcslen(zip_path) + 1;
|
bufsz += wcslen(zip_path) + 1;
|
||||||
#endif
|
|
||||||
if (envpath != NULL)
|
if (envpath != NULL)
|
||||||
bufsz += wcslen(envpath) + 1;
|
bufsz += wcslen(envpath) + 1;
|
||||||
|
|
||||||
|
@ -651,10 +711,8 @@ calculate_path(void)
|
||||||
fprintf(stderr, "Using default static path.\n");
|
fprintf(stderr, "Using default static path.\n");
|
||||||
module_search_path = PYTHONPATH;
|
module_search_path = PYTHONPATH;
|
||||||
}
|
}
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
PyMem_RawFree(machinepath);
|
PyMem_RawFree(machinepath);
|
||||||
PyMem_RawFree(userpath);
|
PyMem_RawFree(userpath);
|
||||||
#endif /* MS_WINDOWS */
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,7 +722,6 @@ calculate_path(void)
|
||||||
buf = wcschr(buf, L'\0');
|
buf = wcschr(buf, L'\0');
|
||||||
*buf++ = DELIM;
|
*buf++ = DELIM;
|
||||||
}
|
}
|
||||||
#ifdef MS_WINDOWS
|
|
||||||
if (zip_path[0]) {
|
if (zip_path[0]) {
|
||||||
if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path))
|
if (wcscpy_s(buf, bufsz - (buf - module_search_path), zip_path))
|
||||||
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
|
Py_FatalError("buffer overflow in getpathp.c's calculate_path()");
|
||||||
|
@ -692,15 +749,7 @@ calculate_path(void)
|
||||||
buf = wcschr(buf, L'\0');
|
buf = wcschr(buf, L'\0');
|
||||||
*buf++ = DELIM;
|
*buf++ = DELIM;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
#else
|
|
||||||
if (pythonhome == NULL) {
|
|
||||||
wcscpy(buf, PYTHONPATH);
|
|
||||||
buf = wcschr(buf, L'\0');
|
|
||||||
*buf++ = DELIM;
|
|
||||||
}
|
|
||||||
#endif /* MS_WINDOWS */
|
|
||||||
else {
|
|
||||||
wchar_t *p = PYTHONPATH;
|
wchar_t *p = PYTHONPATH;
|
||||||
wchar_t *q;
|
wchar_t *q;
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
|
@ -69,7 +69,7 @@
|
||||||
<PreprocessorDefinitions>_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_USRDLL;Py_BUILD_CORE;Py_ENABLE_SHARED;MS_DLL_ID="$(SysWinVer)";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>shlwapi.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
<BaseAddress>0x1e000000</BaseAddress>
|
<BaseAddress>0x1e000000</BaseAddress>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|
|
@ -46,6 +46,10 @@ EXCLUDE_FILE_FROM_LIBS = {
|
||||||
'python3stub',
|
'python3stub',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXCLUDED_FILES = {
|
||||||
|
'pyshellext',
|
||||||
|
}
|
||||||
|
|
||||||
def is_not_debug(p):
|
def is_not_debug(p):
|
||||||
if DEBUG_RE.search(p.name):
|
if DEBUG_RE.search(p.name):
|
||||||
return False
|
return False
|
||||||
|
@ -53,7 +57,7 @@ def is_not_debug(p):
|
||||||
if TKTCL_RE.search(p.name):
|
if TKTCL_RE.search(p.name):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return p.stem.lower() not in DEBUG_FILES
|
return p.stem.lower() not in DEBUG_FILES and p.stem.lower() not in EXCLUDED_FILES
|
||||||
|
|
||||||
def is_not_debug_or_python(p):
|
def is_not_debug_or_python(p):
|
||||||
return is_not_debug(p) and not PYTHON_DLL_RE.search(p.name)
|
return is_not_debug(p) and not PYTHON_DLL_RE.search(p.name)
|
||||||
|
@ -209,8 +213,9 @@ def main():
|
||||||
copied = copy_to_layout(temp / t.rstrip('/'), rglob(s, p, c))
|
copied = copy_to_layout(temp / t.rstrip('/'), rglob(s, p, c))
|
||||||
print('Copied {} files'.format(copied))
|
print('Copied {} files'.format(copied))
|
||||||
|
|
||||||
with open(str(temp / 'pyvenv.cfg'), 'w') as f:
|
with open(str(temp / 'sys.path'), 'w') as f:
|
||||||
print('applocal = true', file=f)
|
print('python{0.major}{0.minor}.zip'.format(sys.version_info), file=f)
|
||||||
|
print('.', file=f)
|
||||||
|
|
||||||
if out:
|
if out:
|
||||||
total = copy_to_layout(out, rglob(temp, '**/*', None))
|
total = copy_to_layout(out, rglob(temp, '**/*', None))
|
||||||
|
|
Loading…
Reference in New Issue