Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 569b494

Browse files
committed
Fix #13327. utimensat now has the atime and mtime arguments set as optional,
defaulting to None like the other utimes family members. It now accepts keyword arguments because, unlike other other functions in the family, it has a `flags` value at the end of the argument list (which retains its 0 default).
1 parent 7ef53ef commit 569b494

3 files changed

Lines changed: 21 additions & 11 deletions

File tree

Doc/library/os.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,17 +1285,17 @@ as internal buffering of data.
12851285
.. versionadded:: 3.3
12861286

12871287

1288-
.. function:: utimensat(dirfd, path, (atime_sec, atime_nsec), (mtime_sec, mtime_nsec), flags)
1289-
utimensat(dirfd, path, None, None, flags)
1288+
.. function:: utimensat(dirfd, path[, atime=(atime_sec, atime_nsec), mtime=(mtime_sec, mtime_nsec), flags=0])
12901289

12911290
Updates the timestamps of a file with nanosecond precision.
1292-
The second form sets *atime* and *mtime* to the current time.
1291+
The *atime* and *mtime* tuples default to ``None``, which sets those
1292+
values to the current time.
12931293
If *atime_nsec* or *mtime_nsec* is specified as :data:`UTIME_NOW`, the corresponding
12941294
timestamp is updated to the current time.
12951295
If *atime_nsec* or *mtime_nsec* is specified as :data:`UTIME_OMIT`, the corresponding
12961296
timestamp is not updated.
12971297
If *path* is relative, it is taken as relative to *dirfd*.
1298-
*flags* is optional and may be 0 or :data:`AT_SYMLINK_NOFOLLOW`.
1298+
*flags* is optional and may be 0 (the default) or :data:`AT_SYMLINK_NOFOLLOW`.
12991299
If *path* is relative and *dirfd* is the special value :data:`AT_FDCWD`, then *path*
13001300
is interpreted relative to the current working directory.
13011301

Lib/test/test_posix.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,11 +815,16 @@ def test_utimensat(self):
815815
try:
816816
now = time.time()
817817
posix.utimensat(f, support.TESTFN, None, None)
818+
posix.utimensat(f, support.TESTFN)
819+
posix.utimensat(f, support.TESTFN, flags=os.AT_SYMLINK_NOFOLLOW)
818820
self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (None, None), (None, None))
819821
self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, (now, 0), None)
820822
self.assertRaises(TypeError, posix.utimensat, f, support.TESTFN, None, (now, 0))
821823
posix.utimensat(f, support.TESTFN, (int(now), int((now - int(now)) * 1e9)),
822824
(int(now), int((now - int(now)) * 1e9)))
825+
posix.utimensat(dirfd=f, path=support.TESTFN,
826+
atime=(int(now), int((now - int(now)) * 1e9)),
827+
mtime=(int(now), int((now - int(now)) * 1e9)))
823828
finally:
824829
posix.close(f)
825830

Modules/posixmodule.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10019,12 +10019,13 @@ posix_unlinkat(PyObject *self, PyObject *args)
1001910019

1002010020
#ifdef HAVE_UTIMENSAT
1002110021
PyDoc_STRVAR(posix_utimensat__doc__,
10022-
"utimensat(dirfd, path, (atime_sec, atime_nsec),\n\
10023-
(mtime_sec, mtime_nsec), flags)\n\
10022+
"utimensat(dirfd, path[, atime=(atime_sec, atime_nsec),\n\
10023+
mtime=(mtime_sec, mtime_nsec), flags=0])\n\
1002410024
utimensat(dirfd, path, None, None, flags)\n\n\
1002510025
Updates the timestamps of a file with nanosecond precision. If path is\n\
1002610026
relative, it is taken as relative to dirfd.\n\
10027-
The second form sets atime and mtime to the current time.\n\
10027+
If atime and mtime are both None, which is the default, set atime and\n\
10028+
mtime to the current time.\n\
1002810029
flags is optional and may be 0 or AT_SYMLINK_NOFOLLOW.\n\
1002910030
If path is relative and dirfd is the special value AT_FDCWD, then path\n\
1003010031
is interpreted relative to the current working directory.\n\
@@ -10033,16 +10034,19 @@ current time.\n\
1003310034
If *_nsec is specified as UTIME_OMIT, the timestamp is not updated.");
1003410035

1003510036
static PyObject *
10036-
posix_utimensat(PyObject *self, PyObject *args)
10037+
posix_utimensat(PyObject *self, PyObject *args, PyObject *kwargs)
1003710038
{
1003810039
PyObject *opath;
1003910040
char *path;
1004010041
int res, dirfd, flags = 0;
10041-
PyObject *atime, *mtime;
10042+
PyObject *atime = Py_None;
10043+
PyObject *mtime = Py_None;
10044+
10045+
static char *kwlist[] = {"dirfd", "path", "atime", "mtime", "flags", NULL};
1004210046

1004310047
struct timespec buf[2];
1004410048

10045-
if (!PyArg_ParseTuple(args, "iO&OO|i:utimensat",
10049+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO&|OOi:utimensat", kwlist,
1004610050
&dirfd, PyUnicode_FSConverter, &opath, &atime, &mtime, &flags))
1004710051
return NULL;
1004810052
path = PyBytes_AsString(opath);
@@ -10939,7 +10943,8 @@ static PyMethodDef posix_methods[] = {
1093910943
{"unlinkat", posix_unlinkat, METH_VARARGS, posix_unlinkat__doc__},
1094010944
#endif
1094110945
#ifdef HAVE_UTIMENSAT
10942-
{"utimensat", posix_utimensat, METH_VARARGS, posix_utimensat__doc__},
10946+
{"utimensat", posix_utimensat, METH_VARARGS | METH_KEYWORDS,
10947+
posix_utimensat__doc__},
1094310948
#endif
1094410949
#ifdef HAVE_MKFIFOAT
1094510950
{"mkfifoat", posix_mkfifoat, METH_VARARGS, posix_mkfifoat__doc__},

0 commit comments

Comments
 (0)