diff --git a/Lib/platform.py b/Lib/platform.py index 36489d4fdd98ae..5a63ce9504e264 100644 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -427,11 +427,16 @@ def _win32_ver(version, csd, ptype): winver = getwindowsversion() is_client = (getattr(winver, 'product_type', 1) == 1) - try: - version = _syscmd_ver()[2] - major, minor, build = map(int, version.split('.')) - except ValueError: - major, minor, build = winver.platform_version or winver[:3] + + if winver.device_family == "Desktop": + try: + version = _syscmd_ver()[2] + major, minor, build = map(int, version.split('.')) + except ValueError: + major, minor, build = winver.platform_version or winver[:3] + version = '{0}.{1}.{2}'.format(major, minor, build) + else: + major, minor, build = winver[:3] version = '{0}.{1}.{2}'.format(major, minor, build) # getwindowsversion() reflect the compatibility mode Python is diff --git a/Misc/NEWS.d/next/Windows/2026-06-29-17-17-10.gh-issue-152433.AhW--j.rst b/Misc/NEWS.d/next/Windows/2026-06-29-17-17-10.gh-issue-152433.AhW--j.rst new file mode 100644 index 00000000000000..47f4ff689bd60a --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-06-29-17-17-10.gh-issue-152433.AhW--j.rst @@ -0,0 +1,2 @@ +Fix errors in :func:`sys.getwindowsversion` for Universal Windows Platform +build. diff --git a/Python/sysmodule.c b/Python/sysmodule.c index d9f7b9c449cfb9..7f14531999d928 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1633,6 +1633,7 @@ static PyStructSequence_Field windows_version_fields[] = { {"suite_mask", "Bit mask identifying available product suites"}, {"product_type", "System product type"}, {"platform_version", "Diagnostic version number"}, + {"device_family", "Desktop or UWP"}, {0} }; @@ -1645,13 +1646,10 @@ static PyStructSequence_Desc windows_version_desc = { via indexing, the rest are name only */ }; +#ifdef MS_WINDOWS_DESKTOP static PyObject * _sys_getwindowsversion_from_kernel32(void) { -#ifndef MS_WINDOWS_DESKTOP - PyErr_SetString(PyExc_OSError, "cannot read version info on this platform"); - return NULL; -#else HANDLE hKernel32; wchar_t kernel32_path[MAX_PATH]; LPVOID verblock; @@ -1688,8 +1686,8 @@ _sys_getwindowsversion_from_kernel32(void) realBuild = HIWORD(ffi->dwProductVersionLS); PyMem_RawFree(verblock); return Py_BuildValue("(kkk)", realMajor, realMinor, realBuild); -#endif /* !MS_WINDOWS_DESKTOP */ } +#endif /* MS_WINDOWS_DESKTOP */ /* Disable deprecation warnings about GetVersionEx as the result is being passed straight through to the caller, who is responsible for @@ -1719,7 +1717,6 @@ sys_getwindowsversion_impl(PyObject *module) { PyObject *version; int pos = 0; - OSVERSIONINFOEXW ver; if (PyObject_GetOptionalAttrString(module, "_cached_windows_version", &version) < 0) { return NULL; @@ -1729,6 +1726,8 @@ sys_getwindowsversion_impl(PyObject *module) } Py_XDECREF(version); + OSVERSIONINFOEXW ver; + ZeroMemory(&ver, sizeof(ver)); ver.dwOSVersionInfoSize = sizeof(ver); if (!GetVersionExW((OSVERSIONINFOW*) &ver)) return PyErr_SetFromWindowsErr(0); @@ -1756,10 +1755,12 @@ sys_getwindowsversion_impl(PyObject *module) SET_VERSION_INFO(PyLong_FromLong(ver.wSuiteMask)); SET_VERSION_INFO(PyLong_FromLong(ver.wProductType)); +#ifdef MS_WINDOWS_DESKTOP // GetVersion will lie if we are running in a compatibility mode. // We need to read the version info from a system file resource // to accurately identify the OS version. If we fail for any reason, // just return whatever GetVersion said. + // UWP return correct version from GetVersionExW, this is not necessary. PyObject *realVersion = _sys_getwindowsversion_from_kernel32(); if (!realVersion) { if (!PyErr_ExceptionMatches(PyExc_WindowsError)) { @@ -1775,6 +1776,11 @@ sys_getwindowsversion_impl(PyObject *module) } SET_VERSION_INFO(realVersion); + SET_VERSION_INFO(PyUnicode_FromString("Desktop")); +#else + SET_VERSION_INFO(Py_BuildValue("(kkk)", ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber)); + SET_VERSION_INFO(PyUnicode_FromString("UWP")); +#endif #undef SET_VERSION_INFO