From: Walter Dörwald Date: Wed, 12 Apr 2006 10:09:16 +0000 (+0000) Subject: Patch #1463288: use a context manager to temporarily switch locales. X-Git-Tag: v2.5a2~309 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bc96609555db6f62fa755c047d7db4441dd2ffe1;p=python Patch #1463288: use a context manager to temporarily switch locales. Add tests for the output of the TextCalendar and HTMLCalendar classes. --- diff --git a/Lib/calendar.py b/Lib/calendar.py index db7b2b63fd..7800aaeaf9 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -5,6 +5,7 @@ default, these calendars have Monday as the first day of the week, and Sunday as the last (the European convention). Use setfirstweekday() to set the first day of the week (0=Monday, 6=Sunday).""" +from __future__ import with_statement import sys, datetime, locale __all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", @@ -479,6 +480,21 @@ class HTMLCalendar(Calendar): return ''.join(v).encode(encoding, "xmlcharrefreplace") +class TimeEncoding: + def __init__(self, locale): + self.locale = locale + + def __context__(self): + return self + + def __enter__(self): + self.oldlocale = locale.setlocale(locale.LC_TIME, self.locale) + return locale.getlocale(locale.LC_TIME)[1] + + def __exit__(self, *args): + locale.setlocale(locale.LC_TIME, self.oldlocale) + + class LocaleTextCalendar(TextCalendar): """ This class can be passed a locale name in the constructor and will return @@ -494,9 +510,7 @@ class LocaleTextCalendar(TextCalendar): self.locale = locale def formatweekday(self, day, width): - oldlocale = locale.setlocale(locale.LC_TIME, self.locale) - try: - encoding = locale.getlocale(locale.LC_TIME)[1] + with TimeEncoding(self.locale) as encoding: if width >= 9: names = day_name else: @@ -504,24 +518,16 @@ class LocaleTextCalendar(TextCalendar): name = names[day] if encoding is not None: name = name.decode(encoding) - result = name[:width].center(width) - finally: - locale.setlocale(locale.LC_TIME, oldlocale) - return result + return name[:width].center(width) def formatmonthname(self, theyear, themonth, width, withyear=True): - oldlocale = locale.setlocale(locale.LC_TIME, self.locale) - try: - encoding = locale.getlocale(locale.LC_TIME)[1] + with TimeEncoding(self.locale) as encoding: s = month_name[themonth] if encoding is not None: s = s.decode(encoding) if withyear: s = "%s %r" % (s, theyear) - result = s.center(width) - finally: - locale.setlocale(locale.LC_TIME, oldlocale) - return result + return s.center(width) class LocaleHTMLCalendar(HTMLCalendar): @@ -538,30 +544,20 @@ class LocaleHTMLCalendar(HTMLCalendar): self.locale = locale def formatweekday(self, day): - oldlocale = locale.setlocale(locale.LC_TIME, self.locale) - try: - encoding = locale.getlocale(locale.LC_TIME)[1] + with TimeEncoding(self.locale) as encoding: s = day_abbr[day] if encoding is not None: s = s.decode(encoding) - result = '%s' % (self.cssclasses[day], s) - finally: - locale.setlocale(locale.LC_TIME, oldlocale) - return result + return '%s' % (self.cssclasses[day], s) def formatmonthname(self, theyear, themonth, withyear=True): - oldlocale = locale.setlocale(locale.LC_TIME, self.locale) - try: - encoding = locale.getlocale(locale.LC_TIME)[1] + with TimeEncoding(self.locale) as encoding: s = month_name[themonth] if encoding is not None: s = s.decode(encoding) if withyear: s = '%s %s' % (s, theyear) - result = '%s' % s - finally: - locale.setlocale(locale.LC_TIME, oldlocale) - return result + return '%s' % s # Support for old module level interface diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index bd8e6b415a..e414324d67 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -4,7 +4,7 @@ import unittest from test import test_support -result_2004 = """ +result_2004_text = """ 2004 January February March @@ -42,9 +42,135 @@ Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su Mo Tu We Th Fr Sa Su 25 26 27 28 29 30 31 29 30 27 28 29 30 31 """ +result_2004_html = """ + + + + + + +Calendar for 2004 + + +
2004
+ + + + + + + +
January
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
262728293031 
+
+ + + + + + + +
February
MonTueWedThuFriSatSun
      1
2345678
9101112131415
16171819202122
23242526272829
+
+ + + + + + + +
March
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
293031    
+
+ + + + + + + +
April
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
2627282930  
+
+ + + + + + + + +
May
MonTueWedThuFriSatSun
     12
3456789
10111213141516
17181920212223
24252627282930
31      
+
+ + + + + + + +
June
MonTueWedThuFriSatSun
 123456
78910111213
14151617181920
21222324252627
282930    
+
+ + + + + + + +
July
MonTueWedThuFriSatSun
   1234
567891011
12131415161718
19202122232425
262728293031 
+
+ + + + + + + + +
August
MonTueWedThuFriSatSun
      1
2345678
9101112131415
16171819202122
23242526272829
3031     
+
+ + + + + + + +
September
MonTueWedThuFriSatSun
  12345
6789101112
13141516171819
20212223242526
27282930   
+
+ + + + + + + +
October
MonTueWedThuFriSatSun
    123
45678910
11121314151617
18192021222324
25262728293031
+
+ + + + + + + +
November
MonTueWedThuFriSatSun
1234567
891011121314
15161718192021
22232425262728
2930     
+
+ + + + + + + +
December
MonTueWedThuFriSatSun
  12345
6789101112
13141516171819
20212223242526
2728293031  
+
+ +""" + class OutputTestCase(unittest.TestCase): def normalize_calendar(self, s): + # Filters out locale dependant strings def neitherspacenordigit(c): return not c.isspace() and not c.isdigit() @@ -58,7 +184,19 @@ class OutputTestCase(unittest.TestCase): def test_output(self): self.assertEqual( self.normalize_calendar(calendar.calendar(2004)), - self.normalize_calendar(result_2004) + self.normalize_calendar(result_2004_text) + ) + + def test_output_textcalendar(self): + self.assertEqual( + calendar.TextCalendar().formatyear(2004).strip(), + result_2004_text.strip() + ) + + def test_output_htmlcalendar(self): + self.assertEqual( + calendar.HTMLCalendar().formatyearpage(2004).strip(), + result_2004_html.strip() )