diff -r 2035c5ad4239 Doc/library/os.rst --- a/Doc/library/os.rst Wed Jun 20 23:47:14 2012 -0700 +++ b/Doc/library/os.rst Thu Jun 21 02:48:43 2012 -0700 @@ -566,15 +566,30 @@ single: gethostname() (in module socket) single: gethostbyaddr() (in module socket) - Return a 5-tuple containing information identifying the current operating - system. The tuple contains 5 strings: ``(sysname, nodename, release, version, - machine)``. Some systems truncate the nodename to 8 characters or to the + Returns information identifying the current operating system. + The return value is an object with five attributes: + + * :attr:`sysname` - operating system name + * :attr:`nodename` - name of machine on network (implementation-defined) + * :attr:`release` - operating system release + * :attr:`version` - operating system version + * :attr:`machine` - hardware identifier + + For backwards compatibility, this object is also iterable, behaving + like a five-tuple of containing :attr:`sysname`, :attr:`nodename`, + :attr:`release`, :attr:`version`, and :attr:`machine` + in that order. + + Some systems truncate :attr:`nodename` to 8 characters or to the leading component; a better way to get the hostname is :func:`socket.gethostname` or even ``socket.gethostbyaddr(socket.gethostname())``. Availability: recent flavors of Unix. + .. versionadded:: 3.3 + Return type changed from a tuple to an iterable object with named attributes. + .. function:: unsetenv(key) @@ -2840,15 +2855,30 @@ .. function:: times() - Return a 5-tuple of floating point numbers indicating accumulated (processor - or other) times, in seconds. The items are: user time, system time, - children's user time, children's system time, and elapsed real time since a - fixed point in the past, in that order. See the Unix manual page + Returns the current global process times. + The return value is an object with five attributes: + + * :attr:`user` - user time + * :attr:`system` - system time + * :attr:`children_user` - user time of all child processes + * :attr:`children_system` - system time of all child processes + * :attr:`elapsed` - elapsed real time since a fixed point in the past + + For backwards compatibility, this object is also iterable, behaving + like a five-tuple of containing :attr:`user`, :attr:`system`, + :attr:`children_user`, :attr:`children_system`, and :attr:`elapsed` + in that order. + + See the Unix manual page :manpage:`times(2)` or the corresponding Windows Platform API documentation. - On Windows, only the first two items are filled, the others are zero. + On Windows, only the first two items are filled; the others are zero. + On OS/2, only the last item is filled; the others are zero. Availability: Unix, Windows + .. versionadded:: 3.3 + Return type changed from a tuple to an iterable object with named attributes. + .. function:: wait() diff -r 2035c5ad4239 Modules/posixmodule.c --- a/Modules/posixmodule.c Wed Jun 20 23:47:14 2012 -0700 +++ b/Modules/posixmodule.c Thu Jun 21 02:48:43 2012 -0700 @@ -3555,23 +3555,68 @@ "uname() -> (sysname, nodename, release, version, machine)\n\n\ Return a tuple identifying the current operating system."); +static PyStructSequence_Field uname_result_fields[] = { + {"sysname", "operating system name"}, + {"nodename", "name of machine on network (implementation-defined)"}, + {"release", "operating system release"}, + {"version", "operating system version"}, + {"machine", "hardware identifier"}, + {NULL} +}; + +PyDoc_STRVAR(uname_result__doc__, +"uname_result: Result from os.uname().\n\n\ +This object may be accessed either as a tuple of\n\ + (sysname, nodename, release, version, machine),\n\ +or via the attributes sysname, nodename, release, version, and machine.\n\ +\n\ +See os.uname for more information."); + +static PyStructSequence_Desc uname_result_desc = { + "uname_result", /* name */ + uname_result__doc__, /* doc */ + uname_result_fields, + 5 +}; + +static PyTypeObject UnameResultType; + static PyObject * posix_uname(PyObject *self, PyObject *noargs) { struct utsname u; int res; + PyObject *value; Py_BEGIN_ALLOW_THREADS res = uname(&u); Py_END_ALLOW_THREADS if (res < 0) return posix_error(); - return Py_BuildValue("(sssss)", - u.sysname, - u.nodename, - u.release, - u.version, - u.machine); + + value = PyStructSequence_New(&UnameResultType); + if (value == NULL) + return NULL; + +#define SET(i, field) \ + { \ + PyObject *o = PyUnicode_DecodeASCII(field, strlen(field), NULL); \ + if (!o) { \ + Py_DECREF(value); \ + return NULL; \ + } \ + PyStructSequence_SET_ITEM(value, i, o); \ + } \ + + SET(0, u.sysname); + SET(1, u.nodename); + SET(2, u.release); + SET(3, u.version); + SET(4, u.machine); + +#undef SET + + return value; } #endif /* HAVE_UNAME */ @@ -6670,6 +6715,71 @@ } #endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */ +#if defined(HAVE_TIMES) || defined(MS_WINDOWS) +#define HAVE_TIMES_RESULT +#endif + +#ifdef HAVE_TIMES_RESULT +static PyStructSequence_Field times_result_fields[] = { + {"user", "user time"}, + {"system", "system time"}, + {"children_user", "user time of children"}, + {"children_system", "system time of children"}, + {"elapsed", "elapsed time since an arbitrary point in the past"}, + {NULL} +}; + +PyDoc_STRVAR(times_result__doc__, +"times_result: Result from os.times().\n\n\ +This object may be accessed either as a tuple of\n\ + (user, system, children_user, children_system, elapsed),\n\ +or via the attributes user, system, children_user, children_system,\n\ +and elapsed.\n\ +\n\ +See os.times for more information."); + +static PyStructSequence_Desc times_result_desc = { + "times_result", /* name */ + times_result__doc__, /* doc */ + times_result_fields, + 5 +}; + +static PyTypeObject TimesResultType; + +static PyObject * +build_times_result(double user, double system, + double children_user, double children_system, + double elapsed) +{ + PyObject *value = PyStructSequence_New(&TimesResultType); + if (value == NULL) + return NULL; + +#define SET(i, field) \ + { \ + PyObject *o = PyFloat_FromDouble(field); \ + if (!o) { \ + Py_DECREF(value); \ + return NULL; \ + } \ + PyStructSequence_SET_ITEM(value, i, o); \ + } \ + + SET(0, user); + SET(1, system); + SET(2, children_user); + SET(3, children_system); + SET(4, elapsed); + +#undef SET + + return value; +} + +#endif + + #ifdef HAVE_TIMES #if defined(PYCC_VACPP) && defined(PYOS_OS2) static long @@ -6688,7 +6798,7 @@ posix_times(PyObject *self, PyObject *noargs) { /* Currently Only Uptime is Provided -- Others Later */ - return Py_BuildValue("ddddd", + return build_times_result( (double)0 /* t.tms_utime / HZ */, (double)0 /* t.tms_stime / HZ */, (double)0 /* t.tms_cutime / HZ */, @@ -6707,7 +6817,7 @@ c = times(&t); if (c == (clock_t) -1) return posix_error(); - return Py_BuildValue("ddddd", + return build_times_result( (double)t.tms_utime / ticks_per_second, (double)t.tms_stime / ticks_per_second, (double)t.tms_cutime / ticks_per_second, @@ -6732,8 +6842,7 @@ 1e7 is one second in such units; 1e-7 the inverse. 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7. */ - return Py_BuildValue( - "ddddd", + return build_times_result( (double)(user.dwHighDateTime*429.4967296 + user.dwLowDateTime*1e-7), (double)(kernel.dwHighDateTime*429.4967296 + @@ -11682,6 +11791,12 @@ /* initialize TerminalSize_info */ PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc); Py_INCREF(&TerminalSizeType); + + uname_result_desc.name = MODNAME ".uname_result"; + PyStructSequence_InitType(&UnameResultType, &uname_result_desc); + + times_result_desc.name = MODNAME ".times_result"; + PyStructSequence_InitType(&TimesResultType, ×_result_desc); } #if defined(HAVE_WAITID) && !defined(__APPLE__) Py_INCREF((PyObject*) &WaitidResultType);