Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r62862:b702bc169189
Date: 2013-03-28 20:55 -0700
http://bitbucket.org/pypy/pypy/changeset/b702bc169189/

Log:    cpython issue8013: replace asctime/ctime system calls with our own
        impl that accommodates a wider array of years

diff --git a/pypy/module/rctime/interp_time.py 
b/pypy/module/rctime/interp_time.py
--- a/pypy/module/rctime/interp_time.py
+++ b/pypy/module/rctime/interp_time.py
@@ -167,10 +167,8 @@
 TM_P = lltype.Ptr(tm)
 c_clock = external('clock', [rffi.TIME_TP], clock_t)
 c_time = external('time', [rffi.TIME_TP], rffi.TIME_T)
-c_ctime = external('ctime', [rffi.TIME_TP], rffi.CCHARP)
 c_gmtime = external('gmtime', [rffi.TIME_TP], TM_P)
 c_mktime = external('mktime', [TM_P], rffi.TIME_T)
-c_asctime = external('asctime', [TM_P], rffi.CCHARP)
 c_localtime = external('localtime', [rffi.TIME_TP], TM_P)
 if _POSIX:
     c_tzset = external('tzset', [], lltype.Void)
@@ -496,16 +494,13 @@
     not present, current time as returned by localtime() is used."""
 
     seconds = _get_inttime(space, w_seconds)
-
-    t_ref = lltype.malloc(rffi.TIME_TP.TO, 1, flavor='raw')
-    t_ref[0] = seconds
-    p = c_ctime(t_ref)
-    lltype.free(t_ref, flavor='raw')
+    with lltype.scoped_alloc(rffi.TIME_TP.TO, 1) as t_ref:
+        t_ref[0] = seconds
+        p = c_localtime(t_ref)
     if not p:
         raise OperationError(space.w_ValueError,
-            space.wrap("unconvertible time"))
-
-    return space.wrap(rffi.charp2str(p)[:-1]) # get rid of new line
+                             space.wrap("unconvertible time"))
+    return _asctime(space, p)
 
 # by now w_tup is an optional argument (and not *args)
 # because of the ext. compiler bugs in handling such arguments (*args, **kwds)
@@ -516,12 +511,25 @@
     When the time tuple is not present, current time as returned by localtime()
     is used."""
     buf_value = _gettmarg(space, w_tup)
-    p = c_asctime(buf_value)
-    if not p:
-        raise OperationError(space.w_ValueError,
-            space.wrap("unconvertible time"))
+    return _asctime(space, buf_value)
 
-    return space.wrap(rffi.charp2str(p)[:-1]) # get rid of new line
+_wday_names = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
+_mon_names = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
+              "Oct", "Nov", "Dec"]
+
+def _asctime(space, t_ref):
+    # Inspired by Open Group reference implementation available at
+    # http://pubs.opengroup.org/onlinepubs/009695399/functions/asctime.html
+    w, getif = space.wrap, rffi.getintfield
+    args = [w(_wday_names[getif(t_ref, 'c_tm_wday')]),
+            w(_mon_names[getif(t_ref, 'c_tm_mon')]),
+            w(getif(t_ref, 'c_tm_mday')),
+            w(getif(t_ref, 'c_tm_hour')),
+            w(getif(t_ref, 'c_tm_min')),
+            w(getif(t_ref, 'c_tm_sec')),
+            w(getif(t_ref, 'c_tm_year') + 1900)]
+    return space.mod(w("%.3s %.3s%3d %.2d:%.2d:%.2d %d"),
+                     space.newtuple(args))
 
 def gmtime(space, w_seconds=None):
     """gmtime([seconds]) -> (tm_year, tm_mon, tm_day, tm_hour, tm_min,
diff --git a/pypy/module/rctime/test/test_rctime.py 
b/pypy/module/rctime/test/test_rctime.py
--- a/pypy/module/rctime/test/test_rctime.py
+++ b/pypy/module/rctime/test/test_rctime.py
@@ -43,6 +43,15 @@
         assert isinstance(res, str)
         rctime.ctime(rctime.time())
         raises(ValueError, rctime.ctime, 1E200)
+        for year in [-100, 100, 1000, 2000, 10000]:
+            try:
+                testval = rctime.mktime((year, 1, 10) + (0,)*6)
+            except (ValueError, OverflowError):
+                # If mktime fails, ctime will fail too.  This may happen
+                # on some platforms.
+                pass
+            else:
+                assert rctime.ctime(testval)[20:] == str(year)
 
     def test_gmtime(self):
         import time as rctime
@@ -139,6 +148,13 @@
         ltime = rctime.localtime()
         assert rctime.asctime(tuple(ltime)) == rctime.asctime(ltime)
 
+    def test_asctime_large_year(self):
+        import time as rctime
+        assert rctime.asctime((12345,) +
+                              (0,) * 8) == 'Mon Jan  1 00:00:00 12345'
+        assert rctime.asctime((123456789,) +
+                              (0,) * 8) == 'Mon Jan  1 00:00:00 123456789'
+
     def test_accept2dyear_access(self):
         import time as rctime
 
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to