Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit38af903

Browse files
authored
gh-91985: Ensure in-tree builds override platstdlib_dir in every path calculation (GH-93641)
1 parentf8e576b commit38af903

File tree

4 files changed

+125
-2
lines changed

4 files changed

+125
-2
lines changed

‎Lib/test/test_embed.py‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,66 @@ def test_init_setpythonhome(self):
13031303
self.check_all_configs("test_init_setpythonhome",config,
13041304
api=API_COMPAT,env=env)
13051305

1306+
deftest_init_is_python_build_with_home(self):
1307+
# Test _Py_path_config._is_python_build configuration (gh-91985)
1308+
config=self._get_expected_config()
1309+
paths=config['config']['module_search_paths']
1310+
paths_str=os.path.pathsep.join(paths)
1311+
1312+
forpathinpaths:
1313+
ifnotos.path.isdir(path):
1314+
continue
1315+
ifos.path.exists(os.path.join(path,'os.py')):
1316+
home=os.path.dirname(path)
1317+
break
1318+
else:
1319+
self.fail(f"Unable to find home in{paths!r}")
1320+
1321+
prefix=exec_prefix=home
1322+
ifMS_WINDOWS:
1323+
stdlib=os.path.join(home,"Lib")
1324+
# Because we are specifying 'home', module search paths
1325+
# are fairly static
1326+
expected_paths= [paths[0],stdlib,os.path.join(home,'DLLs')]
1327+
else:
1328+
version=f'{sys.version_info.major}.{sys.version_info.minor}'
1329+
stdlib=os.path.join(home,sys.platlibdir,f'python{version}')
1330+
expected_paths=self.module_search_paths(prefix=home,exec_prefix=home)
1331+
1332+
config= {
1333+
'home':home,
1334+
'module_search_paths':expected_paths,
1335+
'prefix':prefix,
1336+
'base_prefix':prefix,
1337+
'exec_prefix':exec_prefix,
1338+
'base_exec_prefix':exec_prefix,
1339+
'pythonpath_env':paths_str,
1340+
'stdlib_dir':stdlib,
1341+
}
1342+
# The code above is taken from test_init_setpythonhome()
1343+
env= {'TESTHOME':home,'PYTHONPATH':paths_str}
1344+
1345+
env['NEGATIVE_ISPYTHONBUILD']='1'
1346+
config['_is_python_build']=0
1347+
self.check_all_configs("test_init_is_python_build",config,
1348+
api=API_COMPAT,env=env)
1349+
1350+
env['NEGATIVE_ISPYTHONBUILD']='0'
1351+
config['_is_python_build']=1
1352+
exedir=os.path.dirname(sys.executable)
1353+
withopen(os.path.join(exedir,'pybuilddir.txt'),encoding='utf8')asf:
1354+
expected_paths[2]=os.path.normpath(
1355+
os.path.join(exedir,f'{f.read()}\n$'.splitlines()[0]))
1356+
ifnotMS_WINDOWS:
1357+
# PREFIX (default) is set when running in build directory
1358+
prefix=exec_prefix=sys.prefix
1359+
# stdlib calculation (/Lib) is not yet supported
1360+
expected_paths[0]=self.module_search_paths(prefix=prefix)[0]
1361+
config.update(prefix=prefix,base_prefix=prefix,
1362+
exec_prefix=exec_prefix,base_exec_prefix=exec_prefix)
1363+
self.check_all_configs("test_init_is_python_build",config,
1364+
api=API_COMPAT,env=env)
1365+
13061366
defcopy_paths_by_env(self,config):
13071367
all_configs=self._get_expected_config()
13081368
paths=all_configs['config']['module_search_paths']

‎Modules/getpath.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,8 @@ def search_up(prefix, *landmarks, test=isfile):
461461

462462
build_prefix=None
463463

464-
ifnothome_was_setandreal_executable_dirandnotpy_setpath:
464+
if ((nothome_was_setandreal_executable_dirandnotpy_setpath)
465+
orconfig.get('_is_python_build',0)>0):
465466
# Detect a build marker and use it to infer prefix, exec_prefix,
466467
# stdlib_dir and the platstdlib_dir directories.
467468
try:

‎Programs/_testembed.c‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,46 @@ static int test_init_setpythonhome(void)
15501550
}
15511551

15521552

