From 0c2c8e77fba38a68554b264a2985000d3006d8d1 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sat, 23 Mar 2002 03:26:53 +0000 Subject: [PATCH] SF bug 533234: tm_isdst > 1 Passed to strftime. One more time on this turkey, but duller instead of cleverer. Curious: The docs say __getslice__ has been deprecated since 2.0, but list.__getitem__ still doesn't work if you pass it a slice. This makes it a lot clearer to emulate a list by *being* a list . Bugfix candidate. Michael, just pile this patch on top of the others that went by -- no need to try to pick these apart. --- Lib/calendar.py | 61 +++++++++++++++++++++++++++------------ Lib/test/test_calendar.py | 23 +++++++++++++++ 2 files changed, 66 insertions(+), 18 deletions(-) diff --git a/Lib/calendar.py b/Lib/calendar.py index cb6354784e5..8c81b5398cb 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -9,10 +9,12 @@ set the first day of the week (0=Monday, 6=Sunday).""" # Import functions and variables from time module from time import localtime, mktime, strftime +from types import SliceType __all__ = ["error","setfirstweekday","firstweekday","isleap", "leapdays","weekday","monthrange","monthcalendar", - "prmonth","month","prcal","calendar","timegm"] + "prmonth","month","prcal","calendar","timegm", + "month_name", "month_abbr", "day_name", "day_abbr"] # Exception raised for bad input (with string parameter for details) error = ValueError @@ -24,29 +26,52 @@ February = 2 # Number of days per month (except for February in leap years) mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] -class _localized_name: - def __init__(self, format, len): +# This module used to have hard-coded lists of day and month names, as +# English strings. The classes following emulate a read-only version of +# that, but supply localized names. Note that the values are computed +# fresh on each call, in case the user changes locale between calls. + +class _indexer: + def __getitem__(self, i): + if isinstance(i, SliceType): + return self.data[i.start : i.stop] + else: + # May raise an appropriate exception. + return self.data[i] + +class _localized_month(_indexer): + def __init__(self, format): self.format = format - self.len = len - def __getitem__(self, item): - if isinstance(item, int): - if item < 0: item += self.len - if not 0 <= item < self.len: - raise IndexError, "out of range" - t = (2001, 1, item+1, 12, 0, 0, item, item+1, 0) - return strftime(self.format, t).capitalize() - elif isinstance(item, type(slice(0))): - return [self[e] for e in range(self.len)].__getslice__(item.start, item.stop) + + def __getitem__(self, i): + self.data = [strftime(self.format, (2001, j, 1, 12, 0, 0, 1, 1, 0)) + for j in range(1, 13)] + self.data.insert(0, "") + return _indexer.__getitem__(self, i) + def __len__(self): - return self.len + return 13 + +class _localized_day(_indexer): + def __init__(self, format): + self.format = format + + def __getitem__(self, i): + # January 1, 2001, was a Monday. + self.data = [strftime(self.format, (2001, 1, j+1, 12, 0, 0, j, j+1, 0)) + for j in range(7)] + return _indexer.__getitem__(self, i) + + def __len__(self_): + return 7 # Full and abbreviated names of weekdays -day_name = _localized_name('%A', 7) -day_abbr = _localized_name('%a', 7) +day_name = _localized_day('%A') +day_abbr = _localized_day('%a') # Full and abbreviated names of months (1-based arrays!!!) -month_name = _localized_name('%B', 13) -month_abbr = _localized_name('%b', 13) +month_name = _localized_month('%B') +month_abbr = _localized_month('%b') # Constants for weekdays (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index eed96efa936..2059eaf3558 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -31,6 +31,29 @@ class CalendarTestCase(unittest.TestCase): self.assertRaises(IndexError, calendar.day_name.__getitem__, 10) self.assertEqual(len([d for d in calendar.day_abbr]), 7) + def test_days(self): + for attr in "day_name", "day_abbr": + value = getattr(calendar, attr) + self.assertEqual(len(value), 7) + self.assertEqual(len(value[:]), 7) + # ensure they're all unique + d = {} + for v in value: + d[v] = 1 + self.assertEqual(len(d), 7) + + def test_months(self): + for attr in "month_name", "month_abbr": + value = getattr(calendar, attr) + self.assertEqual(len(value), 13) + self.assertEqual(len(value[:]), 13) + self.assertEqual(value[0], "") + # ensure they're all unique + d = {} + for v in value: + d[v] = 1 + self.assertEqual(len(d), 13) + def test_main(): run_unittest(CalendarTestCase)