-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
gh-152433: Windows: fix errors in sys.getwindowsversion() for UWP build #152604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
5dab92e
ce0d374
0428b7d
0f69920
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Fix errors in :func:`sys.getwindowsversion` for Universal Windows Platform | ||
| build. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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")); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we're going to do this (which I like, tbqh), then we should handle all the API partitions that we have checks for, rather than assuming that anything "not DESKTOP" is UWP. I believe the UWP case is covered by
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Then maybe define names "Desktop" "UWP-Games" and "UWP-Apps" or even better: "Desktop" "Xbox" "UWP" (because MS_WINDOWS_APP is still "universal").
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What you've changed here looks fine to me. It wouldn't surprise me if one day we regret using "Xbox" instead of "Games", but that day is likely to be a long way out, and it won't be any worse than places where we used "darwin" instead of "macos". |
||
| #endif | ||
|
|
||
| #undef SET_VERSION_INFO | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well add a comment saying that this whole
#ifblock should be removed and replaced with the#elseand we're just not doing it yet (unless you want to do it now?)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not really sure what to do here... all the proposed options have been rejected, and the main goal wasn't really to improve things for Windows Desktop... keep in mind that if this is removed without adding an alternative, things will be much worse, as it will return that it's running on Windows 8 in many cases for embedded applications.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nowadays most fields here are obsolete:
Current method should return current relevant info, e.g
Windows 11 25H2 10.0.26200.887525H2 --> is missing and can be obtained from registry.
8875 --> (UBR update build revision) is missing and can be obtained from registry and API for UWP:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, nowadays most feature checks involving the version number are incorrect, which is why the compatibility shims on the version number are important - they're more likely to affect the ones that actually apply.
An embedding app that isn't properly manifested should get the version number the OS intends to give it. This is why it's designed this way. The rejected proposals were all ways to circumvent this, but we don't want to circumvent it.
The "current relevant info" for the
sysmodule is "what conditions is this Python runtime running under". For theplatformmodule it's "what is installed on this machine". That's why theplatformmodule does extra work to get the real version, while this function should get the most applicable version, which Windows has decided should be changed for the sake of compatibility.