@@ -4299,28 +4299,76 @@ posix_unlink(PyObject *self, PyObject *args, PyObject *kwargs)
42994299}
43004300
43014301
4302- #ifdef HAVE_UNAME
43034302PyDoc_STRVAR (posix_uname__doc__ ,
4304- "uname() -> (sysname, nodename, release, version, machine)\n\n\
4305- Return a tuple identifying the current operating system." );
4303+ "uname() -> uname_result\n\n\
4304+ Return an object identifying the current operating system.\n\
4305+ The object behaves like a named tuple with the following fields:\n\
4306+ (sysname, nodename, release, version, machine)" );
4307+
4308+ static PyStructSequence_Field uname_result_fields [] = {
4309+ {"sysname" , "operating system name" },
4310+ {"nodename" , "name of machine on network (implementation-defined)" },
4311+ {"release" , "operating system release" },
4312+ {"version" , "operating system version" },
4313+ {"machine" , "hardware identifier" },
4314+ {NULL }
4315+ };
4316+
4317+ PyDoc_STRVAR (uname_result__doc__ ,
4318+ "uname_result: Result from os.uname().\n\n\
4319+ This object may be accessed either as a tuple of\n\
4320+ (sysname, nodename, release, version, machine),\n\
4321+ or via the attributes sysname, nodename, release, version, and machine.\n\
4322+ \n\
4323+ See os.uname for more information." );
4324+
4325+ static PyStructSequence_Desc uname_result_desc = {
4326+ "uname_result" , /* name */
4327+ uname_result__doc__ , /* doc */
4328+ uname_result_fields ,
4329+ 5
4330+ };
43064331
4332+ static PyTypeObject UnameResultType ;
4333+
4334+
4335+ #ifdef HAVE_UNAME
43074336static PyObject *
43084337posix_uname (PyObject * self , PyObject * noargs )
43094338{
43104339 struct utsname u ;
43114340 int res ;
4341+ PyObject * value ;
43124342
43134343 Py_BEGIN_ALLOW_THREADS
43144344 res = uname (& u );
43154345 Py_END_ALLOW_THREADS
43164346 if (res < 0 )
43174347 return posix_error ();
4318- return Py_BuildValue ("(sssss)" ,
4319- u .sysname ,
4320- u .nodename ,
4321- u .release ,
4322- u .version ,
4323- u .machine );
4348+
4349+ value = PyStructSequence_New (& UnameResultType );
4350+ if (value == NULL)
4351+ return NULL ;
4352+
4353+ #define SET (i , field ) \
4354+ { \
4355+ PyObject * o = PyUnicode_DecodeASCII (field , strlen (field ), NULL ); \
4356+ if (!o ) { \
4357+ Py_DECREF (value ); \
4358+ return NULL ; \
4359+ } \
4360+ PyStructSequence_SET_ITEM (value , i , o ); \
4361+ } \
4362+
4363+ SET (0 , u .sysname );
4364+ SET (1 , u .nodename );
4365+ SET (2 , u .release );
4366+ SET (3 , u .version );
4367+ SET (4 , u .machine );
4368+
4369+ #undef SET
4370+
4371+ return value ;
43244372}
43254373#endif /* HAVE_UNAME */
43264374
@@ -7366,6 +7414,75 @@ win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
73667414#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
73677415
73687416
7417+ static PyStructSequence_Field times_result_fields [] = {
7418+ {"user" , "user time" },
7419+ {"system" , "system time" },
7420+ {"children_user" , "user time of children" },
7421+ {"children_system" , "system time of children" },
7422+ {"elapsed" , "elapsed time since an arbitrary point in the past" },
7423+ {NULL }
7424+ };
7425+
7426+ PyDoc_STRVAR (times_result__doc__ ,
7427+ "times_result: Result from os.times().\n\n\
7428+ This object may be accessed either as a tuple of\n\
7429+ (user, system, children_user, children_system, elapsed),\n\
7430+ or via the attributes user, system, children_user, children_system,\n\
7431+ and elapsed.\n\
7432+ \n\
7433+ See os.times for more information." );
7434+
7435+ static PyStructSequence_Desc times_result_desc = {
7436+ "times_result" , /* name */
7437+ times_result__doc__ , /* doc */
7438+ times_result_fields ,
7439+ 5
7440+ };
7441+
7442+ static PyTypeObject TimesResultType ;
7443+
7444+
7445+ #if defined(HAVE_TIMES ) || defined(MS_WINDOWS )
7446+
7447+ static PyObject *
7448+ build_times_result (double user , double system ,
7449+ double children_user , double children_system ,
7450+ double elapsed )
7451+ {
7452+ PyObject * value = PyStructSequence_New (& TimesResultType );
7453+ if (value == NULL )
7454+ return NULL ;
7455+
7456+ #define SET (i , field ) \
7457+ { \
7458+ PyObject *o = PyFloat_FromDouble(field); \
7459+ if (!o) { \
7460+ Py_DECREF(value); \
7461+ return NULL; \
7462+ } \
7463+ PyStructSequence_SET_ITEM(value, i, o); \
7464+ } \
7465+
7466+ SET (0 , user );
7467+ SET (1 , system );
7468+ SET (2 , children_user );
7469+ SET (3 , children_system );
7470+ SET (4 , elapsed );
7471+
7472+ #undef SET
7473+
7474+ return value ;
7475+ }
7476+
7477+ PyDoc_STRVAR (posix_times__doc__ ,
7478+ "times() -> times_result\n\n\
7479+ Return an object containing floating point numbers indicating process\n\
7480+ times. The object behaves like a named tuple with these fields:\n\
7481+ (utime, stime, cutime, cstime, elapsed_time)" );
7482+
7483+ #endif
7484+
7485+
73697486#ifdef HAVE_TIMES
73707487#if defined(PYCC_VACPP ) && defined(PYOS_OS2 )
73717488static long
@@ -7384,7 +7501,7 @@ static PyObject *
73847501posix_times (PyObject * self , PyObject * noargs )
73857502{
73867503 /* Currently Only Uptime is Provided -- Others Later */
7387- return Py_BuildValue ( "ddddd" ,
7504+ return build_times_result (
73887505 (double )0 /* t.tms_utime / HZ */ ,
73897506 (double )0 /* t.tms_stime / HZ */ ,
73907507 (double )0 /* t.tms_cutime / HZ */ ,
@@ -7403,19 +7520,15 @@ posix_times(PyObject *self, PyObject *noargs)
74037520 c = times (& t );
74047521 if (c == (clock_t ) - 1 )
74057522 return posix_error ();
7406- return Py_BuildValue ( "ddddd" ,
7523+ return build_times_result (
74077524 (double )t .tms_utime / ticks_per_second ,
74087525 (double )t .tms_stime / ticks_per_second ,
74097526 (double )t .tms_cutime / ticks_per_second ,
74107527 (double )t .tms_cstime / ticks_per_second ,
74117528 (double )c / ticks_per_second );
74127529}
74137530#endif /* not OS2 */
7414- #endif /* HAVE_TIMES */
7415-
7416-
7417- #ifdef MS_WINDOWS
7418- #define HAVE_TIMES /* so the method table will pick it up */
7531+ #elif defined(MS_WINDOWS)
74197532static PyObject *
74207533posix_times (PyObject * self , PyObject * noargs )
74217534{
@@ -7428,8 +7541,7 @@ posix_times(PyObject *self, PyObject *noargs)
74287541 1e7 is one second in such units; 1e-7 the inverse.
74297542 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
74307543 */
7431- return Py_BuildValue (
7432- "ddddd" ,
7544+ return build_times_result (
74337545 (double )(user .dwHighDateTime * 429.4967296 +
74347546 user .dwLowDateTime * 1e-7 ),
74357547 (double )(kernel .dwHighDateTime * 429.4967296 +
@@ -7438,12 +7550,6 @@ posix_times(PyObject *self, PyObject *noargs)
74387550 (double )0 ,
74397551 (double )0 );
74407552}
7441- #endif /* MS_WINDOWS */
7442-
7443- #ifdef HAVE_TIMES
7444- PyDoc_STRVAR (posix_times__doc__ ,
7445- "times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
7446- Return a tuple of floating point numbers indicating process times." );
74477553#endif
74487554
74497555
@@ -11965,6 +12071,14 @@ INITFUNC(void)
1196512071 PyModule_AddObject (m , "sched_param" , (PyObject * )& SchedParamType );
1196612072#endif
1196712073
12074+ times_result_desc .name = MODNAME ".times_result" ;
12075+ PyStructSequence_InitType (& TimesResultType , & times_result_desc );
12076+ PyModule_AddObject (m , "times_result" , (PyObject * )& TimesResultType );
12077+
12078+ uname_result_desc .name = MODNAME ".uname_result" ;
12079+ PyStructSequence_InitType (& UnameResultType , & uname_result_desc );
12080+ PyModule_AddObject (m , "uname_result" , (PyObject * )& UnameResultType );
12081+
1196812082#ifdef __APPLE__
1196912083 /*
1197012084 * Step 2 of weak-linking support on Mac OS X.
0 commit comments