@@ -1048,7 +1048,7 @@ maxsize -- the largest supported length of containers.\n\
10481048maxunicode -- the largest supported character\n\
10491049builtin_module_names -- tuple of module names built into this interpreter\n\
10501050version -- the version of this interpreter as a string\n\
1051- version_info -- version information as a tuple\n\
1051+ version_info -- version information as a named tuple\n\
10521052hexversion -- version information encoded as a single integer\n\
10531053copyright -- copyright notice pertaining to this interpreter\n\
10541054platform -- platform identifier\n\
@@ -1279,6 +1279,75 @@ make_flags(void)
12791279 return seq ;
12801280}
12811281
1282+ PyDoc_STRVAR (version_info__doc__ ,
1283+ "sys.version_info\n\
1284+ \n\
1285+ Version information as a named tuple." );
1286+
1287+ static PyTypeObject VersionInfoType = {0 , 0 , 0 , 0 , 0 , 0 };
1288+
1289+ static PyStructSequence_Field version_info_fields [] = {
1290+ {"major" , "Major release number" },
1291+ {"minor" , "Minor release number" },
1292+ {"micro" , "Patch release number" },
1293+ {"releaselevel" , "'alpha', 'beta', 'candidate', or 'release'" },
1294+ {"serial" , "Serial release number" },
1295+ {0 }
1296+ };
1297+
1298+ static PyStructSequence_Desc version_info_desc = {
1299+ "sys.version_info" , /* name */
1300+ version_info__doc__ , /* doc */
1301+ version_info_fields , /* fields */
1302+ 5
1303+ };
1304+
1305+ static PyObject *
1306+ make_version_info (void )
1307+ {
1308+ PyObject * version_info ;
1309+ char * s ;
1310+ int pos = 0 ;
1311+
1312+ version_info = PyStructSequence_New (& VersionInfoType );
1313+ if (version_info == NULL ) {
1314+ return NULL ;
1315+ }
1316+
1317+ /*
1318+ * These release level checks are mutually exclusive and cover
1319+ * the field, so don't get too fancy with the pre-processor!
1320+ */
1321+ #if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
1322+ s = "alpha" ;
1323+ #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
1324+ s = "beta" ;
1325+ #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
1326+ s = "candidate" ;
1327+ #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
1328+ s = "final" ;
1329+ #endif
1330+
1331+ #define SetIntItem (flag ) \
1332+ PyStructSequence_SET_ITEM(version_info, pos++, PyInt_FromLong(flag))
1333+ #define SetStrItem (flag ) \
1334+ PyStructSequence_SET_ITEM(version_info, pos++, PyString_FromString(flag))
1335+
1336+ SetIntItem (PY_MAJOR_VERSION );
1337+ SetIntItem (PY_MINOR_VERSION );
1338+ SetIntItem (PY_MICRO_VERSION );
1339+ SetStrItem (s );
1340+ SetIntItem (PY_RELEASE_SERIAL );
1341+ #undef SetIntItem
1342+ #undef SetStrItem
1343+
1344+ if (PyErr_Occurred ()) {
1345+ Py_CLEAR (version_info );
1346+ return NULL ;
1347+ }
1348+ return version_info ;
1349+ }
1350+
12821351PyObject *
12831352_PySys_Init (void )
12841353{
@@ -1354,25 +1423,6 @@ _PySys_Init(void)
13541423 svn_revision ));
13551424 SET_SYS_FROM_STRING ("dont_write_bytecode" ,
13561425 PyBool_FromLong (Py_DontWriteBytecodeFlag ));
1357- /*
1358- * These release level checks are mutually exclusive and cover
1359- * the field, so don't get too fancy with the pre-processor!
1360- */
1361- #if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
1362- s = "alpha" ;
1363- #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
1364- s = "beta" ;
1365- #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
1366- s = "candidate" ;
1367- #elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
1368- s = "final" ;
1369- #endif
1370-
1371- SET_SYS_FROM_STRING ("version_info" ,
1372- Py_BuildValue ("iiisi" , PY_MAJOR_VERSION ,
1373- PY_MINOR_VERSION ,
1374- PY_MICRO_VERSION , s ,
1375- PY_RELEASE_SERIAL ));
13761426 SET_SYS_FROM_STRING ("api_version" ,
13771427 PyInt_FromLong (PYTHON_API_VERSION ));
13781428 SET_SYS_FROM_STRING ("copyright" ,
@@ -1429,6 +1479,15 @@ _PySys_Init(void)
14291479 PyDict_SetItemString (sysdict , "warnoptions" , warnoptions );
14301480 }
14311481
1482+ /* version_info */
1483+ if (VersionInfoType .tp_name == 0 )
1484+ PyStructSequence_InitType (& VersionInfoType , & version_info_desc );
1485+ SET_SYS_FROM_STRING ("version_info" , make_version_info ());
1486+ /* prevent user from creating new instances */
1487+ VersionInfoType .tp_init = NULL ;
1488+ VersionInfoType .tp_new = NULL ;
1489+
1490+ /* flags */
14321491 if (FlagsType .tp_name == 0 )
14331492 PyStructSequence_InitType (& FlagsType , & flags_desc );
14341493 SET_SYS_FROM_STRING ("flags" , make_flags ());
0 commit comments