@@ -678,6 +678,10 @@ static PyStructSequence_Field stat_result_fields[] = {
678678 {"st_uid" , "user ID of owner" },
679679 {"st_gid" , "group ID of owner" },
680680 {"st_size" , "total size, in bytes" },
681+ /* The NULL is replaced with PyStructSequence_UnnamedField later. */
682+ {NULL , "integer time of last access" },
683+ {NULL , "integer time of last modification" },
684+ {NULL , "integer time of last change" },
681685 {"st_atime" , "time of last access" },
682686 {"st_mtime" , "time of last modification" },
683687 {"st_ctime" , "time of last change" },
@@ -694,9 +698,9 @@ static PyStructSequence_Field stat_result_fields[] = {
694698};
695699
696700#ifdef HAVE_ST_BLKSIZE
697- #define ST_BLKSIZE_IDX 10
701+ #define ST_BLKSIZE_IDX 13
698702#else
699- #define ST_BLKSIZE_IDX 9
703+ #define ST_BLKSIZE_IDX 12
700704#endif
701705
702706#ifdef HAVE_ST_BLOCKS
@@ -749,13 +753,73 @@ static PyStructSequence_Desc statvfs_result_desc = {
749753
750754static PyTypeObject StatResultType ;
751755static PyTypeObject StatVFSResultType ;
756+ static newfunc structseq_new ;
757+
758+ static PyObject *
759+ statresult_new (PyTypeObject * type , PyObject * args , PyObject * kwds )
760+ {
761+ PyStructSequence * result ;
762+ int i ;
763+
764+ result = (PyStructSequence * )structseq_new (type , args , kwds );
765+ if (!result )
766+ return NULL ;
767+ /* If we have been initialized from a tuple,
768+ st_?time might be set to None. Initialize it
769+ from the int slots. */
770+ for (i = 7 ; i <= 9 ; i ++ ) {
771+ if (result -> ob_item [i + 3 ] == Py_None ) {
772+ Py_DECREF (Py_None );
773+ Py_INCREF (result -> ob_item [i ]);
774+ result -> ob_item [i + 3 ] = result -> ob_item [i ];
775+ }
776+ }
777+ return (PyObject * )result ;
778+ }
779+
780+
781+
782+ /* If true, st_?time is float. */
783+ static int _stat_float_times = 0 ;
784+
785+ PyDoc_STRVAR (stat_float_times__doc__ ,
786+ "stat_float_times([newval]) -> oldval\n\n\
787+ Determine whether os.[lf]stat represents time stamps as float objects.\n\
788+ If newval is True, future calls to stat() return floats, if it is False,\n\
789+ future calls return ints. \n\
790+ If newval is omitted, return the current setting.\n" );
791+
792+ static PyObject *
793+ stat_float_times (PyObject * self , PyObject * args )
794+ {
795+ int newval = -1 ;
796+ if (!PyArg_ParseTuple (args , "|i:stat_float_times" , & newval ))
797+ return NULL ;
798+ if (newval == -1 )
799+ /* Return old value */
800+ return PyBool_FromLong (_stat_float_times );
801+ _stat_float_times = newval ;
802+ Py_INCREF (Py_None );
803+ return Py_None ;
804+ }
752805
753806static void
754807fill_time (PyObject * v , int index , time_t sec , unsigned long nsec )
755808{
756- PyObject * val ;
757- val = PyFloat_FromDouble (sec + 1e-9 * nsec );
758- PyStructSequence_SET_ITEM (v , index , val );
809+ PyObject * fval ,* ival ;
810+ #if SIZEOF_TIME_T > SIZEOF_LONG
811+ ival = PyLong_FromLongLong ((LONG_LONG )sec );
812+ #else
813+ ival = PyInt_FromLong ((long )sec );
814+ #endif
815+ if (_stat_float_times ) {
816+ fval = PyFloat_FromDouble (sec + 1e-9 * nsec );
817+ } else {
818+ fval = ival ;
819+ Py_INCREF (fval );
820+ }
821+ PyStructSequence_SET_ITEM (v , index , ival );
822+ PyStructSequence_SET_ITEM (v , index + 3 , fval );
759823}
760824
761825/* pack a system stat C structure into the Python stat tuple
@@ -6802,6 +6866,7 @@ static PyMethodDef posix_methods[] = {
68026866 {"rename" , posix_rename , METH_VARARGS , posix_rename__doc__ },
68036867 {"rmdir" , posix_rmdir , METH_VARARGS , posix_rmdir__doc__ },
68046868 {"stat" , posix_stat , METH_VARARGS , posix_stat__doc__ },
6869+ {"stat_float_times" , stat_float_times , METH_VARARGS , stat_float_times__doc__ },
68056870#ifdef HAVE_SYMLINK
68066871 {"symlink" , posix_symlink , METH_VARARGS , posix_symlink__doc__ },
68076872#endif /* HAVE_SYMLINK */
@@ -7296,7 +7361,12 @@ INITFUNC(void)
72967361#endif
72977362
72987363 stat_result_desc .name = MODNAME ".stat_result" ;
7364+ stat_result_desc .fields [7 ].name = PyStructSequence_UnnamedField ;
7365+ stat_result_desc .fields [8 ].name = PyStructSequence_UnnamedField ;
7366+ stat_result_desc .fields [9 ].name = PyStructSequence_UnnamedField ;
72997367 PyStructSequence_InitType (& StatResultType , & stat_result_desc );
7368+ structseq_new = StatResultType .tp_new ;
7369+ StatResultType .tp_new = statresult_new ;
73007370 Py_INCREF ((PyObject * ) & StatResultType );
73017371 PyModule_AddObject (m , "stat_result" , (PyObject * ) & StatResultType );
73027372
0 commit comments