[Python-checkins] bpo-43284: Update platform.win32_ver to use _syscmd_ver instead of sys.getwindowsversion() (GH-25500)

miss-islington webhook-mailer at python.org
Thu Apr 22 13:03:45 EDT 2021


https://github.com/python/cpython/commit/ef63328b46fe7402794cde51008a47e79f37b153
commit: ef63328b46fe7402794cde51008a47e79f37b153
branch: 3.8
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2021-04-22T10:03:36-07:00
summary:

bpo-43284: Update platform.win32_ver to use _syscmd_ver instead of sys.getwindowsversion() (GH-25500)


The sys module uses the kernel32.dll version number, which can vary from the "actual" Windows version.
Since the best option for getting the version is WMI (which is expensive), we switch back to launching cmd.exe (which is also expensive, but a lot less code on our part).
sys.getwindowsversion() is not updated to avoid launching executables from that module.
(cherry picked from commit 2a3f4899c63806439e5bcea0c30f7e6a6295a763)

Co-authored-by: Shreyan Avigyan <shreyan.avigyan at gmail.com>

files:
A Misc/NEWS.d/next/Library/2021-04-21-14-50-57.bpo-43284.2QZn2T.rst
M Doc/library/sys.rst
M Lib/platform.py

diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 95cbaf2f033ea1..7e11dc0c499d14 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -778,11 +778,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
diff --git a/Lib/platform.py b/Lib/platform.py
index 994d892c5e6166..b7e7bc439e0a90 100755
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -236,11 +236,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
 
@@ -362,17 +360,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:
@@ -381,8 +382,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:
diff --git a/Misc/NEWS.d/next/Library/2021-04-21-14-50-57.bpo-43284.2QZn2T.rst b/Misc/NEWS.d/next/Library/2021-04-21-14-50-57.bpo-43284.2QZn2T.rst
new file mode 100644
index 00000000000000..7e41016015efed
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-04-21-14-50-57.bpo-43284.2QZn2T.rst
@@ -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.



More information about the Python-checkins mailing list