Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0e5b562

Browse files
committed
Merged revisions 69331 via svnmerge from
svn+ssh://[email protected]/python/trunk ........ r69331 | eric.smith | 2009-02-05 19:48:26 -0500 (Thu, 05 Feb 2009) | 2 lines Implement issue #4285, convert sys.version_info to a named tuple. Patch by Ross Light. ........
1 parent d3409de commit 0e5b562

4 files changed

Lines changed: 100 additions & 24 deletions

File tree

Doc/library/sys.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -769,8 +769,12 @@ always available.
769769
*micro*, *releaselevel*, and *serial*. All values except *releaselevel* are
770770
integers; the release level is ``'alpha'``, ``'beta'``, ``'candidate'``, or
771771
``'final'``. The ``version_info`` value corresponding to the Python version 2.0
772-
is ``(2, 0, 0, 'final', 0)``.
772+
is ``(2, 0, 0, 'final', 0)``. The components can also be accessed by name,
773+
so ``sys.version_info[0]`` is equivalent to ``sys.version_info.major``
774+
and so on.
773775

776+
.. versionchanged:: 2.7
777+
Added named component attributes
774778

775779
.. data:: warnoptions
776780

Lib/test/test_sys.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,25 @@ def test_attributes(self):
298298
self.assert_(isinstance(sys.prefix, str))
299299
self.assert_(isinstance(sys.version, str))
300300
vi = sys.version_info
301-
self.assert_(isinstance(vi, tuple))
301+
self.assert_(isinstance(vi[:], tuple))
302302
self.assertEqual(len(vi), 5)
303303
self.assert_(isinstance(vi[0], int))
304304
self.assert_(isinstance(vi[1], int))
305305
self.assert_(isinstance(vi[2], int))
306306
self.assert_(vi[3] in ("alpha", "beta", "candidate", "final"))
307307
self.assert_(isinstance(vi[4], int))
308+
self.assert_(isinstance(vi.major, int))
309+
self.assert_(isinstance(vi.minor, int))
310+
self.assert_(isinstance(vi.micro, int))
311+
self.assert_(vi.releaselevel in
312+
("alpha", "beta", "candidate", "final"))
313+
self.assert_(isinstance(vi.serial, int))
314+
self.assertEqual(vi[0], vi.major)
315+
self.assertEqual(vi[1], vi.minor)
316+
self.assertEqual(vi[2], vi.micro)
317+
self.assertEqual(vi[3], vi.releaselevel)
318+
self.assertEqual(vi[4], vi.serial)
319+
self.assert_(vi > (1,0,0))
308320

309321
def test_43581(self):
310322
# Can't use sys.stdout, as this is a StringIO object when

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,9 @@ Core and Builtins
155155
Library
156156
-------
157157

158+
- Issue #4285: Change sys.version_info to be a named tuple. Patch by
159+
Ross Light.
160+
158161
- Issue #1520877: Now distutils.sysconfig reads $AR from the
159162
environment/Makefile. Patch by Douglas Greiman.
160163

Python/sysmodule.c

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ maxunicode -- the largest supported character\n\
10171017
builtin_module_names -- tuple of module names built into this interpreter\n\
10181018
subversion -- subversion information of the build as tuple\n\
10191019
version -- the version of this interpreter as a string\n\
1020-
version_info -- version information as a tuple\n\
1020+
version_info -- version information as a named tuple\n\
10211021
hexversion -- version information encoded as a single integer\n\
10221022
copyright -- copyright notice pertaining to this interpreter\n\
10231023
platform -- platform identifier\n\
@@ -1227,6 +1227,75 @@ make_flags(void)
12271227
return seq;
12281228
}
12291229

