FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

bpo-45211: Remember the stdlib dir during startup. by ericsnowcurrently · Pull Request #28586 · python/cpython · GitHub

Repository navigation

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (5) .h  (3) .py  (2) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
1 change: 1 addition & 0 deletions Include/cpython/initconfig.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ typedef struct PyConfig {
/* --- Path configuration outputs ----------- */
int module_search_paths_set;
PyWideStringList module_search_paths;
wchar_t *stdlib_dir;
wchar_t *executable;
wchar_t *base_executable;
wchar_t *prefix;
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_pathconfig.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ typedef struct _PyPathConfig {
wchar_t *program_full_path;
wchar_t *prefix;
wchar_t *exec_prefix;
wchar_t *stdlib_dir;
/* Set by Py_SetPath(), or computed by _PyConfig_InitPathConfig() */
wchar_t *module_search_path;
/* Python program name */
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_pylifecycle.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ PyAPI_FUNC(PyStatus) _Py_PreInitializeFromConfig(
const PyConfig *config,
const struct _PyArgv *args);

PyAPI_FUNC(wchar_t *) _Py_GetStdlibDir(void);

PyAPI_FUNC(int) _Py_HandleSystemExit(int *exitcode_p);

Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_embed.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'module_search_paths': GET_DEFAULT_CONFIG,
'module_search_paths_set': 1,
'platlibdir': sys.platlibdir,
'stdlib_dir': GET_DEFAULT_CONFIG,

'site_import': 1,
'bytes_warning': 0,
Expand Down Expand Up @@ -515,6 +516,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
'exec_prefix',
'program_name',
'home',
'stdlib_dir',
# program_full_path and module_search_path are copied indirectly from
# the core configuration in check_path_config().
]
Expand Down Expand Up @@ -1142,6 +1144,9 @@ def test_init_setpath(self):
'base_prefix': '',
'exec_prefix': '',
'base_exec_prefix': '',
# The current getpath.c doesn't determine the stdlib dir
# in this case.
'stdlib_dir': '',
}
self.default_program_name(config)
env = {'TESTPATH': os.path.pathsep.join(paths)}
Expand All @@ -1162,6 +1167,9 @@ def test_init_setpath_config(self):
'base_prefix': '',
'exec_prefix': '',
'base_exec_prefix': '',
# The current getpath.c doesn't determine the stdlib dir
# in this case.
'stdlib_dir': '',
# overriden by PyConfig
'program_name': 'conf_program_name',
'base_executable': 'conf_executable',
Expand Down Expand Up @@ -1251,6 +1259,7 @@ def test_init_setpythonhome(self):
'exec_prefix': exec_prefix,
'base_exec_prefix': exec_prefix,
'pythonpath_env': paths_str,
'stdlib_dir': home,
}
self.default_program_name(config)
env = {'TESTHOME': home, 'PYTHONPATH': paths_str}
Expand Down Expand Up @@ -1288,6 +1297,9 @@ def test_init_pybuilddir(self):
'base_executable': executable,
'executable': executable,
'module_search_paths': module_search_paths,
# The current getpath.c doesn't determine the stdlib dir
# in this case.
'stdlib_dir': None,
}
env = self.copy_paths_by_env(config)
self.check_all_configs("test_init_compat_config", config,
Expand Down Expand Up @@ -1345,6 +1357,7 @@ def test_init_pyvenv_cfg(self):
if MS_WINDOWS:
config['base_prefix'] = pyvenv_home
config['prefix'] = pyvenv_home
config['stdlib_dir'] = os.path.join(pyvenv_home, 'lib')

ver = sys.version_info
dll = f'python{ver.major}'
Expand All @@ -1353,6 +1366,10 @@ def test_init_pyvenv_cfg(self):
dll += '.DLL'
dll = os.path.join(os.path.dirname(executable), dll)
path_config['python3_dll'] = dll
else:
# The current getpath.c doesn't determine the stdlib dir
# in this case.
config['stdlib_dir'] = None

env = self.copy_paths_by_env(config)
self.check_all_configs("test_init_compat_config", config,
Expand Down
10 changes: 10 additions & 0 deletions Lib/test/test_sys.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from test.support import os_helper
from test.support.script_helper import assert_python_ok, assert_python_failure
from test.support import threading_helper
from test.support import import_helper
import textwrap
import unittest
import warnings
Expand Down Expand Up @@ -994,6 +995,15 @@ def test_module_names(self):
for name in sys.stdlib_module_names:
self.assertIsInstance(name, str)

def test_stdlib_dir(self):
os = import_helper.import_fresh_module('os')
marker = getattr(os, '__file__', None)
if marker and not os.path.exists(marker):
marker = None
expected = os.path.dirname(marker) if marker else None
actual = sys._stdlib_dir
self.assertEqual(actual, expected)


@test.support.cpython_only
class UnraisableHookTest(unittest.TestCase):
Expand Down
10 changes: 10 additions & 0 deletions Modules/getpath.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -1492,6 +1492,16 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
}
}

