mirror of
https://github.com/python/cpython.git
synced 2025-07-29 06:05:00 +00:00
Issue #7766: Change sys.getwindowsversion() return value to a named tuple and add the additional members returned in an OSVERSIONINFOEX structure. The new members are service_pack_major, service_pack_minor, suite_mask, and product_type.
This commit is contained in:
parent
92e68af56a
commit
ee931b7253
4 changed files with 114 additions and 19 deletions
|
@ -470,9 +470,15 @@ always available.
|
||||||
|
|
||||||
.. function:: getwindowsversion()
|
.. function:: getwindowsversion()
|
||||||
|
|
||||||
Return a tuple containing five components, describing the Windows version
|
Return a named tuple containing describing the Windows version
|
||||||
currently running. The elements are *major*, *minor*, *build*, *platform*, and
|
currently running. The named elements are *major*, *minor*,
|
||||||
*text*. *text* contains a string while all other values are integers.
|
*build*, *platform*, *service_pack*, *service_pack_minor*,
|
||||||
|
*service_pack_major*, *suite_mask*, and *product_type*.
|
||||||
|
*service_pack* contains a string while all other values are
|
||||||
|
integers. The components can also be accessed by name, so
|
||||||
|
``sys.getwindowsversion()[0]`` is equivalent to
|
||||||
|
``sys.getwindowsversion().major``. For compatibility with prior
|
||||||
|
versions, only the first 5 elements are retrievable by indexing.
|
||||||
|
|
||||||
*platform* may be one of the following values:
|
*platform* may be one of the following values:
|
||||||
|
|
||||||
|
@ -488,12 +494,31 @@ always available.
|
||||||
| :const:`3 (VER_PLATFORM_WIN32_CE)` | Windows CE |
|
| :const:`3 (VER_PLATFORM_WIN32_CE)` | Windows CE |
|
||||||
+-----------------------------------------+-------------------------+
|
+-----------------------------------------+-------------------------+
|
||||||
|
|
||||||
This function wraps the Win32 :cfunc:`GetVersionEx` function; see the Microsoft
|
*product_type* may be one of the following values:
|
||||||
documentation for more information about these fields.
|
|
||||||
|
+---------------------------------------+---------------------------------+
|
||||||
|
| Constant | Meaning |
|
||||||
|
+=======================================+=================================+
|
||||||
|
| :const:`1 (VER_NT_WORKSTATION)` | The system is a workstation. |
|
||||||
|
+---------------------------------------+---------------------------------+
|
||||||
|
| :const:`2 (VER_NT_DOMAIN_CONTROLLER)` | The system is a domain |
|
||||||
|
| | controller. |
|
||||||
|
+---------------------------------------+---------------------------------+
|
||||||
|
| :const:`3 (VER_NT_SERVER)` | The system is a server, but not |
|
||||||
|
| | a domain controller. |
|
||||||
|
+---------------------------------------+---------------------------------+
|
||||||
|
|
||||||
|
|
||||||
|
This function wraps the Win32 :cfunc:`GetVersionEx` function; see the
|
||||||
|
Microsoft documentation on :cfunc:`OSVERSIONINFOEX` for more information
|
||||||
|
about these fields.
|
||||||
|
|
||||||
Availability: Windows.
|
Availability: Windows.
|
||||||
|
|
||||||
.. versionadded:: 2.3
|
.. versionadded:: 2.3
|
||||||
|
.. versionchanged:: 2.7
|
||||||
|
Changed to a named tuple and added *service_pack_minor*,
|
||||||
|
*service_pack_major*, *suite_mask*, and *product_type*.
|
||||||
|
|
||||||
|
|
||||||
.. data:: hexversion
|
.. data:: hexversion
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import unittest, test.test_support
|
import unittest, test.test_support
|
||||||
import sys, cStringIO, os
|
import sys, cStringIO, os
|
||||||
import struct
|
import struct
|
||||||
|
import operator
|
||||||
|
|
||||||
class SysModuleTest(unittest.TestCase):
|
class SysModuleTest(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -205,13 +206,28 @@ class SysModuleTest(unittest.TestCase):
|
||||||
def test_getwindowsversion(self):
|
def test_getwindowsversion(self):
|
||||||
if hasattr(sys, "getwindowsversion"):
|
if hasattr(sys, "getwindowsversion"):
|
||||||
v = sys.getwindowsversion()
|
v = sys.getwindowsversion()
|
||||||
self.assertIsInstance(v, tuple)
|
self.assertTrue(isinstance(v[:], tuple))
|
||||||
self.assertEqual(len(v), 5)
|
self.assertEqual(len(v), 5)
|
||||||
self.assertIsInstance(v[0], int)
|
self.assertIsInstance(v[0], int)
|
||||||
self.assertIsInstance(v[1], int)
|
self.assertIsInstance(v[1], int)
|
||||||
self.assertIsInstance(v[2], int)
|
self.assertIsInstance(v[2], int)
|
||||||
self.assertIsInstance(v[3], int)
|
self.assertIsInstance(v[3], int)
|
||||||
self.assertIsInstance(v[4], str)
|
self.assertIsInstance(v[4], str)
|
||||||
|
self.assertRaises(IndexError, operator.getitem, v, 5)
|
||||||
|
self.assertIsInstance(v.major, int)
|
||||||
|
self.assertIsInstance(v.minor, int)
|
||||||
|
self.assertIsInstance(v.build, int)
|
||||||
|
self.assertIsInstance(v.platform, int)
|
||||||
|
self.assertIsInstance(v.service_pack, str)
|
||||||
|
self.assertEqual(v[0], v.major)
|
||||||
|
self.assertEqual(v[1], v.minor)
|
||||||
|
self.assertEqual(v[2], v.build)
|
||||||
|
self.assertEqual(v[3], v.platform)
|
||||||
|
self.assertEqual(v[4], v.service_pack)
|
||||||
|
|
||||||
|
# This is how platform.py calls it. Make sure tuple
|
||||||
|
# still has 5 elements
|
||||||
|
maj, min, buildno, plat, csd = sys.getwindowsversion()
|
||||||
|
|
||||||
def test_dlopenflags(self):
|
def test_dlopenflags(self):
|
||||||
if hasattr(sys, "setdlopenflags"):
|
if hasattr(sys, "setdlopenflags"):
|
||||||
|
|
|
@ -12,6 +12,11 @@ What's New in Python 2.7 alpha 3?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- Issue #7766: Change sys.getwindowsversion() return value to a named
|
||||||
|
tuple and add the additional members returned in an OSVERSIONINFOEX
|
||||||
|
structure. The new members are service_pack_major, service_pack_minor,
|
||||||
|
suite_mask, and product_type.
|
||||||
|
|
||||||
- Issue #7561: Operations on empty bytearrays (such as `int(bytearray())`)
|
- Issue #7561: Operations on empty bytearrays (such as `int(bytearray())`)
|
||||||
could crash in many places because of the PyByteArray_AS_STRING() macro
|
could crash in many places because of the PyByteArray_AS_STRING() macro
|
||||||
returning NULL. The macro now returns a statically allocated empty
|
returning NULL. The macro now returns a statically allocated empty
|
||||||
|
|
|
@ -557,26 +557,65 @@ recursion from causing an overflow of the C stack and crashing Python."
|
||||||
PyDoc_STRVAR(getwindowsversion_doc,
|
PyDoc_STRVAR(getwindowsversion_doc,
|
||||||
"getwindowsversion()\n\
|
"getwindowsversion()\n\
|
||||||
\n\
|
\n\
|
||||||
Return information about the running version of Windows.\n\
|
Return information about the running version of Windows as a named tuple.\n\
|
||||||
The result is a tuple of (major, minor, build, platform, text)\n\
|
The members are named: major, minor, build, platform, service_pack,\n\
|
||||||
All elements are numbers, except text which is a string.\n\
|
service_pack_major, service_pack_minor, suite_mask, and product_type. For\n\
|
||||||
Platform may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP\n\
|
backward compatibiliy, only the first 5 items are available by indexing.\n\
|
||||||
"
|
All elements are numbers, except service_pack which is a string. Platform\n\
|
||||||
|
may be 0 for win32s, 1 for Windows 9x/ME, 2 for Windows NT/2000/XP/Vista/7,\n\
|
||||||
|
3 for Windows CE. Product_type may be 1 for a workstation, 2 for a domain\n\
|
||||||
|
controller, 3 for a server."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
static PyStructSequence_Field windows_version_fields[] = {
|
||||||
|
{"major", "Major version number"},
|
||||||
|
{"minor", "Minor version number"},
|
||||||
|
{"build", "Build number"},
|
||||||
|
{"platform", "Operating system platform"},
|
||||||
|
{"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"},
|
||||||
|
{0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyStructSequence_Desc windows_version_desc = {
|
||||||
|
"sys.getwindowsversion", /* name */
|
||||||
|
getwindowsversion_doc, /* doc */
|
||||||
|
windows_version_fields, /* fields */
|
||||||
|
5 /* For backward compatibility,
|
||||||
|
only the first 5 items are accessible
|
||||||
|
via indexing, the rest are name only */
|
||||||
|
};
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
sys_getwindowsversion(PyObject *self)
|
sys_getwindowsversion(PyObject *self)
|
||||||
{
|
{
|
||||||
OSVERSIONINFO ver;
|
PyObject *version;
|
||||||
|
int pos = 0;
|
||||||
|
OSVERSIONINFOEX ver;
|
||||||
ver.dwOSVersionInfoSize = sizeof(ver);
|
ver.dwOSVersionInfoSize = sizeof(ver);
|
||||||
if (!GetVersionEx(&ver))
|
if (!GetVersionEx((OSVERSIONINFO*) &ver))
|
||||||
return PyErr_SetFromWindowsErr(0);
|
return PyErr_SetFromWindowsErr(0);
|
||||||
return Py_BuildValue("HHHHs",
|
|
||||||
ver.dwMajorVersion,
|
version = PyStructSequence_New(&WindowsVersionType);
|
||||||
ver.dwMinorVersion,
|
if (version == NULL)
|
||||||
ver.dwBuildNumber,
|
return NULL;
|
||||||
ver.dwPlatformId,
|
|
||||||
ver.szCSDVersion);
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwMajorVersion));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwMinorVersion));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwBuildNumber));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.dwPlatformId));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyString_FromString(ver.szCSDVersion));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wServicePackMajor));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wServicePackMinor));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wSuiteMask));
|
||||||
|
PyStructSequence_SET_ITEM(version, pos++, PyInt_FromLong(ver.wProductType));
|
||||||
|
|
||||||
|
return version;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
|
@ -1499,6 +1538,16 @@ _PySys_Init(void)
|
||||||
FlagsType.tp_init = NULL;
|
FlagsType.tp_init = NULL;
|
||||||
FlagsType.tp_new = NULL;
|
FlagsType.tp_new = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(MS_WINDOWS)
|
||||||
|
/* getwindowsversion */
|
||||||
|
if (WindowsVersionType.tp_name == 0)
|
||||||
|
PyStructSequence_InitType(&WindowsVersionType, &windows_version_desc);
|
||||||
|
/* prevent user from creating new instances */
|
||||||
|
WindowsVersionType.tp_init = NULL;
|
||||||
|
WindowsVersionType.tp_new = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
|
/* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
|
||||||
#ifndef PY_NO_SHORT_FLOAT_REPR
|
#ifndef PY_NO_SHORT_FLOAT_REPR
|
||||||
SET_SYS_FROM_STRING("float_repr_style",
|
SET_SYS_FROM_STRING("float_repr_style",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue