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 = '
' % (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
+
+