@@ -1643,12 +1643,13 @@ sys_getwindowsversion_impl(PyObject *module)
16431643 int pos = 0 ;
16441644 OSVERSIONINFOEXW ver ;
16451645
1646- version = PyObject_GetAttrString (module , "_cached_windows_version" );
1646+ if (PyObject_GetOptionalAttrString (module , "_cached_windows_version" , & version ) < 0 ) {
1647+ return NULL ;
1648+ };
16471649 if (version && PyObject_TypeCheck (version , & WindowsVersionType )) {
16481650 return version ;
16491651 }
16501652 Py_XDECREF (version );
1651- PyErr_Clear ();
16521653
16531654 ver .dwOSVersionInfoSize = sizeof (ver );
16541655 if (!GetVersionExW ((OSVERSIONINFOW * ) & ver ))
@@ -1658,22 +1659,35 @@ sys_getwindowsversion_impl(PyObject *module)
16581659 if (version == NULL )
16591660 return NULL ;
16601661
1661- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .dwMajorVersion ));
1662- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .dwMinorVersion ));
1663- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .dwBuildNumber ));
1664- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .dwPlatformId ));
1665- PyStructSequence_SET_ITEM (version , pos ++ , PyUnicode_FromWideChar (ver .szCSDVersion , -1 ));
1666- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .wServicePackMajor ));
1667- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .wServicePackMinor ));
1668- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .wSuiteMask ));
1669- PyStructSequence_SET_ITEM (version , pos ++ , PyLong_FromLong (ver .wProductType ));
1662+ #define SET_VERSION_INFO (CALL ) \
1663+ do { \
1664+ PyObject *item = (CALL); \
1665+ if (item == NULL) { \
1666+ goto error; \
1667+ } \
1668+ PyStructSequence_SET_ITEM(version, pos++, item); \
1669+ } while(0)
1670+
1671+ SET_VERSION_INFO (PyLong_FromLong (ver .dwMajorVersion ));
1672+ SET_VERSION_INFO (PyLong_FromLong (ver .dwMinorVersion ));
1673+ SET_VERSION_INFO (PyLong_FromLong (ver .dwBuildNumber ));
1674+ SET_VERSION_INFO (PyLong_FromLong (ver .dwPlatformId ));
1675+ SET_VERSION_INFO (PyUnicode_FromWideChar (ver .szCSDVersion , -1 ));
1676+ SET_VERSION_INFO (PyLong_FromLong (ver .wServicePackMajor ));
1677+ SET_VERSION_INFO (PyLong_FromLong (ver .wServicePackMinor ));
1678+ SET_VERSION_INFO (PyLong_FromLong (ver .wSuiteMask ));
1679+ SET_VERSION_INFO (PyLong_FromLong (ver .wProductType ));
16701680
16711681 // GetVersion will lie if we are running in a compatibility mode.
16721682 // We need to read the version info from a system file resource
16731683 // to accurately identify the OS version. If we fail for any reason,
16741684 // just return whatever GetVersion said.
16751685 PyObject * realVersion = _sys_getwindowsversion_from_kernel32 ();
16761686 if (!realVersion ) {
1687+ if (!PyErr_ExceptionMatches (PyExc_WindowsError )) {
1688+ return NULL ;
1689+ }
1690+
16771691 PyErr_Clear ();
16781692 realVersion = Py_BuildValue ("(kkk)" ,
16791693 ver .dwMajorVersion ,
@@ -1682,21 +1696,19 @@ sys_getwindowsversion_impl(PyObject *module)
16821696 );
16831697 }
16841698
1685- if (realVersion ) {
1686- PyStructSequence_SET_ITEM (version , pos ++ , realVersion );
1687- }
1699+ SET_VERSION_INFO (realVersion );
16881700
1689- if (PyErr_Occurred ()) {
1690- Py_DECREF (version );
1691- return NULL ;
1692- }
1701+ #undef SET_VERSION_INFO
16931702
16941703 if (PyObject_SetAttrString (module , "_cached_windows_version" , version ) < 0 ) {
1695- Py_DECREF (version );
1696- return NULL ;
1704+ goto error ;
16971705 }
16981706
16991707 return version ;
1708+
1709+ error :
1710+ Py_DECREF (version );
1711+ return NULL ;
17001712}
17011713
17021714#pragma warning(pop)
0 commit comments