"""Return the path of pyconfig.h."""
if _PYTHON_BUILD:
if os.name == "nt":
- # This ought to be as simple as dirname(sys._base_executable), but
- # if a venv uses symlinks to a build in the source tree, then this
- # fails. So instead we guess the subdirectory name from sys.winver
- if sys.winver.endswith('-32'):
- arch = 'win32'
- elif sys.winver.endswith('-arm64'):
- arch = 'arm64'
- else:
- arch = 'amd64'
- inc_dir = os.path.join(_PROJECT_BASE, 'PCbuild', arch)
+ inc_dir = os.path.dirname(sys._base_executable)
else:
inc_dir = _PROJECT_BASE
else:
def check_output(cmd, encoding=None):
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
+ stderr=subprocess.PIPE,
+ env={**os.environ, "PYTHONHOME": ""})
out, err = p.communicate()
if p.returncode:
if verbose and err:
cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call
out, err = check_output(cmd, encoding='utf-8')
self.assertEqual(out.strip(), expected, err)
+ for attr, expected in (
+ ('executable', self.envpy()),
+ # Usually compare to sys.executable, but if we're running in our own
+ # venv then we really need to compare to our base executable
+ ('_base_executable', sys._base_executable),
+ ):
+ with self.subTest(attr):
+ cmd[2] = f'import sys; print(sys.{attr})'
+ out, err = check_output(cmd, encoding='utf-8')
+ self.assertEqual(out.strip(), expected, err)
@requireVenvCreate
@unittest.skipUnless(can_symlink(), 'Needs symlinks')
cmd[2] = 'import sysconfig; print(sysconfig.%s)' % call
out, err = check_output(cmd, encoding='utf-8')
self.assertEqual(out.strip(), expected, err)
+ for attr, expected in (
+ ('executable', self.envpy()),
+ # Usually compare to sys.executable, but if we're running in our own
+ # venv then we really need to compare to our base executable
+ ('_base_executable', sys._base_executable),
+ ):
+ with self.subTest(attr):
+ cmd[2] = f'import sys; print(sys.{attr})'
+ out, err = check_output(cmd, encoding='utf-8')
+ self.assertEqual(out.strip(), expected, err)
if sys.platform == 'win32':
ENV_SUBDIRS = (
PyMem_Free((void *)path);
PyMem_Free((void *)narrow);
return r;
+#elif defined(MS_WINDOWS)
+ HANDLE hFile;
+ wchar_t resolved[MAXPATHLEN+1];
+ int len = 0, err;
+ PyObject *result;
+
+ wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
+ if (!path) {
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ hFile = CreateFileW(path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hFile != INVALID_HANDLE_VALUE) {
+ len = GetFinalPathNameByHandleW(hFile, resolved, MAXPATHLEN, VOLUME_NAME_DOS);
+ err = len ? 0 : GetLastError();
+ CloseHandle(hFile);
+ } else {
+ err = GetLastError();
+ }
+ Py_END_ALLOW_THREADS
+
+ if (err) {
+ PyErr_SetFromWindowsErr(err);
+ result = NULL;
+ } else if (len <= MAXPATHLEN) {
+ const wchar_t *p = resolved;
+ if (0 == wcsncmp(p, L"\\\\?\\", 4)) {
+ if (GetFileAttributesW(&p[4]) != INVALID_FILE_ATTRIBUTES) {
+ p += 4;
+ len -= 4;
+ }
+ }
+ result = PyUnicode_FromWideChar(p, len);
+ } else {
+ result = Py_NewRef(pathobj);
+ }
+ PyMem_Free(path);
+ return result;
#endif
return Py_NewRef(pathobj);