[pypy-svn] r30146 - in pypy/dist/pypy/module/rctime: . test
rhymes at codespeak.net
rhymes at codespeak.net
Tue Jul 18 13:03:41 CEST 2006
Author: rhymes
Date: Tue Jul 18 13:03:24 2006
New Revision: 30146
Modified:
pypy/dist/pypy/module/rctime/__init__.py
pypy/dist/pypy/module/rctime/interp_time.py
pypy/dist/pypy/module/rctime/test/test_rctime.py
Log:
added strftime() support.
Modified: pypy/dist/pypy/module/rctime/__init__.py
==============================================================================
--- pypy/dist/pypy/module/rctime/__init__.py (original)
+++ pypy/dist/pypy/module/rctime/__init__.py Tue Jul 18 13:03:24 2006
@@ -15,7 +15,8 @@
'gmtime': 'interp_time.gmtime',
'localtime': 'interp_time.localtime',
'mktime': 'interp_time.mktime',
- 'tzset': 'interp_time.tzset'
+ 'tzset': 'interp_time.tzset',
+ 'strftime': 'interp_time.strftime',
}
# def init(self, space):
Modified: pypy/dist/pypy/module/rctime/interp_time.py
==============================================================================
--- pypy/dist/pypy/module/rctime/interp_time.py (original)
+++ pypy/dist/pypy/module/rctime/interp_time.py Tue Jul 18 13:03:24 2006
@@ -25,6 +25,7 @@
CLOCKS_PER_SEC = ctypes_platform.ConstantInteger("CLOCKS_PER_SEC")
clock_t = ctypes_platform.SimpleType("clock_t", c_ulong)
time_t = ctypes_platform.SimpleType("time_t", c_long)
+ size_t = ctypes_platform.SimpleType("time_t", c_long)
class cConfig:
pass
@@ -35,6 +36,7 @@
CLOCKS_PER_SEC = cConfig.CLOCKS_PER_SEC
clock_t = cConfig.clock_t
time_t = cConfig.time_t
+size_t = cConfig.size_t
timeval = cConfig.timeval
tm = cConfig.tm
@@ -59,6 +61,8 @@
libc.asctime.argtypes = [POINTER(tm)]
libc.asctime.restype = c_char_p
libc.tzset.restype = None # tzset() returns void
+libc.strftime.argtypes = [c_char_p, size_t, c_char_p, POINTER(tm)]
+libc.strftime.restype = size_t
def _init_accept2dyear():
return (1, 0)[bool(os.getenv("PYTHONY2K"))]
@@ -413,3 +417,92 @@
_set_module_list_object(space, 'tzname', tzname_w)
_set_module_object(space, 'altzone', altzone)
tzset.unwrap_spec = [ObjSpace]
+
+def strftime(space, w_format, w_tup=None):
+ """strftime(format[, tuple]) -> string
+
+ Convert a time tuple to a string according to a format specification.
+ See the library reference manual for formatting codes. When the time tuple
+ is not present, current time as returned by localtime() is used."""
+
+ tup = None
+ tuple_len = 0
+ buf_value = tm()
+
+ format = space.str_w(w_format)
+
+ # if len(tup_w):
+ # w_tup = tup_w[0]
+ if not space.is_w(w_tup, space.w_None):
+ tuple_len = space.int_w(space.len(w_tup))
+
+ #if space.is_w(w_tup, space.w_None) or 1 < tuple_len < 9:
+ if 1 < tuple_len < 9:
+ raise OperationError(space.w_TypeError,
+ space.wrap("argument must be 9-item sequence"))
+
+ # check if every passed object is a int
+ tup = space.unpackiterable(w_tup)
+ for t in tup:
+ space.int_w(t)
+ # map(space.int_w, tup) # XXX: can't use it
+
+ buf_value = _gettmarg(space, tup, buf_value)
+ else:
+ # empty list
+ buf = None
+
+ tt = time_t(int(_floattime()))
+ buf = libc.localtime(byref(tt))
+ if not buf:
+ raise OperationError(space.w_ValueError,
+ space.wrap(_get_error_msg()))
+ buf_value = buf.contents
+
+ # Checks added to make sure strftime() does not crash Python by
+ # indexing blindly into some array for a textual representation
+ # by some bad index (fixes bug #897625).
+ # No check for year since handled in gettmarg().
+ if buf_value.tm_mon < 0 or buf_value.tm_mon > 11:
+ raise OperationError(space.w_ValueError,
+ space.wrap("month out of range"))
+ if buf_value.tm_mday < 1 or buf_value.tm_mday > 31:
+ raise OperationError(space.w_ValueError,
+ space.wrap("day of month out of range"))
+ if buf_value.tm_hour < 0 or buf_value.tm_hour > 23:
+ raise OperationError(space.w_ValueError,
+ space.wrap("hour out of range"))
+ if buf_value.tm_min < 0 or buf_value.tm_min > 59:
+ raise OperationError(space.w_ValueError,
+ space.wrap("minute out of range"))
+ if buf_value.tm_sec < 0 or buf_value.tm_sec > 61:
+ raise OperationError(space.w_ValueError,
+ space.wrap("seconds out of range"))
+ # tm_wday does not need checking of its upper-bound since taking
+ # "% 7" in gettmarg() automatically restricts the range.
+ if buf_value.tm_wday < 0:
+ raise OperationError(space.w_ValueError,
+ space.wrap("day of week out of range"))
+ if buf_value.tm_yday < 0 or buf_value.tm_yday > 365:
+ raise OperationError(space.w_ValueError,
+ space.wrap("day of year out of range"))
+ if buf_value.tm_isdst < -1 or buf_value.tm_isdst > 1:
+ raise OperationError(space.w_ValueError,
+ space.wrap("daylight savings flag out of range"))
+
+ i = 1024
+ while True:
+ outbuf = create_string_buffer(i)
+ buflen = libc.strftime(outbuf, i, format, byref(buf_value))
+
+ if buflen > 0 or i >= 256 * len(format):
+ # if the buffer is 256 times as long as the format,
+ # it's probably not failing for lack of room!
+ # More likely, the format yields an empty result,
+ # e.g. an empty format, or %Z when the timezone
+ # is unknown.
+ if buflen > 0:
+ return space.wrap(outbuf.value[:buflen])
+
+ i += i
+strftime.unwrap_spec = [ObjSpace, W_Root, W_Root]
Modified: pypy/dist/pypy/module/rctime/test/test_rctime.py
==============================================================================
--- pypy/dist/pypy/module/rctime/test/test_rctime.py (original)
+++ pypy/dist/pypy/module/rctime/test/test_rctime.py Tue Jul 18 13:03:24 2006
@@ -190,55 +190,57 @@
elif os.environ.has_key('TZ'):
del os.environ['TZ']
rctime.tzset()
- #
- # def test_strftime():
- # tt = rctime.gmtime(t)
- # for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
- # 'j', 'm', 'M', 'p', 'S',
- # 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
- # format = ' %' + directive
- # assert rctime.strftime(format, tt) != None
- # assert rctime.strftime(format, tt) != ""
- #
- # def test_strftime_bounds_checking():
- # # make sure that strftime() checks the bounds of the various parts
- # # of the time tuple.
- #
- # raises = py.test.raises
- #
- # # check year
- # raises(ValueError, rctime.strftime, '', (1899, 1, 1, 0, 0, 0, 0, 1, -1))
- # if rctime.accept2dyear:
- # raises(ValueError, rctime.strftime, '', (-1, 1, 1, 0, 0, 0, 0, 1, -1))
- # raises(ValueError, rctime.strftime, '', (100, 1, 1, 0, 0, 0, 0, 1, -1))
- # # check month
- # raises(ValueError, rctime.strftime, '', (1900, 0, 1, 0, 0, 0, 0, 1, -1))
- # raises(ValueError, rctime.strftime, '', (1900, 13, 1, 0, 0, 0, 0, 1, -1))
- # # check day of month
- # raises(ValueError, rctime.strftime, '', (1900, 1, 0, 0, 0, 0, 0, 1, -1))
- # raises(ValueError, rctime.strftime, '', (1900, 1, 32, 0, 0, 0, 0, 1, -1))
- # # check hour
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, -1, 0, 0, 0, 1, -1))
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 24, 0, 0, 0, 1, -1))
- # # check minute
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, -1, 0, 0, 1, -1))
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 60, 0, 0, 1, -1))
- # # check second
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, -1, 0, 1, -1))
- # # C99 only requires allowing for one leap second, but Python's docs say
- # # allow two leap seconds (0..61)
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 62, 0, 1, -1))
- # # no check for upper-bound day of week;
- # # value forced into range by a "% 7" calculation.
- # # start check at -2 since gettmarg() increments value before taking
- # # modulo.
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, -2, 1, -1))
- # # check day of the year
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 0, -1))
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 367, -1))
- # # check daylight savings flag
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, -2))
- # raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, 2))
+
+ def test_strftime(self):
+ import rctime
+
+ t = rctime.time()
+ tt = rctime.gmtime(t)
+ for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
+ 'j', 'm', 'M', 'p', 'S',
+ 'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
+ format = ' %' + directive
+ rctime.strftime(format, tt)
+
+ def test_strftime_bounds_checking(self):
+ import rctime
+
+ # make sure that strftime() checks the bounds of the various parts
+ # of the time tuple.
+
+ # check year
+ raises(ValueError, rctime.strftime, '', (1899, 1, 1, 0, 0, 0, 0, 1, -1))
+ if rctime.accept2dyear:
+ raises(ValueError, rctime.strftime, '', (-1, 1, 1, 0, 0, 0, 0, 1, -1))
+ raises(ValueError, rctime.strftime, '', (100, 1, 1, 0, 0, 0, 0, 1, -1))
+ # check month
+ raises(ValueError, rctime.strftime, '', (1900, 0, 1, 0, 0, 0, 0, 1, -1))
+ raises(ValueError, rctime.strftime, '', (1900, 13, 1, 0, 0, 0, 0, 1, -1))
+ # check day of month
+ raises(ValueError, rctime.strftime, '', (1900, 1, 0, 0, 0, 0, 0, 1, -1))
+ raises(ValueError, rctime.strftime, '', (1900, 1, 32, 0, 0, 0, 0, 1, -1))
+ # check hour
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, -1, 0, 0, 0, 1, -1))
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 24, 0, 0, 0, 1, -1))
+ # check minute
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, -1, 0, 0, 1, -1))
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 60, 0, 0, 1, -1))
+ # check second
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, -1, 0, 1, -1))
+ # C99 only requires allowing for one leap second, but Python's docs say
+ # allow two leap seconds (0..61)
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 62, 0, 1, -1))
+ # no check for upper-bound day of week;
+ # value forced into range by a "% 7" calculation.
+ # start check at -2 since gettmarg() increments value before taking
+ # modulo.
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, -2, 1, -1))
+ # check day of the year
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 0, -1))
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 367, -1))
+ # check daylight savings flag
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, -2))
+ raises(ValueError, rctime.strftime, '', (1900, 1, 1, 0, 0, 0, 0, 1, 2))
#
# def test_strptime():
# tt = rctime.gmtime(t)
More information about the Pypy-commit
mailing list