1230+
PyDoc_STRVAR(version_info__doc__,
1231+
"sys.version_info\n\
1232+
\n\
1233+
Version information as a named tuple.");
1234+
1235+
static PyTypeObject VersionInfoType;
1236+
1237+
static PyStructSequence_Field version_info_fields[] = {
1238+
{"major", "Major release number"},
1239+
{"minor", "Minor release number"},
1240+
{"micro", "Patch release number"},
1241+
{"releaselevel", "'alpha', 'beta', 'candidate', or 'release'"},
1242+
{"serial", "Serial release number"},
1243+
{0}
1244+
};
1245+
1246+
static PyStructSequence_Desc version_info_desc = {
1247+
"sys.version_info", /* name */
1248+
version_info__doc__, /* doc */
1249+
version_info_fields, /* fields */
1250+
5
1251+
};
1252+
1253+
static PyObject *
1254+
make_version_info(void)
1255+
{
1256+
PyObject *version_info;
1257+
char *s;
1258+
int pos = 0;
1259+
1260+
version_info = PyStructSequence_New(&VersionInfoType);
1261+
if (version_info == NULL) {
1262+
return NULL;
1263+
}
1264+
1265+
/*
1266+
* These release level checks are mutually exclusive and cover
1267+
* the field, so don't get too fancy with the pre-processor!
1268+
*/
1269+
#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
1270+
s = "alpha";
1271+
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
1272+
s = "beta";
1273+
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
1274+
s = "candidate";
1275+
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
1276+
s = "final";
1277+
#endif
1278+
1279+
#define SetIntItem(flag) \
1280+
PyStructSequence_SET_ITEM(version_info, pos++, PyLong_FromLong(flag))
1281+
#define SetStrItem(flag) \
1282+
PyStructSequence_SET_ITEM(version_info, pos++, PyUnicode_FromString(flag))
1283+
1284+
SetIntItem(PY_MAJOR_VERSION);
1285+
SetIntItem(PY_MINOR_VERSION);
1286+
SetIntItem(PY_MICRO_VERSION);
1287+
SetStrItem(s);
1288+
SetIntItem(PY_RELEASE_SERIAL);
1289+
#undef SetIntItem
1290+
#undef SetStrItem
1291+
1292+
if (PyErr_Occurred()) {
1293+
Py_CLEAR(version_info);
1294+
return NULL;
1295+
}
1296+
return version_info;
1297+
}
1298+
12301299
static struct PyModuleDef sysmodule = {
12311300
PyModuleDef_HEAD_INIT,
12321301
"sys",
@@ -1239,8 +1308,6 @@ static struct PyModuleDef sysmodule = {
12391308
NULL
12401309
};
12411310

1242-
1243-
12441311
PyObject *
12451312
_PySys_Init(void)
12461313
{
@@ -1291,25 +1358,6 @@ _PySys_Init(void)
12911358
svn_revision));
12921359
SET_SYS_FROM_STRING("dont_write_bytecode",
12931360
PyBool_FromLong(Py_DontWriteBytecodeFlag));
1294-
/*
1295-
* These release level checks are mutually exclusive and cover
1296-
* the field, so don't get too fancy with the pre-processor!
1297-
*/
1298-
#if PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_ALPHA
1299-
s = "alpha";
1300-
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_BETA
1301-
s = "beta";
1302-
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_GAMMA
1303-
s = "candidate";
1304-
#elif PY_RELEASE_LEVEL == PY_RELEASE_LEVEL_FINAL
1305-
s = "final";
1306-
#endif
1307-
1308-
SET_SYS_FROM_STRING("version_info",
1309-
Py_BuildValue("iiiUi", PY_MAJOR_VERSION,
1310-
PY_MINOR_VERSION,
1311-
PY_MICRO_VERSION, s,
1312-
PY_RELEASE_SERIAL));
13131361
SET_SYS_FROM_STRING("api_version",
13141362
PyLong_FromLong(PYTHON_API_VERSION));
13151363
SET_SYS_FROM_STRING("copyright",
@@ -1361,6 +1409,15 @@ _PySys_Init(void)
13611409
PyDict_SetItemString(sysdict, "warnoptions", warnoptions);
13621410
}
13631411

1412+
/* version_info */
1413+
if (VersionInfoType.tp_name == 0)
1414+
PyStructSequence_InitType(&VersionInfoType, &version_info_desc);
1415+
SET_SYS_FROM_STRING("version_info", make_version_info());
1416+
/* prevent user from creating new instances */
1417+
VersionInfoType.tp_init = NULL;
1418+
VersionInfoType.tp_new = NULL;
1419+
1420+
/* flags */
13641421
if (FlagsType.tp_name == 0)
13651422
PyStructSequence_InitType(&FlagsType, &flags_desc);
13661423
SET_SYS_FROM_STRING("flags", make_flags());

0 commit comments

Comments
 (0)