]> granicus.if.org Git - python/commitdiff
#8278: In the Windows implementation of stat() and utime(),
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>
Mon, 3 Jan 2011 00:19:11 +0000 (00:19 +0000)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>
Mon, 3 Jan 2011 00:19:11 +0000 (00:19 +0000)
use time_t instead of int.  This gives support for dates after 2038,
at least when compiled with VS2003 or later, where time_t is 64bit.

Lib/test/test_os.py
Misc/NEWS
Modules/posixmodule.c

index 497d8096c1f0da30420055b0043a976a9bcc5039..544eee16b59ca92d27928e45616f1c755cbe49ba 100644 (file)
@@ -365,6 +365,11 @@ class StatAttributeTests(unittest.TestCase):
                 os.utime(self.fname, (t1, t1))
                 self.assertEqual(os.stat(self.fname).st_mtime, t1)
 
+            def test_large_time(self):
+                t1 = 5000000000 # some day in 2128
+                os.utime(self.fname, (t1, t1))
+                self.assertEqual(os.stat(self.fname).st_mtime, t1)
+
         def test_1686475(self):
             # Verify that an open file can be stat'ed
             try:
index 75083cf314c5f1dc12b7aa4162c3c4934358ad21..4ee67ab84aa61c399555ee88f7a67cda4803ff2a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -8,6 +8,9 @@ What's New in Python 3.2 Release Candidate 1
 Core and Builtins
 -----------------
 
+- Issue #8278: On Windows and with a NTFS filesystem, os.stat() and os.utime()
+  can now handle dates after 2038.
+
 - Issue #10780: PyErr_SetFromWindowsErrWithFilename() and
   PyErr_SetExcFromWindowsErrWithFilename() decode the filename from the
   filesystem encoding instead of UTF-8.
index 0b7f3f09bc714bf0e0be2f1ded5dee075f68105c..d7891fa6c870257157783675816687740bbcc1bd 100644 (file)
@@ -976,18 +976,18 @@ struct win32_stat{
     int st_gid;
     int st_rdev;
     __int64 st_size;
-    int st_atime;
+    time_t st_atime;
     int st_atime_nsec;
-    int st_mtime;
+    time_t st_mtime;
     int st_mtime_nsec;
-    int st_ctime;
+    time_t st_ctime;
     int st_ctime_nsec;
 };
 
 static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
 
 static void
-FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
+FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, time_t *time_out, int* nsec_out)
 {
     /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
     /* Cannot simply cast and dereference in_ptr,
@@ -995,12 +995,11 @@ FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
     __int64 in;
     memcpy(&in, in_ptr, sizeof(in));
     *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
-    /* XXX Win32 supports time stamps past 2038; we currently don't */
-    *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
+    *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, time_t);
 }
 
 static void
-time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
+time_t_to_FILE_TIME(time_t time_in, int nsec_in, FILETIME *out_ptr)
 {
     /* XXX endianness */
     __int64 out;
@@ -3138,15 +3137,19 @@ posix_uname(PyObject *self, PyObject *noargs)
 #endif /* HAVE_UNAME */
 
 static int
-extract_time(PyObject *t, long* sec, long* usec)
+extract_time(PyObject *t, time_t* sec, long* usec)
 {
-    long intval;
+    time_t intval;
     if (PyFloat_Check(t)) {
         double tval = PyFloat_AsDouble(t);
-        PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
+        PyObject *intobj = PyNumber_Long(t);
         if (!intobj)
             return -1;
+#if SIZEOF_TIME_T > SIZEOF_LONG
+        intval = PyLong_AsUnsignedLongLongMask(intobj);
+#else
         intval = PyLong_AsLong(intobj);
+#endif
         Py_DECREF(intobj);
         if (intval == -1 && PyErr_Occurred())
             return -1;
@@ -3158,7 +3161,11 @@ extract_time(PyObject *t, long* sec, long* usec)
             *usec = 0;
         return 0;
     }
+#if SIZEOF_TIME_T > SIZEOF_LONG
+    intval = PyLong_AsUnsignedLongLongMask(t);
+#else
     intval = PyLong_AsLong(t);
+#endif
     if (intval == -1 && PyErr_Occurred())
         return -1;
     *sec = intval;
@@ -3182,7 +3189,8 @@ posix_utime(PyObject *self, PyObject *args)
     PyObject *oapath;
     char *apath;
     HANDLE hFile;
-    long atimesec, mtimesec, ausec, musec;
+    time_t atimesec, mtimesec;
+    long ausec, musec;
     FILETIME atime, mtime;
     PyObject *result = NULL;
 
@@ -3258,7 +3266,8 @@ done:
 
     PyObject *opath;
     char *path;
-    long atime, mtime, ausec, musec;
+    time_t atime, mtime;
+    long ausec, musec;
     int res;
     PyObject* arg;