Index: Doc/library/sys.rst =================================================================== --- Doc/library/sys.rst (revision 77710) +++ Doc/library/sys.rst (working copy) @@ -471,8 +471,12 @@ .. function:: getwindowsversion() Return a tuple containing five components, describing the Windows version - currently running. The elements are *major*, *minor*, *build*, *platform*, and - *text*. *text* contains a string while all other values are integers. + currently running. The elements are *major*, *minor*, *build*, + *platform*, and *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`` *platform* may be one of the following values: @@ -488,12 +492,15 @@ | :const:`3 (VER_PLATFORM_WIN32_CE)` | Windows CE | +-----------------------------------------+-------------------------+ - This function wraps the Win32 :cfunc:`GetVersionEx` function; see the Microsoft - documentation for more information about these fields. + This function wraps the Win32 :cfunc:`GetVersionEx` function; see the + Microsoft documentation on :cfunc:`OSVERSIONINFOEX` for more information + about these fields. Availability: Windows. .. versionadded:: 2.3 + .. versionchanged:: 2.7 + Added named component attributes .. data:: hexversion Index: Lib/test/test_sys.py =================================================================== --- Lib/test/test_sys.py (revision 77710) +++ Lib/test/test_sys.py (working copy) @@ -205,13 +205,35 @@ def test_getwindowsversion(self): if hasattr(sys, "getwindowsversion"): v = sys.getwindowsversion() - self.assertTrue(isinstance(v, tuple)) - self.assertEqual(len(v), 5) + self.assertTrue(isinstance(v[:], tuple)) + self.assertEqual(len(v), 9) self.assertTrue(isinstance(v[0], int)) self.assertTrue(isinstance(v[1], int)) self.assertTrue(isinstance(v[2], int)) self.assertTrue(isinstance(v[3], int)) self.assertTrue(isinstance(v[4], str)) + self.assertTrue(isinstance(v[5], int)) + self.assertTrue(isinstance(v[6], int)) + self.assertTrue(isinstance(v[7], int)) + self.assertTrue(isinstance(v[8], int)) + self.assertTrue(isinstance(v.major, int)) + self.assertTrue(isinstance(v.minor, int)) + self.assertTrue(isinstance(v.build, int)) + self.assertTrue(isinstance(v.platform, int)) + self.assertTrue(isinstance(v.service_pack, str)) + self.assertTrue(isinstance(v.service_pack_minor, int)) + self.assertTrue(isinstance(v.service_pack_major, int)) + self.assertTrue(isinstance(v.suite_mask, int)) + self.assertTrue(isinstance(v.product_type, int)) + 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) + self.assertEqual(v[5], v.service_pack_major) + self.assertEqual(v[6], v.service_pack_minor) + self.assertEqual(v[7], v.suite_mask) + self.assertEqual(v[8], v.product_type) def test_dlopenflags(self): if hasattr(sys, "setdlopenflags"): Index: Python/sysmodule.c =================================================================== --- Python/sysmodule.c (revision 77710) +++ Python/sysmodule.c (working copy) @@ -564,19 +564,53 @@ " ); +static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 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 */ + 9 +}; + static PyObject * sys_getwindowsversion(PyObject *self) { - OSVERSIONINFO ver; + PyObject *version; + int pos = 0; + OSVERSIONINFOEX ver; ver.dwOSVersionInfoSize = sizeof(ver); - if (!GetVersionEx(&ver)) + if (!GetVersionEx((OSVERSIONINFO*) &ver)) return PyErr_SetFromWindowsErr(0); - return Py_BuildValue("HHHHs", - ver.dwMajorVersion, - ver.dwMinorVersion, - ver.dwBuildNumber, - ver.dwPlatformId, - ver.szCSDVersion); + + version = PyStructSequence_New(&WindowsVersionType); + if (version == NULL) + return NULL; + + 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 */ @@ -1499,6 +1533,13 @@ FlagsType.tp_init = NULL; FlagsType.tp_new = NULL; + /* 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; + /* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */ #ifndef PY_NO_SHORT_FLOAT_REPR SET_SYS_FROM_STRING("float_repr_style",