GeezerVison is showing github.com — gh-152433: Windows: fix errors in sys.getwindowsversion() for UWP build by thexai · Pull Request #152604 · python/cpython
Conversation
thexai
commented
Jun 29, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Fixes errors in sys.getwindowsversion() only for UWP build, not changes behavior in Windows desktop.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
For more context, the actual issue with sys.getwindowsversion() is that return incorrect value in recent Windows 11 versions:
e.g: in Windows 11 25H2 return 10.0.26100 instead of correct 10.0.26200.
(but not directly observable because only is used as second fallback on platform module)
With this change, it will be possible use sys.getwindowsversion() as the first fallback (after WMI) and will also be compatible with UWP.
In UWP, it would be the primary method because WMI is not available and subprocess "cmd ver" is also not available.
Related to #129294
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
thexai
changed the title
gh-152433: Windows: improve sys.getwindowsversion() use RtlGetVersion for Desktop
gh-152433: Windows: improve sys.getwindowsversion(), use RtlGetVersion() and allow build for UWP
Jul 23, 2026
Uh oh!
There was an error while loading. Please reload this page.
|
Updated with alternative fix:
// Obtain the build number from Windows registry in case of Windows 10/11
if (realMajor == 10 && realMinor == 0) {
wchar_t currentBuild[32] = {0};
DWORD len = sizeof(currentBuild);
if (ERROR_SUCCESS == RegGetValueW(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION, L"CurrentBuild",
RRF_RT_REG_SZ, NULL, ¤tBuild, &len))
{
realBuild = _wtol(currentBuild);
}
}
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
thexai
changed the title
gh-152433: Windows: improve sys.getwindowsversion(), use RtlGetVersion() and allow build for UWP
gh-152433: Windows: improve sys.getwindowsversion(), fix return incorrect build number for Windows 11+ and fix errors in UWP
Jul 24, 2026
the point of this API is to find out what OS features are available, and if you're under compatibility shims, they may not be. In that case, getting the "real" version is going to be a lie.
So the right answer to "what version should I assume is running" is the one that GetVersion returns.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Okay, we'll take it one step at a time...
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
thexai
changed the title
gh-152433: Windows: improve sys.getwindowsversion(), fix return incorrect build number for Windows 11+ and fix errors in UWP
gh-152433: Windows: fix errors in sys.getwindowsversion() for UWP build
Jul 24, 2026
|
PR updated: only fixes things in UWP build, not touches anything in regular Windows desktop build.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Updated with alternative fix:
Is that Registry key actually documented? If not, using it directly seems at least as bad as using RtlGetVersion (i.e., not very, in my opinion, but if RtlGetVersion is considered problematic, I don't really see why touching Registry directly would be better).
|
zooba reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
// 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();
|
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 #if block should be removed and replaced with the #else and we're just not doing it yet (unless you want to do it now?)
Sorry, something went wrong.
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.
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.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
thexai
Jul 28, 2026
•
edited
Loading
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:
{"service_pack", "Latest Service Pack installed on the system"},
{"service_pack_major", "Service Pack major version number"},
{"service_pack_minor", "Service Pack minor version number"},
{"suite_mask", "Bit mask identifying available product suites"},
{"product_type", "System product type"},
Current method should return current relevant info, e.g
Windows 11 25H2 10.0.26200.8875
25H2 --> 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:
// get the system version number
auto sv = AnalyticsInfo::VersionInfo().DeviceFamilyVersion();
wchar_t* end;
unsigned long long v = wcstoull(sv.c_str(), &end, 10);
unsigned long long v1 = (v & 0xFFFF000000000000L) >> 48;
unsigned long long v2 = (v & 0x0000FFFF00000000L) >> 32;
unsigned long long v3 = (v & 0x00000000FFFF0000L) >> 16;
unsigned long long v4 = (v & 0x000000000000FFFFL);
kernelVersionFull = StringUtils::Format("{}.{}.{}", v1, v2, v3);
if (v4)
kernelVersionFull += StringUtils::Format(".{}", v4);
Sorry, something went wrong.
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.
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 sys module is "what conditions is this Python runtime running under". For the platform module it's "what is installed on this machine". That's why the platform module 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.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
|
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"));
|
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.
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 MS_WINDOWS_APP, and then we should also handle MS_WINDOWS_SYSTEM and MS_WINDOWS_GAMES.
Sorry, something went wrong.
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.
MS_WINDOWS_SYSTEM is only for build system drivers/services and it doesn't seem relevant to Python or applications that has Python embedded. I don't think it needs to be defined, and I believe the instances where it appears should be removed from the code.
MS_WINDOWS_GAMES is only for Xbox Games and it's another flavor of UWP.
MS_WINDOWS_APP is for Xbox Apps and formerly also for "Windows Phone" (which no longer exists). It has the peculiarity (or complication) that it's also defined when compiling for Desktop (because Universal Apps can run also on Desktop).
Then maybe define names "Desktop" "UWP-Games" and "UWP-Apps" or even better:
"Desktop" "Xbox" "UWP" (because MS_WINDOWS_APP is still "universal").
Sorry, something went wrong.
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.
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".
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
thexai reacted with thumbs up emoji
If not, using it directly seems at least as bad as using RtlGetVersion (i.e., not very, in my opinion, but if RtlGetVersion is considered problematic, I don't really see why touching Registry directly would be better).
Agreed, it's on the same level as ntdll. We don't need either approach - GetVersion[Ex] is the right behaviour here, and I think the only reason we explored alternatives was because platform relied on this function rather than WMI (that was added later).
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
This is enough of an improvement over the current code that I'll merge it. Then I'll file a new issue to fully remove _sys_getwindowsversion_from_kernel32 and use the same code for all API partitions.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️
Hi! The buildbot AMD64 Fedora Stable 3.x (tier-1) has failed when building commit af49df9.
What do you need to do:
- Don't panic.
- Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
- Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/543/builds/10312) and take a look at the build logs.
- Check if the failure is related to this commit (af49df9) or if it is a false positive.
- If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.
You can take a look at the buildbot page here:
https://buildbot.python.org/#/builders/543/builds/10312
Summary of the results of the build (if available):
Click to see traceback logs
Note: switching to 'af49df919dafc3767ae956767dce0482f9cd6d4e'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at af49df919dafc gh-152433: Fix errors in sys.getwindowsversion() for UWP build (GH-152604)
Switched to and reset branch 'main'
configure: WARNING: unrecognized options: --with-system-libmpdec
configure: WARNING: unrecognized options: --with-system-libmpdec
/tmp/ccCSacpP.s: Assembler messages:
/tmp/ccCSacpP.s: Fatal error: can't write 8 bytes to section .debug_loclists of Modules/xxlimited_3_13.o: 'No space left on device'
/tmp/ccCSacpP.s: Fatal error: Modules/xxlimited_3_13.o: No such file or directory
make: *** [Makefile:3931: Modules/xxlimited_3_13.o] Error 1
make: *** Waiting for unfinished jobs....
/tmp/cc2rpz45.s: Assembler messages:
/tmp/cc2rpz45.s: Fatal error: can't write 333 bytes to section .gnu.lto_Example_Type_slots.18.dc398c4adf0d60a3 of Modules/_testmultiphase.o: 'No space left on device'
/tmp/cc2rpz45.s: Fatal error: Modules/_testmultiphase.o: No such file or directory
make: *** [Makefile:3921: Modules/_testmultiphase.o] Error 1
/usr/bin/ld.bfd: final link failed: No space left on device
collect2: error: ld returned 1 exit status
make: *** [Makefile:3675: Modules/_bisect.cpython-316d-x86_64-linux-gnu.so] Error 1
/usr/bin/ld.bfd: final link failed: No space left on device
collect2: error: ld returned 1 exit status
make: *** [Makefile:3673: Modules/array.cpython-316d-x86_64-linux-gnu.so] Error 1
/tmp/ccB8pDql.s: Assembler messages:
/tmp/ccB8pDql.s: Fatal error: can't write 564 bytes to section .data of Programs/_testembed.o: 'No space left on device'
/tmp/ccB8pDql.s: Fatal error: Programs/_testembed.o: No such file or directory
make: *** [Makefile:2077: Programs/_testembed.o] Error 1
/tmp/ccdnnZZC.s: Assembler messages:
/tmp/ccdnnZZC.s: Fatal error: can't write 64 bytes to section .text of Modules/_testlimitedcapi/unicode.o: 'No space left on device'
/tmp/ccdnnZZC.s: Fatal error: Modules/_testlimitedcapi/unicode.o: No such file or directory
make: *** [Makefile:3907: Modules/_testlimitedcapi/unicode.o] Error 1
/tmp/ccaK0bFK.s: Assembler messages:
/tmp/ccaK0bFK.s: Fatal error: can't write 48 bytes to section .text of Modules/_testclinic.o: 'No space left on device'
/tmp/ccaK0bFK.s: Fatal error: Modules/_testclinic.o: No such file or directory
make: *** [Makefile:3915: Modules/_testclinic.o] Error 1
/tmp/ccBx7sjz.s: Assembler messages:
/tmp/ccBx7sjz.s: Fatal error: can't write 117 bytes to section .text of Modules/_testinternalcapi/interpreter.o: 'No space left on device'
/tmp/ccBx7sjz.s: Fatal error: Modules/_testinternalcapi/interpreter.o: No such file or directory
make: *** [Makefile:3840: Modules/_testinternalcapi/interpreter.o] Error 1
/tmp/cc8DRUyJ.s: Assembler messages:
/tmp/cc8DRUyJ.s: Fatal error: can't write 32 bytes to section .text of Modules/_ctypes/_ctypes_test.o: 'No space left on device'
/tmp/cc8DRUyJ.s: Fatal error: Modules/_ctypes/_ctypes_test.o: No such file or directory
make: *** [Makefile:3925: Modules/_ctypes/_ctypes_test.o] Error 1
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️
Hi! The buildbot AMD64 Fedora Stable Clang 3.x (tier-2) has failed when building commit af49df9.
What do you need to do:
- Don't panic.
- Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
- Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/441/builds/10278) and take a look at the build logs.
- Check if the failure is related to this commit (af49df9) or if it is a false positive.
- If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.
You can take a look at the buildbot page here:
https://buildbot.python.org/#/builders/441/builds/10278
Summary of the results of the build (if available):
Click to see traceback logs
Note: switching to 'af49df919dafc3767ae956767dce0482f9cd6d4e'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at af49df919dafc gh-152433: Fix errors in sys.getwindowsversion() for UWP build (GH-152604)
Switched to and reset branch 'main'
rror: unable to open output file 'Modules/_testcapi/exceptions.o': 'No space left on device'
1 error generated.
rror: unable to open output file 'Modules/_ssl.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3863: Modules/_testcapi/exceptions.o] Error 1
make: *** Waiting for unfinished jobs....
make: *** [Makefile:3818: Modules/_ssl.o] Error 1
rror: unable to open output file 'Modules/_testcapi/file.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3868: Modules/_testcapi/file.o] Error 1
rror: unable to open output file 'Modules/_testcapi/codec.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3869: Modules/_testcapi/codec.o] Error 1
rror: unable to open output file 'Modules/_testcapi/gc.o': 'No space left on device'
1 error generated.
rror: unable to open output file 'Modules/_testcapi/immortal.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3871: Modules/_testcapi/gc.o] Error 1
make: *** [Makefile:3870: Modules/_testcapi/immortal.o] Error 1
rror: unable to open output file 'Modules/_testcapi/run.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3867: Modules/_testcapi/run.o] Error 1
rror: unable to open output file 'Modules/_testcapi/pyatomic.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3866: Modules/_testcapi/pyatomic.o] Error 1
rror: unable to open output file 'Python/ceval.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3392: Python/ceval.o] Error 1
rror: unable to open output file 'Modules/_testinternalcapi/interpreter.o': 'No space left on device'
1 error generated.
make: *** [Makefile:3840: Modules/_testinternalcapi/interpreter.o] Error 1
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make: [Makefile:3476: clean-retain-profile] Error 1 (ignored)
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
zooba
zooba left review comments
ericsnowcurrently
Awaiting requested review from ericsnowcurrently
ericsnowcurrently is a code owner
+1 more reviewer
Reviewers whose approvals may not affect merge requirements
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|