Commits

Antoine Pitrou committed 7116f6e

Issue #13: touch() now bumps the file timestamp

Comments (0)

Files changed (3)

    Create a file at this given path.  If *mode* is given, it is combined
    with the process' ``umask`` value to determine the file mode and access
    flags.  If the file already exists, the function succeeds if *exist_ok*
-   is true, otherwise :exc:`OSError` is raised.
+   is true (and its modification time is updated to the current time),
+   otherwise :exc:`OSError` is raised.
 
 
 .. method:: Path.unlink()
 import posixpath
 import re
 import sys
+import time
 import weakref
 try:
     import threading
             parent_fd, name = _fdnamepair(pathobj)
             os.symlink(str(target), name, dir_fd=parent_fd)
 
+        utime = _wrap_atfunc(os.utime)
+
         def _make_fd(self, pathobj, tolerant=True):
             fd = pathobj._cached_fd
             if fd is not None:
         def symlink(a, b, target_is_directory):
             return os.symlink(str(a), str(b))
 
+    utime = _wrap_strfunc(os.utime)
+
     def init_path(self, pathobj):
         pass
 
         """
         if self._closed:
             self._raise_closed()
+        if exist_ok:
+            # First try to bump modification time
+            # Implementation note: GNU touch uses the UTIME_NOW option of
+            # the utimensat() / futimens() functions.
+            t = time.time()
+            try:
+                self._accessor.utime(self, (t, t))
+            except OSError:
+                # Avoid exception chaining
+                pass
+            else:
+                return
         flags = os.O_CREAT
         if not exist_ok:
             flags |= os.O_EXCL
         self.assertFalse(p.exists())
         p.touch()
         self.assertTrue(p.exists())
+        old_mtime = p.restat().st_mtime
+        # Rewind the mtime sufficiently far in the past to work around
+        # filesystem-specific timestamp granularity.
+        os.utime(str(p), (old_mtime - 10, old_mtime - 10))
+        # The file mtime is refreshed by calling touch() again
         p.touch()
+        os.close(p.raw_open(os.O_CREAT))
+        self.assertGreaterEqual(p.restat().st_mtime, old_mtime)
         p = P['newfileB']
         self.assertFalse(p.exists())
         p.touch(mode=0o700, exist_ok=False)