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