if (pathconfig->stdlib_dir == NULL) {
if (calculate->prefix_found) {
/* This must be done *before* calculate_set_prefix() is called. */
pathconfig->stdlib_dir = _PyMem_RawWcsdup(calculate->prefix);
if (pathconfig->stdlib_dir == NULL) {
return _PyStatus_NO_MEMORY();
}
}
}

if (pathconfig->prefix == NULL) {
status = calculate_set_prefix(calculate, pathconfig);
if (_PyStatus_EXCEPTION(status)) {
Expand Down
12 changes: 10 additions & 2 deletions PC/getpathp.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@
* with a semicolon separated path prior to calling Py_Initialize.
*/

#define STDLIB_SUBDIR L"lib"

#define INIT_ERR_BUFFER_OVERFLOW() _PyStatus_ERR("buffer overflow")


Expand Down Expand Up @@ -293,12 +295,12 @@ search_for_prefix(wchar_t *prefix, const wchar_t *argv0_path)
wcscpy_s(stdlibdir, Py_ARRAY_LENGTH(stdlibdir), prefix);
/* We initialize with the longest possible path, in case it doesn't fit.
This also gives us an initial SEP at stdlibdir[wcslen(prefix)]. */
join(stdlibdir, L"lib");
join(stdlibdir, STDLIB_SUBDIR);
do {
assert(stdlibdir[wcslen(prefix)] == SEP);
/* Due to reduce() and our initial value, this result
is guaranteed to fit. */
wcscpy(&stdlibdir[wcslen(prefix) + 1], L"lib");
wcscpy(&stdlibdir[wcslen(prefix) + 1], STDLIB_SUBDIR);
if (is_stdlibdir(stdlibdir)) {
return 1;
}
Expand Down Expand Up @@ -1013,6 +1015,12 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
}

done:
if (pathconfig->stdlib_dir == NULL) {
pathconfig->stdlib_dir = _Py_join_relfile(prefix, STDLIB_SUBDIR);
if (pathconfig->stdlib_dir == NULL) {
return _PyStatus_NO_MEMORY();
}
}
if (pathconfig->prefix == NULL) {
pathconfig->prefix = _PyMem_RawWcsdup(prefix);
if (pathconfig->prefix == NULL) {
Expand Down
5 changes: 5 additions & 0 deletions Python/initconfig.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,7 @@ PyConfig_Clear(PyConfig *config)
_PyWideStringList_Clear(&config->xoptions);
_PyWideStringList_Clear(&config->module_search_paths);
config->module_search_paths_set = 0;
CLEAR(config->stdlib_dir);

CLEAR(config->executable);
CLEAR(config->base_executable);
Expand Down Expand Up @@ -909,6 +910,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
COPY_WSTRLIST(xoptions);
COPY_WSTRLIST(module_search_paths);
COPY_ATTR(module_search_paths_set);
COPY_WSTR_ATTR(stdlib_dir);

COPY_WSTR_ATTR(executable);
COPY_WSTR_ATTR(base_executable);
Expand Down Expand Up @@ -1015,6 +1017,7 @@ _PyConfig_AsDict(const PyConfig *config)
SET_ITEM_WSTR(home);
SET_ITEM_INT(module_search_paths_set);
SET_ITEM_WSTRLIST(module_search_paths);
SET_ITEM_WSTR(stdlib_dir);
SET_ITEM_WSTR(executable);
SET_ITEM_WSTR(base_executable);
SET_ITEM_WSTR(prefix);
Expand Down Expand Up @@ -1318,6 +1321,7 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict)
// Path configuration output
GET_UINT(module_search_paths_set);
GET_WSTRLIST(module_search_paths);
GET_WSTR_OPT(stdlib_dir);
GET_WSTR_OPT(executable);
GET_WSTR_OPT(base_executable);
GET_WSTR_OPT(prefix);
Expand Down Expand Up @@ -3094,6 +3098,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
PySys_WriteStderr(" environment = %i\n", config->use_environment);
PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
PySys_WriteStderr(" import site = %i\n", config->site_import);
DUMP_CONFIG("stdlib dir", stdlib_dir);
#undef DUMP_CONFIG

#define DUMP_SYS(NAME) \
Expand Down
31 changes: 30 additions & 1 deletion Python/pathconfig.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pathconfig_clear(_PyPathConfig *config)
CLEAR(config->program_full_path);
CLEAR(config->prefix);
CLEAR(config->exec_prefix);
CLEAR(config->stdlib_dir);
CLEAR(config->module_search_path);
CLEAR(config->program_name);
CLEAR(config->home);
Expand Down Expand Up @@ -83,6 +84,7 @@ pathconfig_copy(_PyPathConfig *config, const _PyPathConfig *config2)
COPY_ATTR(prefix);
COPY_ATTR(exec_prefix);
COPY_ATTR(module_search_path);
COPY_ATTR(stdlib_dir);
COPY_ATTR(program_name);
COPY_ATTR(home);
#ifdef MS_WINDOWS
Expand Down Expand Up @@ -167,6 +169,7 @@ pathconfig_set_from_config(_PyPathConfig *pathconfig, const PyConfig *config)
COPY_CONFIG(program_full_path, executable);
COPY_CONFIG(prefix, prefix);
COPY_CONFIG(exec_prefix, exec_prefix);
COPY_CONFIG(stdlib_dir, stdlib_dir);
COPY_CONFIG(program_name, program_name);
COPY_CONFIG(home, home);
#ifdef MS_WINDOWS
Expand Down Expand Up @@ -218,6 +221,7 @@ _PyPathConfig_AsDict(void)
SET_ITEM_STR(prefix);
SET_ITEM_STR(exec_prefix);
SET_ITEM_STR(module_search_path);
SET_ITEM_STR(stdlib_dir);
SET_ITEM_STR(program_name);
SET_ITEM_STR(home);
#ifdef MS_WINDOWS
Expand Down Expand Up @@ -311,6 +315,7 @@ config_init_module_search_paths(PyConfig *config, _PyPathConfig *pathconfig)

- exec_prefix
- module_search_path
- stdlib_dir
- prefix
- program_full_path

Expand Down Expand Up @@ -401,6 +406,7 @@ config_init_pathconfig(PyConfig *config, int compute_path_config)
COPY_ATTR(program_full_path, executable);
COPY_ATTR(prefix, prefix);
COPY_ATTR(exec_prefix, exec_prefix);
COPY_ATTR(stdlib_dir, stdlib_dir);

#undef COPY_ATTR

Expand Down Expand Up @@ -486,16 +492,25 @@ Py_SetPath(const wchar_t *path)

PyMem_RawFree(_Py_path_config.prefix);
PyMem_RawFree(_Py_path_config.exec_prefix);
PyMem_RawFree(_Py_path_config.stdlib_dir);
PyMem_RawFree(_Py_path_config.module_search_path);

_Py_path_config.prefix = _PyMem_RawWcsdup(L"");
_Py_path_config.exec_prefix = _PyMem_RawWcsdup(L"");
// XXX Copy this from the new module_search_path?
if (_Py_path_config.home != NULL) {
_Py_path_config.stdlib_dir = _PyMem_RawWcsdup(_Py_path_config.home);
}
else {
_Py_path_config.stdlib_dir = _PyMem_RawWcsdup(L"");
}
_Py_path_config.module_search_path = _PyMem_RawWcsdup(path);

PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

if (_Py_path_config.prefix == NULL
|| _Py_path_config.exec_prefix == NULL
|| _Py_path_config.stdlib_dir == NULL
|| _Py_path_config.module_search_path == NULL)
{
path_out_of_memory(__func__);
Expand All @@ -515,10 +530,13 @@ Py_SetPythonHome(const wchar_t *home)

PyMem_RawFree(_Py_path_config.home);
_Py_path_config.home = _PyMem_RawWcsdup(home);
if (_Py_path_config.home != NULL) {
_Py_path_config.stdlib_dir = _PyMem_RawWcsdup(home);
}

PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

if (_Py_path_config.home == NULL) {
if (_Py_path_config.home == NULL || _Py_path_config.stdlib_dir == NULL) {
path_out_of_memory(__func__);
}
}
Expand Down Expand Up @@ -572,6 +590,17 @@ Py_GetPath(void)
}


wchar_t *
_Py_GetStdlibDir(void)
{
wchar_t *stdlib_dir = _Py_path_config.stdlib_dir;
if (stdlib_dir != NULL && stdlib_dir[0] != L'\0') {
return stdlib_dir;
}
return NULL;
}


wchar_t *
Py_GetPrefix(void)
{
Expand Down
8 changes: 8 additions & 0 deletions Python/sysmodule.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -2974,6 +2974,14 @@ _PySys_UpdateConfig(PyThreadState *tstate)

SET_SYS("_xoptions", sys_create_xoptions_dict(config));

const wchar_t *stdlibdir = _Py_GetStdlibDir();
if (stdlibdir != NULL) {
SET_SYS_FROM_WSTR("_stdlib_dir", stdlibdir);
}
else {
PyDict_SetItemString(sysdict, "_stdlib_dir", Py_None);
}

#undef SET_SYS_FROM_WSTR
#undef COPY_LIST
#undef COPY_WSTR
Expand Down

Back | FazBrowse Home | New Git URL