changeset 166:3a6df7bfdae0

Manage to get higher than second resolution timestamps from "stat()" and friends. Mercurial seems so disable non-int timestamps from "os.stat()" calls with "os.stat_float_times(False)". Implemented a context manager that temporarily reactivates float-style timestamps when retrieving timestamps.
author Franz Glasner <hg@dom66.de>
date Fri, 31 Aug 2018 00:58:19 +0200
parents ffe20b7d21c4
children 3c9c7b41c41c
files extensions/timestamps.py
diffstat 1 files changed, 33 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/timestamps.py	Thu Aug 30 09:47:08 2018 +0200
+++ b/extensions/timestamps.py	Fri Aug 31 00:58:19 2018 +0200
@@ -132,10 +132,12 @@
     if not repo.local():
         raise error.Abort(_("repository is not local"))
     matcher = gen_matcher(repo, ctx, tsconfig=tsconfig)
-    for fn in ctx:
-        if matcher(fn):
-            st = os.lstat(fn)
-            print (fn, st, st.st_mtime, to_isoformat(st.st_mtime))
+    with FloatTimesInStat():
+        for fn in ctx:
+            if matcher(fn):
+                print fn
+                st = os.lstat(os.path.join(repo.root, fn))
+                print (fn, st, st.st_mtime, to_isoformat(st.st_mtime))
 
 
 def restore_timestamps(ui, repo, ctx,
@@ -191,8 +193,35 @@
 
 
 def to_isoformat(t):
+    print "T:", repr(t), type(t)
     dt = datetime.datetime.utcfromtimestamp(t)
     if dt.utcoffset() is None:
         return dt.isoformat() + "Z"
     else:
         return dt.isoformat()
+
+
+class FloatTimesInStat(object):
+    """Context manager to ensure that stat returns float values.
+
+    For 3.7 <= Mercurial < 4.6: Mercurial calls :func:`os.stat_float_times`
+    for `stat` and friends to return :class:`int` values.
+
+    Temporarily fix this.
+
+    """
+
+    __slots__ = ("_do_reset",)
+
+    def __init__(self):
+        self._do_reset = False
+
+    def __enter__(self):
+        if not os.stat_float_times():
+            os.stat_float_times(True)
+            self._do_reset = True
+        return self
+
+    def __exit__(self, *args):
+        if self._do_reset:
+            os.stat_float_times(False)