1553+
staticinttest_init_is_python_build(void)
1554+
{
1555+
// gh-91985: in-tree builds fail to check for build directory landmarks
1556+
// under the effect of 'home' or PYTHONHOME environment variable.
1557+
char*env=getenv("TESTHOME");
1558+
if (!env) {
1559+
error("missing TESTHOME env var");
1560+
return1;
1561+
}
1562+
wchar_t*home=Py_DecodeLocale(env,NULL);
1563+
if (home==NULL) {
1564+
error("failed to decode TESTHOME");
1565+
return1;
1566+
}
1567+
1568+
PyConfigconfig;
1569+
_PyConfig_InitCompatConfig(&config);
1570+
config_set_program_name(&config);
1571+
config_set_string(&config,&config.home,home);
1572+
PyMem_RawFree(home);
1573+
putenv("TESTHOME=");
1574+
1575+
// Use an impossible value so we can detect whether it isn't updated
1576+
// during initialization.
1577+
config._is_python_build=INT_MAX;
1578+
env=getenv("NEGATIVE_ISPYTHONBUILD");
1579+
if (env&&strcmp(env,"0")!=0) {
1580+
config._is_python_build++;
1581+
}
1582+
init_from_config_clear(&config);
1583+
Py_Finalize();
1584+
// Second initialization
1585+
config._is_python_build=-1;
1586+
init_from_config_clear(&config);
1587+
dump_config();// home and _is_python_build are cached in _Py_path_config
1588+
Py_Finalize();
1589+
return0;
1590+
}
1591+
1592+
15531593
staticinttest_init_warnoptions(void)
15541594
{
15551595
putenv("PYTHONWARNINGS=ignore:::env1,ignore:::env2");
@@ -1965,6 +2005,7 @@ static struct TestCase TestCases[] = {
19652005
{"test_init_setpath",test_init_setpath},
19662006
{"test_init_setpath_config",test_init_setpath_config},
19672007
{"test_init_setpythonhome",test_init_setpythonhome},
2008+
{"test_init_is_python_build",test_init_is_python_build},
19682009
{"test_init_warnoptions",test_init_warnoptions},
19692010
{"test_init_set_config",test_init_set_config},
19702011
{"test_run_main",test_run_main},

‎Python/pathconfig.c‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ typedef struct _PyPathConfig {
3636
wchar_t*program_name;
3737
/* Set by Py_SetPythonHome() or PYTHONHOME environment variable */
3838
wchar_t*home;
39+
int_is_python_build;
3940
}_PyPathConfig;
4041

4142
# define_PyPathConfig_INIT \
42-
{.module_search_path = NULL}
43+
{.module_search_path = NULL, ._is_python_build = 0}
4344

4445

4546
_PyPathConfig_Py_path_config=_PyPathConfig_INIT;
@@ -72,6 +73,7 @@ _PyPathConfig_ClearGlobal(void)
7273
CLEAR(calculated_module_search_path);
7374
CLEAR(program_name);
7475
CLEAR(home);
76+
_Py_path_config._is_python_build=0;
7577

7678
#undef CLEAR
7779

@@ -99,15 +101,25 @@ _PyPathConfig_ReadGlobal(PyConfig *config)
99101
} \
100102
} while (0)
101103

104+
#defineCOPY_INT(ATTR) \
105+
do { \
106+
assert(_Py_path_config.ATTR >= 0); \
107+
if ((_Py_path_config.ATTR >= 0) && (config->ATTR <= 0)) { \
108+
config->ATTR = _Py_path_config.ATTR; \
109+
} \
110+
} while (0)
111+
102112
COPY(prefix);
103113
COPY(exec_prefix);
104114
COPY(stdlib_dir);
105115
COPY(program_name);
106116
COPY(home);
107117
COPY2(executable,program_full_path);
118+
COPY_INT(_is_python_build);
108119
// module_search_path must be initialised - not read
109120
#undef COPY
110121
#undef COPY2
122+
#undef COPY_INT
111123

112124
done:
113125
returnstatus;
@@ -137,14 +149,23 @@ _PyPathConfig_UpdateGlobal(const PyConfig *config)
137149
} \
138150
} while (0)
139151

152+
#defineCOPY_INT(ATTR) \
153+
do { \
154+
if (config->ATTR > 0) { \
155+
_Py_path_config.ATTR = config->ATTR; \
156+
} \
157+
} while (0)
158+
140159
COPY(prefix);
141160
COPY(exec_prefix);
142161
COPY(stdlib_dir);
143162
COPY(program_name);
144163
COPY(home);
145164
COPY2(program_full_path,executable);
165+
COPY_INT(_is_python_build);
146166
#undef COPY
147167
#undef COPY2
168+
#undef COPY_INT
148169

149170
PyMem_RawFree(_Py_path_config.module_search_path);
150171
_Py_path_config.module_search_path=NULL;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp