Skip to content

bpo-43284: Update platform.win32_ver to use platform._syscmd_ver instead of sys.getwindowsversion().platform_version for determining accurate Windows version #25500

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

Merged
merged 12 commits into from
Apr 22, 2021
Merged
7 changes: 6 additions & 1 deletion Doc/library/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -796,11 +796,16 @@ always available.
Microsoft documentation on :c:func:`OSVERSIONINFOEX` for more information
about these fields.

*platform_version* returns the accurate major version, minor version and
*platform_version* returns the major version, minor version and
build number of the current operating system, rather than the version that
is being emulated for the process. It is intended for use in logging rather
than for feature detection.

.. note::
*platform_version* derives the version from kernel32.dll which can be of a different
version than the OS version. Please use :mod:`platform` module for achieving accurate
OS version.

.. availability:: Windows.

.. versionchanged:: 3.2
Expand Down
21 changes: 11 additions & 10 deletions Lib/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,9 @@ def _norm_version(version, build=''):
if build:
l.append(build)
try:
ints = map(int, l)
strings = list(map(str, map(int, l)))
except ValueError:
strings = l
else:
strings = list(map(str, ints))
version = '.'.join(strings[:3])
return version

Expand Down Expand Up @@ -365,17 +363,20 @@ def win32_ver(release='', version='', csd='', ptype=''):
return release, version, csd, ptype

winver = getwindowsversion()
maj, min, build = winver.platform_version or winver[:3]
version = '{0}.{1}.{2}'.format(maj, min, build)
try:
major, minor, build = map(int, _syscmd_ver()[2].split('.'))
except ValueError:
major, minor, build = winver.platform_version or winver[:3]
version = '{0}.{1}.{2}'.format(major, minor, build)

release = (_WIN32_CLIENT_RELEASES.get((maj, min)) or
_WIN32_CLIENT_RELEASES.get((maj, None)) or
release = (_WIN32_CLIENT_RELEASES.get((major, minor)) or
_WIN32_CLIENT_RELEASES.get((major, None)) or
release)

# getwindowsversion() reflect the compatibility mode Python is
# running under, and so the service pack value is only going to be
# valid if the versions match.
if winver[:2] == (maj, min):
if winver[:2] == (major, minor):
try:
csd = 'SP{}'.format(winver.service_pack_major)
except AttributeError:
Expand All @@ -384,8 +385,8 @@ def win32_ver(release='', version='', csd='', ptype=''):

# VER_NT_SERVER = 3
if getattr(winver, 'product_type', None) == 3:
release = (_WIN32_SERVER_RELEASES.get((maj, min)) or
_WIN32_SERVER_RELEASES.get((maj, None)) or
release = (_WIN32_SERVER_RELEASES.get((major, minor)) or
_WIN32_SERVER_RELEASES.get((major, None)) or
release)

try:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
platform.win32_ver derives the windows version from
sys.getwindowsversion().platform_version which in turn derives the version
from kernel32.dll (which can be of a different version than Windows itself).
Therefore change the platform.win32_ver to determine the version using the
platform module's _syscmd_ver private function to return an accurate
version.