[Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.202,2.203 timemodule.c,2.114,2.115
Guido van Rossum
gvanrossum@users.sourceforge.net
Thu, 18 Oct 2001 13:34:28 -0700
Update of /cvsroot/python/python/dist/src/Modules
In directory usw-pr-cvs1:/tmp/cvs-serv7266/Modules
Modified Files:
posixmodule.c timemodule.c
Log Message:
SF patch #462296: Add attributes to os.stat results; by Nick Mathewson.
This is a big one, touching lots of files. Some of the platforms
aren't tested yet. Briefly, this changes the return value of the
os/posix functions stat(), fstat(), statvfs(), fstatvfs(), and the
time functions localtime(), gmtime(), and strptime() from tuples into
pseudo-sequences. When accessed as a sequence, they behave exactly as
before. But they also have attributes like st_mtime or tm_year. The
stat return value, moreover, has a few platform-specific attributes
that are not available through the sequence interface (because
everybody expects the sequence to have a fixed length, these couldn't
be added there). If your platform's struct stat doesn't define
st_blksize, st_blocks or st_rdev, they won't be accessible from Python
either.
(Still missing is a documentation update.)
Index: posixmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v
retrieving revision 2.202
retrieving revision 2.203
diff -C2 -d -r2.202 -r2.203
*** posixmodule.c 2001/10/18 19:44:10 2.202
--- posixmodule.c 2001/10/18 20:34:25 2.203
***************
*** 18,21 ****
--- 18,22 ----
#include "Python.h"
+ #include "structseq.h"
#if defined(PYOS_OS2)
***************
*** 517,520 ****
--- 518,612 ----
}
+ static char stat_result__doc__[] =
+ "stat_result: Result from stat or lstat.\n\n\
+ This object may be accessed either as a tuple of\n\
+ (mode,ino,dev,nlink,uid,gid,size,atime,mtime,ctime)\n\
+ or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
+ \n\
+ Posix/windows: If your platform supports st_blksize, st_blocks, or st_rdev,
+ they are available as attributes only.\n\
+ \n\
+ See os.stat for more information.\n";
+
+ static PyStructSequence_Field stat_result_fields[] = {
+ {"st_mode", "protection bits"},
+ {"st_ino", "inode"},
+ {"st_dev", "device"},
+ {"st_nlink", "number of hard links"},
+ {"st_uid", "user ID of owner"},
+ {"st_gid", "group ID of owner"},
+ {"st_size", "total size, in bytes"},
+ {"st_atime", "time of last access"},
+ {"st_mtime", "time of last modification"},
+ {"st_ctime", "time of last change"},
+ #ifdef HAVE_ST_BLKSIZE
+ {"st_blksize", "blocksize for filesystem I/O"},
+ #endif
+ #ifdef HAVE_ST_BLOCKS
+ {"st_blocks", "number of blocks allocated"},
+ #endif
+ #ifdef HAVE_ST_RDEV
+ {"st_rdev", "device type (if inode device)"},
+ #endif
+ {0}
+ };
+
+ #ifdef HAVE_ST_BLKSIZE
+ #define ST_BLKSIZE_IDX 10
+ #else
+ #define ST_BLKSIZE_IDX 9
+ #endif
+
+ #ifdef HAVE_ST_BLOCKS
+ #define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
+ #else
+ #define ST_BLOCKS_IDX ST_BLKSIZE_IDX
+ #endif
+
+ #ifdef HAVE_ST_RDEV
+ #define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
+ #else
+ #define ST_RDEV_IDX ST_BLOCKS_IDX
+ #endif
+
+ static PyStructSequence_Desc stat_result_desc = {
+ "stat_result", /* name */
+ stat_result__doc__, /* doc */
+ stat_result_fields,
+ 10
+ };
+
+ static char statvfs_result__doc__[] =
+ "statvfs_result: Result from statvfs or fstatvfs.\n\n\
+ This object may be accessed either as a tuple of\n\
+ (bsize,frsize,blocks,bfree,bavail,files,ffree,favail,flag,namemax),
+ or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.
+ \n\
+ See os.statvfs for more information.\n";
+
+ static PyStructSequence_Field statvfs_result_fields[] = {
+ {"f_bsize", },
+ {"f_frsize", },
+ {"f_blocks", },
+ {"f_bfree", },
+ {"f_bavail", },
+ {"f_files", },
+ {"f_ffree", },
+ {"f_favail", },
+ {"f_flag", },
+ {"f_namemax",},
+ {0}
+ };
+
+ static PyStructSequence_Desc statvfs_result_desc = {
+ "statvfs_result", /* name */
+ statvfs_result__doc__, /* doc */
+ statvfs_result_fields,
+ 10
+ };
+
+ static PyTypeObject StatResultType;
+ static PyTypeObject StatVFSResultType;
+
/* pack a system stat C structure into the Python stat tuple
(used by posix_stat() and posix_fstat()) */
***************
*** 522,558 ****
_pystat_fromstructstat(STRUCT_STAT st)
{
! PyObject *v = PyTuple_New(10);
if (v == NULL)
return NULL;
! PyTuple_SetItem(v, 0, PyInt_FromLong((long)st.st_mode));
#ifdef HAVE_LARGEFILE_SUPPORT
! PyTuple_SetItem(v, 1, PyLong_FromLongLong((LONG_LONG)st.st_ino));
#else
! PyTuple_SetItem(v, 1, PyInt_FromLong((long)st.st_ino));
#endif
#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
! PyTuple_SetItem(v, 2, PyLong_FromLongLong((LONG_LONG)st.st_dev));
#else
! PyTuple_SetItem(v, 2, PyInt_FromLong((long)st.st_dev));
#endif
! PyTuple_SetItem(v, 3, PyInt_FromLong((long)st.st_nlink));
! PyTuple_SetItem(v, 4, PyInt_FromLong((long)st.st_uid));
! PyTuple_SetItem(v, 5, PyInt_FromLong((long)st.st_gid));
#ifdef HAVE_LARGEFILE_SUPPORT
! PyTuple_SetItem(v, 6, PyLong_FromLongLong((LONG_LONG)st.st_size));
#else
! PyTuple_SetItem(v, 6, PyInt_FromLong(st.st_size));
#endif
#if SIZEOF_TIME_T > SIZEOF_LONG
! PyTuple_SetItem(v, 7, PyLong_FromLongLong((LONG_LONG)st.st_atime));
! PyTuple_SetItem(v, 8, PyLong_FromLongLong((LONG_LONG)st.st_mtime));
! PyTuple_SetItem(v, 9, PyLong_FromLongLong((LONG_LONG)st.st_ctime));
#else
! PyTuple_SetItem(v, 7, PyInt_FromLong((long)st.st_atime));
! PyTuple_SetItem(v, 8, PyInt_FromLong((long)st.st_mtime));
! PyTuple_SetItem(v, 9, PyInt_FromLong((long)st.st_ctime));
#endif
if (PyErr_Occurred()) {
Py_DECREF(v);
--- 614,669 ----
_pystat_fromstructstat(STRUCT_STAT st)
{
! PyObject *v = PyStructSequence_New(&StatResultType);
if (v == NULL)
return NULL;
! PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long)st.st_mode));
#ifdef HAVE_LARGEFILE_SUPPORT
! PyStructSequence_SET_ITEM(v, 1,
! PyLong_FromLongLong((LONG_LONG)st.st_ino));
#else
! PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long)st.st_ino));
#endif
#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
! PyStructSequence_SET_ITEM(v, 2,
! PyLong_FromLongLong((LONG_LONG)st.st_dev));
#else
! PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long)st.st_dev));
#endif
! PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long)st.st_nlink));
! PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long)st.st_uid));
! PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long)st.st_gid));
#ifdef HAVE_LARGEFILE_SUPPORT
! PyStructSequence_SET_ITEM(v, 6,
! PyLong_FromLongLong((LONG_LONG)st.st_size));
#else
! PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong(st.st_size));
#endif
#if SIZEOF_TIME_T > SIZEOF_LONG
! PyStructSequence_SET_ITEM(v, 7,
! PyLong_FromLongLong((LONG_LONG)st.st_atime));
! PyStructSequence_SET_ITEM(v, 8,
! PyLong_FromLongLong((LONG_LONG)st.st_mtime));
! PyStructSequence_SET_ITEM(v, 9,
! PyLong_FromLongLong((LONG_LONG)st.st_ctime));
#else
! PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long)st.st_atime));
! PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long)st.st_mtime));
! PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long)st.st_ctime));
#endif
+ #ifdef HAVE_ST_BLKSIZE
+ PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
+ PyInt_FromLong((long)st.st_blksize));
+ #endif
+ #ifdef HAVE_ST_BLOCKS
+ PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
+ PyInt_FromLong((long)st.st_blocks));
+ #endif
+ #ifdef HAVE_ST_RDEV
+ PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
+ PyInt_FromLong((long)st.st_rdev));
+ #endif
+
if (PyErr_Occurred()) {
Py_DECREF(v);
***************
*** 563,567 ****
}
-
static PyObject *
posix_do_stat(PyObject *self, PyObject *args, char *format,
--- 674,677 ----
***************
*** 4174,4177 ****
--- 4284,4326 ----
#include <sys/statvfs.h>
+ static PyObject*
+ _pystatvfs_fromstructstatvfs(struct statvfs st) {
+ PyObject *v = PyStructSequence_New(&StatVFSResultType);
+ if (v == NULL)
+ return NULL;
+
+ #if !defined(HAVE_LARGEFILE_SUPPORT)
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+ PyStructSequence_SET_ITEM(v, 2, PyInt_FromLong((long) st.f_blocks));
+ PyStructSequence_SET_ITEM(v, 3, PyInt_FromLong((long) st.f_bfree));
+ PyStructSequence_SET_ITEM(v, 4, PyInt_FromLong((long) st.f_bavail));
+ PyStructSequence_SET_ITEM(v, 5, PyInt_FromLong((long) st.f_files));
+ PyStructSequence_SET_ITEM(v, 6, PyInt_FromLong((long) st.f_ffree));
+ PyStructSequence_SET_ITEM(v, 7, PyInt_FromLong((long) st.f_favail));
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+ #else
+ PyStructSequence_SET_ITEM(v, 0, PyInt_FromLong((long) st.f_bsize));
+ PyStructSequence_SET_ITEM(v, 1, PyInt_FromLong((long) st.f_frsize));
+ PyStructSequence_SET_ITEM(v, 2,
+ PyLong_FromLongLong((LONG_LONG) st.f_blocks));
+ PyStructSequence_SET_ITEM(v, 3,
+ PyLong_FromLongLong((LONG_LONG) st.f_bfree));
+ PyStructSequence_SET_ITEM(v, 4,
+ PyLong_FromLongLong((LONG_LONG) st.f_bavail));
+ PyStructSequence_SET_ITEM(v, 5,
+ PyLong_FromLongLong((LONG_LONG) st.f_files));
+ PyStructSequence_SET_ITEM(v, 6,
+ PyLong_FromLongLong((LONG_LONG) st.f_ffree));
+ PyStructSequence_SET_ITEM(v, 7,
+ PyLong_FromLongLong((LONG_LONG) st.f_favail));
+ PyStructSequence_SET_ITEM(v, 8, PyInt_FromLong((long) st.f_flag));
+ PyStructSequence_SET_ITEM(v, 9, PyInt_FromLong((long) st.f_namemax));
+ #endif
+
+ return v;
+ }
+
static char posix_fstatvfs__doc__[] =
"fstatvfs(fd) -> \n\
***************
*** 4184,4187 ****
--- 4333,4337 ----
int fd, res;
struct statvfs st;
+
if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
return NULL;
***************
*** 4191,4219 ****
if (res != 0)
return posix_error();
! #if !defined(HAVE_LARGEFILE_SUPPORT)
! return Py_BuildValue("(llllllllll)",
! (long) st.f_bsize,
! (long) st.f_frsize,
! (long) st.f_blocks,
! (long) st.f_bfree,
! (long) st.f_bavail,
! (long) st.f_files,
! (long) st.f_ffree,
! (long) st.f_favail,
! (long) st.f_flag,
! (long) st.f_namemax);
! #else
! return Py_BuildValue("(llLLLLLLll)",
! (long) st.f_bsize,
! (long) st.f_frsize,
! (LONG_LONG) st.f_blocks,
! (LONG_LONG) st.f_bfree,
! (LONG_LONG) st.f_bavail,
! (LONG_LONG) st.f_files,
! (LONG_LONG) st.f_ffree,
! (LONG_LONG) st.f_favail,
! (long) st.f_flag,
! (long) st.f_namemax);
! #endif
}
#endif /* HAVE_FSTATVFS */
--- 4341,4346 ----
if (res != 0)
return posix_error();
!
! return _pystatvfs_fromstructstatvfs(st);
}
#endif /* HAVE_FSTATVFS */
***************
*** 4241,4269 ****
if (res != 0)
return posix_error_with_filename(path);
! #if !defined(HAVE_LARGEFILE_SUPPORT)
! return Py_BuildValue("(llllllllll)",
! (long) st.f_bsize,
! (long) st.f_frsize,
! (long) st.f_blocks,
! (long) st.f_bfree,
! (long) st.f_bavail,
! (long) st.f_files,
! (long) st.f_ffree,
! (long) st.f_favail,
! (long) st.f_flag,
! (long) st.f_namemax);
! #else /* HAVE_LARGEFILE_SUPPORT */
! return Py_BuildValue("(llLLLLLLll)",
! (long) st.f_bsize,
! (long) st.f_frsize,
! (LONG_LONG) st.f_blocks,
! (LONG_LONG) st.f_bfree,
! (LONG_LONG) st.f_bavail,
! (LONG_LONG) st.f_files,
! (LONG_LONG) st.f_ffree,
! (LONG_LONG) st.f_favail,
! (long) st.f_flag,
! (long) st.f_namemax);
! #endif
}
#endif /* HAVE_STATVFS */
--- 4368,4373 ----
if (res != 0)
return posix_error_with_filename(path);
!
! return _pystatvfs_fromstructstatvfs(st);
}
#endif /* HAVE_STATVFS */
***************
*** 5826,5828 ****
--- 5930,5938 ----
posix_putenv_garbage = PyDict_New();
#endif
+
+ PyStructSequence_InitType(&StatResultType, &stat_result_desc);
+ PyDict_SetItemString(d, "stat_result", (PyObject*) &StatResultType);
+
+ PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
+ PyDict_SetItemString(d, "statvfs_result", (PyObject*) &StatResultType);
}
Index: timemodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v
retrieving revision 2.114
retrieving revision 2.115
diff -C2 -d -r2.114 -r2.115
*** timemodule.c 2001/09/25 13:59:01 2.114
--- timemodule.c 2001/10/18 20:34:25 2.115
***************
*** 3,6 ****
--- 3,7 ----
#include "Python.h"
+ #include "structseq.h"
#include <ctype.h>
***************
*** 211,227 ****
a floating point number for subsecond precision.";
static PyObject *
tmtotuple(struct tm *p)
{
! return Py_BuildValue("(iiiiiiiii)",
! p->tm_year + 1900,
! p->tm_mon + 1, /* Want January == 1 */
! p->tm_mday,
! p->tm_hour,
! p->tm_min,
! p->tm_sec,
! (p->tm_wday + 6) % 7, /* Want Monday == 0 */
! p->tm_yday + 1, /* Want January, 1 == 1 */
! p->tm_isdst);
}
--- 212,262 ----
a floating point number for subsecond precision.";
+ static PyStructSequence_Field struct_time_type_fields[] = {
+ {"tm_year", NULL},
+ {"tm_mon", NULL},
+ {"tm_mday", NULL},
+ {"tm_hour", NULL},
+ {"tm_min", NULL},
+ {"tm_sec", NULL},
+ {"tm_wday", NULL},
+ {"tm_yday", NULL},
+ {"tm_isdst", NULL},
+ {0}
+ };
+
+ static PyStructSequence_Desc struct_time_type_desc = {
+ "struct_time",
+ NULL,
+ struct_time_type_fields,
+ 9,
+ };
+
+ static PyTypeObject StructTimeType;
+
static PyObject *
tmtotuple(struct tm *p)
{
! PyObject *v = PyStructSequence_New(&StructTimeType);
! if (v == NULL)
! return NULL;
!
! #define SET(i,val) PyStructSequence_SET_ITEM(v, i, PyInt_FromLong((long) val))
!
! SET(0, p->tm_year + 1900);
! SET(1, p->tm_mon + 1); /* Want January == 1 */
! SET(2, p->tm_mday);
! SET(3, p->tm_hour);
! SET(4, p->tm_min);
! SET(5, p->tm_sec);
! SET(6, (p->tm_wday + 6) % 7); /* Want Monday == 0 */
! SET(7, p->tm_yday + 1); /* Want January, 1 == 1 */
! SET(8, p->tm_isdst);
! #undef SET
! if (PyErr_Occurred()) {
! Py_XDECREF(v);
! return NULL;
! }
!
! return v;
}
***************
*** 675,678 ****
--- 710,716 ----
#endif /* __CYGWIN__ */
#endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/
+
+ PyStructSequence_InitType(&StructTimeType, &struct_time_type_desc);
+ PyDict_SetItemString(d, "struct_time", (PyObject*) &StructTimeType);
}
***************
*** 853,856 ****
--- 891,895 ----
#endif /* !macintosh */
#endif /* !HAVE_SELECT */
+
return 0;
}