diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2012-02-08 13:31:50 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2012-02-08 13:31:50 (GMT) |
commit | ccd5715a149388eec2f40e5efacac83d3fe357ca (patch) | |
tree | 69b6582c3ed63f6527e56ebdc996c99dccbba910 /Modules/posixmodule.c | |
parent | 6f91ce74a04e958b2e5b1d1904110739eea66841 (diff) | |
download | cpython-ccd5715a149388eec2f40e5efacac83d3fe357ca.zip cpython-ccd5715a149388eec2f40e5efacac83d3fe357ca.tar.gz cpython-ccd5715a149388eec2f40e5efacac83d3fe357ca.tar.bz2 |
PEP 410
Diffstat (limited to 'Modules/posixmodule.c')
-rw-r--r-- | Modules/posixmodule.c | 185 |
1 files changed, 124 insertions, 61 deletions
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 8b2b211..0ab63c3 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -1702,6 +1702,12 @@ stat_float_times(PyObject* self, PyObject *args) int newval = -1; if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval)) return NULL; + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "os.stat_float_times() has been deprecated, " + "use timestamp argument of os.stat() instead", + 1)) + return NULL; + if (newval == -1) /* Return old value */ return PyBool_FromLong(_stat_float_times); @@ -1711,9 +1717,12 @@ stat_float_times(PyObject* self, PyObject *args) } static void -fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) +fill_time(PyObject *v, int index, time_t sec, unsigned long nsec, + int has_nsec, PyObject *timestamp) { PyObject *fval,*ival; + _PyTime_t ts; + #if SIZEOF_TIME_T > SIZEOF_LONG ival = PyLong_FromLongLong((PY_LONG_LONG)sec); #else @@ -1721,9 +1730,21 @@ fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) #endif if (!ival) return; - if (_stat_float_times) { - fval = PyFloat_FromDouble(sec + 1e-9*nsec); - } else { + if (timestamp == NULL && _stat_float_times) + timestamp = (PyObject*)&PyFloat_Type; + if (timestamp != NULL) { + ts.seconds = sec; + if (has_nsec) { + ts.numerator = nsec; + ts.denominator = 1000000000; + } + else { + ts.numerator = 0; + ts.denominator = 1; + } + fval = _PyTime_Convert(&ts, timestamp); + } + else { fval = ival; Py_INCREF(fval); } @@ -1734,9 +1755,14 @@ fill_time(PyObject *v, int index, time_t sec, unsigned long nsec) /* pack a system stat C structure into the Python stat tuple (used by posix_stat() and posix_fstat()) */ static PyObject* -_pystat_fromstructstat(STRUCT_STAT *st) +_pystat_fromstructstat(STRUCT_STAT *st, PyObject *timestamp) { unsigned long ansec, mnsec, cnsec; + int has_nsec; +#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME + _PyTime_t ts; +#endif + PyObject *v = PyStructSequence_New(&StatResultType); if (v == NULL) return NULL; @@ -1768,20 +1794,24 @@ _pystat_fromstructstat(STRUCT_STAT *st) ansec = st->st_atim.tv_nsec; mnsec = st->st_mtim.tv_nsec; cnsec = st->st_ctim.tv_nsec; + has_nsec = 1; #elif defined(HAVE_STAT_TV_NSEC2) ansec = st->st_atimespec.tv_nsec; mnsec = st->st_mtimespec.tv_nsec; cnsec = st->st_ctimespec.tv_nsec; + has_nsec = 1; #elif defined(HAVE_STAT_NSEC) ansec = st->st_atime_nsec; mnsec = st->st_mtime_nsec; cnsec = st->st_ctime_nsec; + has_nsec = 1; #else ansec = mnsec = cnsec = 0; + has_nsec = 0; #endif - fill_time(v, 7, st->st_atime, ansec); - fill_time(v, 8, st->st_mtime, mnsec); - fill_time(v, 9, st->st_ctime, cnsec); + fill_time(v, 7, st->st_atime, ansec, has_nsec, timestamp); + fill_time(v, 8, st->st_mtime, mnsec, has_nsec, timestamp); + fill_time(v, 9, st->st_ctime, cnsec, has_nsec, timestamp); #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX, @@ -1801,21 +1831,26 @@ _pystat_fromstructstat(STRUCT_STAT *st) #endif #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME { - PyObject *val; - unsigned long bsec,bnsec; - bsec = (long)st->st_birthtime; + PyObject *val; + ts.seconds = (long)st->st_birthtime; #ifdef HAVE_STAT_TV_NSEC2 - bnsec = st->st_birthtimespec.tv_nsec; + ts.numerator = st->st_birthtimespec.tv_nsec; + ts.denominator = 1000000000; #else - bnsec = 0; + ts.numerator = 0; + ts.denominator = 1; #endif - if (_stat_float_times) { - val = PyFloat_FromDouble(bsec + 1e-9*bnsec); - } else { - val = PyLong_FromLong((long)bsec); - } - PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, - val); + if (timestamp == NULL) { + if (_stat_float_times) + val = _PyTime_Convert(&ts, (PyObject*)&PyFloat_Type); + else + val = _PyTime_Convert(&ts, (PyObject*)&PyLong_Type); + } + else { + val = _PyTime_Convert(&ts, timestamp); + } + PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX, + val); } #endif #ifdef HAVE_STRUCT_STAT_ST_FLAGS @@ -1832,7 +1867,7 @@ _pystat_fromstructstat(STRUCT_STAT *st) } static PyObject * -posix_do_stat(PyObject *self, PyObject *args, +posix_do_stat(PyObject *self, PyObject *args, PyObject *kw, char *format, #ifdef __VMS int (*statfunc)(const char *, STRUCT_STAT *, ...), @@ -1842,15 +1877,18 @@ posix_do_stat(PyObject *self, PyObject *args, char *wformat, int (*wstatfunc)(const wchar_t *, STRUCT_STAT *)) { + static char *kwlist[] = {"path", "timestamp", NULL}; STRUCT_STAT st; PyObject *opath; char *path; int res; PyObject *result; + PyObject *timestamp = NULL; #ifdef MS_WINDOWS PyObject *po; - if (PyArg_ParseTuple(args, wformat, &po)) { + if (PyArg_ParseTupleAndKeywords(args, kw, wformat, kwlist, + &po, ×tamp)) { wchar_t *wpath = PyUnicode_AsUnicode(po); if (wpath == NULL) return NULL; @@ -1861,15 +1899,17 @@ posix_do_stat(PyObject *self, PyObject *args, if (res != 0) return win32_error_object("stat", po); - return _pystat_fromstructstat(&st); + return _pystat_fromstructstat(&st, timestamp); } /* Drop the argument parsing error as narrow strings are also valid. */ PyErr_Clear(); + timestamp = NULL; #endif - if (!PyArg_ParseTuple(args, format, - PyUnicode_FSConverter, &opath)) + if (!PyArg_ParseTupleAndKeywords(args, kw, format, kwlist, + PyUnicode_FSConverter, &opath, + ×tamp)) return NULL; #ifdef MS_WINDOWS if (win32_warn_bytes_api()) { @@ -1890,7 +1930,7 @@ posix_do_stat(PyObject *self, PyObject *args, #endif } else - result = _pystat_fromstructstat(&st); + result = _pystat_fromstructstat(&st, timestamp); Py_DECREF(opath); return result; @@ -3381,16 +3421,16 @@ posix_rmdir(PyObject *self, PyObject *args) PyDoc_STRVAR(posix_stat__doc__, -"stat(path) -> stat result\n\n\ +"stat(path, timestamp=None) -> stat result\n\n\ Perform a stat system call on the given path."); static PyObject * -posix_stat(PyObject *self, PyObject *args) +posix_stat(PyObject *self, PyObject *args, PyObject *kw) { #ifdef MS_WINDOWS - return posix_do_stat(self, args, "O&:stat", STAT, "U:stat", win32_stat_w); + return posix_do_stat(self, args, kw, "O&|O:stat", STAT, "U|O:stat", win32_stat_w); #else - return posix_do_stat(self, args, "O&:stat", STAT, NULL, NULL); + return posix_do_stat(self, args, kw, "O&|O:stat", STAT, NULL, NULL); #endif } @@ -6118,11 +6158,12 @@ posix_setgroups(PyObject *self, PyObject *groups) #if defined(HAVE_WAIT3) || defined(HAVE_WAIT4) static PyObject * -wait_helper(pid_t pid, int status, struct rusage *ru) +wait_helper(pid_t pid, int status, struct rusage *ru, PyObject *timestamp) { PyObject *result; static PyObject *struct_rusage; _Py_IDENTIFIER(struct_rusage); + _PyTime_t ts; if (pid == -1) return posix_error(); @@ -6146,10 +6187,17 @@ wait_helper(pid_t pid, int status, struct rusage *ru) #define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001) #endif + ts.seconds = ru->ru_utime.tv_sec; + ts.numerator = ru->ru_utime.tv_usec; + ts.denominator = 1000000; PyStructSequence_SET_ITEM(result, 0, - PyFloat_FromDouble(doubletime(ru->ru_utime))); + _PyTime_Convert(&ts, timestamp)); + + ts.seconds = ru->ru_stime.tv_sec; + ts.numerator = ru->ru_stime.tv_usec; + ts.denominator = 1000000; PyStructSequence_SET_ITEM(result, 1, - PyFloat_FromDouble(doubletime(ru->ru_stime))); + _PyTime_Convert(&ts, timestamp)); #define SET_INT(result, index, value)\ PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value)) SET_INT(result, 2, ru->ru_maxrss); @@ -6179,51 +6227,55 @@ wait_helper(pid_t pid, int status, struct rusage *ru) #ifdef HAVE_WAIT3 PyDoc_STRVAR(posix_wait3__doc__, -"wait3(options) -> (pid, status, rusage)\n\n\ +"wait3(options[, timestamp=float]) -> (pid, status, rusage)\n\n\ Wait for completion of a child process."); static PyObject * -posix_wait3(PyObject *self, PyObject *args) +posix_wait3(PyObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"options", "timestamp", NULL}; pid_t pid; int options; struct rusage ru; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; + PyObject *timestamp = NULL; - if (!PyArg_ParseTuple(args, "i:wait3", &options)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|O:wait3", kwlist, &options, ×tamp)) return NULL; Py_BEGIN_ALLOW_THREADS pid = wait3(&status, options, &ru); Py_END_ALLOW_THREADS - return wait_helper(pid, WAIT_STATUS_INT(status), &ru); + return wait_helper(pid, WAIT_STATUS_INT(status), &ru, timestamp); } #endif /* HAVE_WAIT3 */ #ifdef HAVE_WAIT4 PyDoc_STRVAR(posix_wait4__doc__, -"wait4(pid, options) -> (pid, status, rusage)\n\n\ +"wait4(pid, options[, timestamp=float]) -> (pid, status, rusage)\n\n\ Wait for completion of a given child process."); static PyObject * -posix_wait4(PyObject *self, PyObject *args) +posix_wait4(PyObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"pid", "options", "timestamp", NULL}; pid_t pid; int options; struct rusage ru; WAIT_TYPE status; WAIT_STATUS_INT(status) = 0; + PyObject *timestamp = NULL; - if (!PyArg_ParseTuple(args, _Py_PARSE_PID "i:wait4", &pid, &options)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, _Py_PARSE_PID "i|O:wait4", kwlist, &pid, &options, ×tamp)) return NULL; Py_BEGIN_ALLOW_THREADS pid = wait4(pid, &status, options, &ru); Py_END_ALLOW_THREADS - return wait_helper(pid, WAIT_STATUS_INT(status), &ru); + return wait_helper(pid, WAIT_STATUS_INT(status), &ru, timestamp); } #endif /* HAVE_WAIT4 */ @@ -6350,20 +6402,20 @@ posix_wait(PyObject *self, PyObject *noargs) PyDoc_STRVAR(posix_lstat__doc__, -"lstat(path) -> stat result\n\n\ +"lstat(path, timestamp=None) -> stat result\n\n\ Like stat(path), but do not follow symbolic links."); static PyObject * -posix_lstat(PyObject *self, PyObject *args) +posix_lstat(PyObject *self, PyObject *args, PyObject *kw) { #ifdef HAVE_LSTAT - return posix_do_stat(self, args, "O&:lstat", lstat, NULL, NULL); + return posix_do_stat(self, args, kw, "O&|O:lstat", lstat, NULL, NULL); #else /* !HAVE_LSTAT */ #ifdef MS_WINDOWS - return posix_do_stat(self, args, "O&:lstat", win32_lstat, "U:lstat", + return posix_do_stat(self, args, kw, "O&|O:lstat", win32_lstat, "U|O:lstat", win32_lstat_w); #else - return posix_do_stat(self, args, "O&:lstat", STAT, NULL, NULL); + return posix_do_stat(self, args, "kw, O&|O:lstat", STAT, NULL, NULL); #endif #endif /* !HAVE_LSTAT */ } @@ -7322,16 +7374,19 @@ done: #endif PyDoc_STRVAR(posix_fstat__doc__, -"fstat(fd) -> stat result\n\n\ +"fstat(fd, timestamp=None) -> stat result\n\n\ Like stat(), but for an open file descriptor."); static PyObject * -posix_fstat(PyObject *self, PyObject *args) +posix_fstat(PyObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"fd", "timestamp", NULL}; int fd; STRUCT_STAT st; int res; - if (!PyArg_ParseTuple(args, "i:fstat", &fd)) + PyObject *timestamp = NULL; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|O:fstat", kwlist, + &fd, ×tamp)) return NULL; #ifdef __VMS /* on OpenVMS we must ensure that all bytes are written to the file */ @@ -7350,7 +7405,7 @@ posix_fstat(PyObject *self, PyObject *args) #endif } - return _pystat_fromstructstat(&st); + return _pystat_fromstructstat(&st, timestamp); } PyDoc_STRVAR(posix_isatty__doc__, @@ -9634,22 +9689,25 @@ posix_fchownat(PyObject *self, PyObject *args) #ifdef HAVE_FSTATAT PyDoc_STRVAR(posix_fstatat__doc__, -"fstatat(dirfd, path, flags=0) -> stat result\n\n\ +"fstatat(dirfd, path, flags=0, timestamp=None) -> stat result\n\n\ Like stat() but if path is relative, it is taken as relative to dirfd.\n\ flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\ If path is relative and dirfd is the special value AT_FDCWD, then path\n\ is interpreted relative to the current working directory."); static PyObject * -posix_fstatat(PyObject *self, PyObject *args) +posix_fstatat(PyObject *self, PyObject *args, PyObject *kwargs) { + static char *kwlist[] = {"dirfd", "path", "flags", "timestamp", NULL}; PyObject *opath; char *path; STRUCT_STAT st; int dirfd, res, flags = 0; + PyObject *timestamp = NULL; - if (!PyArg_ParseTuple(args, "iO&|i:fstatat", - &dirfd, PyUnicode_FSConverter, &opath, &flags)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|iO:fstatat", kwlist, + &dirfd, PyUnicode_FSConverter, &opath, + &flags, ×tamp)) return NULL; path = PyBytes_AsString(opath); @@ -9660,7 +9718,7 @@ posix_fstatat(PyObject *self, PyObject *args) if (res != 0) return posix_error(); - return _pystat_fromstructstat(&st); + return _pystat_fromstructstat(&st, timestamp); } #endif @@ -10524,7 +10582,7 @@ static PyMethodDef posix_methods[] = { #ifdef HAVE_FDOPENDIR {"flistdir", posix_flistdir, METH_VARARGS, posix_flistdir__doc__}, #endif - {"lstat", posix_lstat, METH_VARARGS, posix_lstat__doc__}, + {"lstat", (PyCFunction)posix_lstat, METH_VARARGS | METH_KEYWORDS, posix_lstat__doc__}, {"mkdir", posix_mkdir, METH_VARARGS, posix_mkdir__doc__}, #ifdef HAVE_NICE {"nice", posix_nice, METH_VARARGS, posix_nice__doc__}, @@ -10544,7 +10602,8 @@ static PyMethodDef posix_methods[] = { {"rename", posix_rename, METH_VARARGS, posix_rename__doc__}, {"replace", posix_replace, METH_VARARGS, posix_replace__doc__}, {"rmdir", posix_rmdir, METH_VARARGS, posix_rmdir__doc__}, - {"stat", posix_stat, METH_VARARGS, posix_stat__doc__}, + {"stat", (PyCFunction)posix_stat, + METH_VARARGS | METH_KEYWORDS, posix_stat__doc__}, {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__}, #if defined(HAVE_SYMLINK) && !defined(MS_WINDOWS) {"symlink", posix_symlink, METH_VARARGS, posix_symlink__doc__}, @@ -10705,10 +10764,12 @@ static PyMethodDef posix_methods[] = { {"wait", posix_wait, METH_NOARGS, posix_wait__doc__}, #endif /* HAVE_WAIT */ #ifdef HAVE_WAIT3 - {"wait3", posix_wait3, METH_VARARGS, posix_wait3__doc__}, + {"wait3", (PyCFunction)posix_wait3, + METH_VARARGS | METH_KEYWORDS, posix_wait3__doc__}, #endif /* HAVE_WAIT3 */ #ifdef HAVE_WAIT4 - {"wait4", posix_wait4, METH_VARARGS, posix_wait4__doc__}, + {"wait4", (PyCFunction)posix_wait4, + METH_VARARGS | METH_KEYWORDS, posix_wait4__doc__}, #endif /* HAVE_WAIT4 */ #if defined(HAVE_WAITID) && !defined(__APPLE__) {"waitid", posix_waitid, METH_VARARGS, posix_waitid__doc__}, @@ -10759,7 +10820,8 @@ static PyMethodDef posix_methods[] = { {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS, posix_sendfile__doc__}, #endif - {"fstat", posix_fstat, METH_VARARGS, posix_fstat__doc__}, + {"fstat", (PyCFunction)posix_fstat, METH_VARARGS | METH_KEYWORDS, + posix_fstat__doc__}, {"isatty", posix_isatty, METH_VARARGS, posix_isatty__doc__}, #ifdef HAVE_PIPE {"pipe", posix_pipe, METH_NOARGS, posix_pipe__doc__}, @@ -10894,7 +10956,8 @@ static PyMethodDef posix_methods[] = { {"fchownat", posix_fchownat, METH_VARARGS, posix_fchownat__doc__}, #endif /* HAVE_FCHOWNAT */ #ifdef HAVE_FSTATAT - {"fstatat", posix_fstatat, METH_VARARGS, posix_fstatat__doc__}, + {"fstatat", (PyCFunction)posix_fstatat, METH_VARARGS | METH_KEYWORDS, + posix_fstatat__doc__}, #endif #ifdef HAVE_FUTIMESAT {"futimesat", posix_futimesat, METH_VARARGS, posix_futimesat__doc__}, |