From 3bc6847d99b56b49418c341d3aca3eaa4abd2879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Wed, 26 Oct 2022 14:17:52 +0100 Subject: [PATCH 1/2] gh-98718: add sys.build_prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Doc/library/sys.rst | 9 +++++++++ Include/cpython/initconfig.h | 1 + Lib/sysconfig.py | 7 ++----- Lib/test/test_sys.py | 1 + .../2022-11-09-03-07-26.gh-issue-98718.rY4eIr.rst | 2 ++ Modules/getpath.py | 3 +++ Python/initconfig.c | 5 +++++ Python/sysmodule.c | 1 + 8 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-11-09-03-07-26.gh-issue-98718.rY4eIr.rst diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 17bbfa50a2ed02..5c19c6cce4d8a6 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -144,6 +144,15 @@ always available. .. versionadded:: 3.3 +.. data:: build_prefix + + Set during Python startup, before ``site.py`` is run. If running Python from + source, the value will be set to the build path, otherwise it will be set to + :const:`None`. + + .. versionadded:: 3.12 + + .. data:: byteorder An indicator of the native byte order. This will have the value ``'big'`` on diff --git a/Include/cpython/initconfig.h b/Include/cpython/initconfig.h index 64748cf78beb72..85f58bfb697af5 100644 --- a/Include/cpython/initconfig.h +++ b/Include/cpython/initconfig.h @@ -197,6 +197,7 @@ typedef struct PyConfig { wchar_t *base_prefix; wchar_t *exec_prefix; wchar_t *base_exec_prefix; + wchar_t *build_prefix; /* --- Parameter only used by Py_Main() ---------- */ int skip_source_first_line; diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index 73c25684db20c9..c88f97959b3eee 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -226,12 +226,9 @@ def is_python_build(check_home=None): import warnings warnings.warn("check_home argument is deprecated and ignored.", DeprecationWarning, stacklevel=2) - for fn in ("Setup", "Setup.local"): - if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): - return True - return False + return bool(sys.build_prefix) -_PYTHON_BUILD = is_python_build() +_PYTHON_BUILD = bool(sys.build_prefix) if _PYTHON_BUILD: for scheme in ('posix_prefix', 'posix_home'): diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 9184e9a42f1941..7164a790bf4238 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -603,6 +603,7 @@ def test_attributes(self): self.assertIsInstance(sys.platform, str) self.assertIsInstance(sys.prefix, str) self.assertIsInstance(sys.base_prefix, str) + self.assertIsInstance(sys.build_prefix, (str, None)) self.assertIsInstance(sys.platlibdir, str) self.assertIsInstance(sys.version, str) vi = sys.version_info diff --git a/Misc/NEWS.d/next/Library/2022-11-09-03-07-26.gh-issue-98718.rY4eIr.rst b/Misc/NEWS.d/next/Library/2022-11-09-03-07-26.gh-issue-98718.rY4eIr.rst new file mode 100644 index 00000000000000..bd7bd9636c0510 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-09-03-07-26.gh-issue-98718.rY4eIr.rst @@ -0,0 +1,2 @@ +:mod:`sys` now exports :attr:`sys.build_prefix`, with the path of the Python +build directory, if any. diff --git a/Modules/getpath.py b/Modules/getpath.py index e3558bc49e389f..8e96f03a17cb7f 100644 --- a/Modules/getpath.py +++ b/Modules/getpath.py @@ -509,6 +509,9 @@ def search_up(prefix, *landmarks, test=isfile): config['_is_python_build'] = 1 +config['build_prefix'] = build_prefix + + # ****************************************************************************** # CALCULATE prefix AND exec_prefix # ****************************************************************************** diff --git a/Python/initconfig.c b/Python/initconfig.c index 4b784290b014d2..ea7b114e9ebea6 100644 --- a/Python/initconfig.c +++ b/Python/initconfig.c @@ -731,6 +731,7 @@ PyConfig_Clear(PyConfig *config) CLEAR(config->base_prefix); CLEAR(config->exec_prefix); CLEAR(config->base_exec_prefix); + CLEAR(config->build_prefix); CLEAR(config->platlibdir); CLEAR(config->filesystem_encoding); @@ -985,6 +986,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2) COPY_WSTR_ATTR(base_prefix); COPY_WSTR_ATTR(exec_prefix); COPY_WSTR_ATTR(base_exec_prefix); + COPY_WSTR_ATTR(build_prefix); COPY_WSTR_ATTR(platlibdir); COPY_ATTR(site_import); @@ -1094,6 +1096,7 @@ _PyConfig_AsDict(const PyConfig *config) SET_ITEM_WSTR(base_prefix); SET_ITEM_WSTR(exec_prefix); SET_ITEM_WSTR(base_exec_prefix); + SET_ITEM_WSTR(build_prefix); SET_ITEM_WSTR(platlibdir); SET_ITEM_INT(site_import); SET_ITEM_INT(bytes_warning); @@ -1407,6 +1410,7 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict) GET_WSTR_OPT(base_prefix); GET_WSTR_OPT(exec_prefix); GET_WSTR_OPT(base_exec_prefix); + GET_WSTR_OPT(build_prefix); GET_UINT(skip_source_first_line); GET_WSTR_OPT(run_command); @@ -3172,6 +3176,7 @@ _Py_DumpPathConfig(PyThreadState *tstate) DUMP_SYS(_base_executable); DUMP_SYS(base_prefix); DUMP_SYS(base_exec_prefix); + DUMP_SYS(build_prefix); DUMP_SYS(platlibdir); DUMP_SYS(executable); DUMP_SYS(prefix); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index f73d332796c986..d73722b96955b4 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -3317,6 +3317,7 @@ _PySys_UpdateConfig(PyThreadState *tstate) COPY_WSTR("exec_prefix", config->exec_prefix); COPY_WSTR("base_exec_prefix", config->base_exec_prefix); COPY_WSTR("platlibdir", config->platlibdir); + COPY_WSTR("build_prefix", config->build_prefix); if (config->pycache_prefix != NULL) { SET_SYS_FROM_WSTR("pycache_prefix", config->pycache_prefix); From 622eccabfbac7627f9cd5a50ac868b77a51e4f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Wed, 9 Nov 2022 14:40:44 +0000 Subject: [PATCH 2/2] fix test_embed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Lib/test/test_embed.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/test_embed.py b/Lib/test/test_embed.py index f622d443257f0f..c13f9397d13ada 100644 --- a/Lib/test/test_embed.py +++ b/Lib/test/test_embed.py @@ -783,6 +783,9 @@ def check_all_configs(self, testname, expected_config=None, except json.JSONDecodeError: self.fail(f"fail to decode stdout: {out!r}") + # build_prefix depends on if Python was installed, ignore it here + configs['config'].pop('build_prefix', None) + self.check_pre_config(configs, expected_preconfig) self.check_config(configs, expected_config) self.check_global_config(configs)