Commit 4c254d51 authored by Walter Dörwald's avatar Walter Dörwald

Patch #1463288: use a context manager to temporarily switch locales.

Add tests for the output of the TextCalendar and HTMLCalendar classes.
parent 60de6eaf
...@@ -5,6 +5,7 @@ default, these calendars have Monday as the first day of the week, and ...@@ -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 Sunday as the last (the European convention). Use setfirstweekday() to
set the first day of the week (0=Monday, 6=Sunday).""" set the first day of the week (0=Monday, 6=Sunday)."""
from __future__ import with_statement
import sys, datetime, locale import sys, datetime, locale
__all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", __all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday",
...@@ -479,6 +480,21 @@ class HTMLCalendar(Calendar): ...@@ -479,6 +480,21 @@ class HTMLCalendar(Calendar):
return ''.join(v).encode(encoding, "xmlcharrefreplace") 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): class LocaleTextCalendar(TextCalendar):
""" """
This class can be passed a locale name in the constructor and will return This class can be passed a locale name in the constructor and will return
...@@ -494,9 +510,7 @@ class LocaleTextCalendar(TextCalendar): ...@@ -494,9 +510,7 @@ class LocaleTextCalendar(TextCalendar):
self.locale = locale self.locale = locale
def formatweekday(self, day, width): def formatweekday(self, day, width):
oldlocale = locale.setlocale(locale.LC_TIME, self.locale) with TimeEncoding(self.locale) as encoding:
try:
encoding = locale.getlocale(locale.LC_TIME)[1]
if width >= 9: if width >= 9:
names = day_name names = day_name
else: else:
...@@ -504,24 +518,16 @@ class LocaleTextCalendar(TextCalendar): ...@@ -504,24 +518,16 @@ class LocaleTextCalendar(TextCalendar):
name = names[day] name = names[day]
if encoding is not None: if encoding is not None:
name = name.decode(encoding) name = name.decode(encoding)
result = name[:width].center(width) return name[:width].center(width)
finally:
locale.setlocale(locale.LC_TIME, oldlocale)
return result
def formatmonthname(self, theyear, themonth, width, withyear=True): def formatmonthname(self, theyear, themonth, width, withyear=True):
oldlocale = locale.setlocale(locale.LC_TIME, self.locale) with TimeEncoding(self.locale) as encoding:
try:
encoding = locale.getlocale(locale.LC_TIME)[1]
s = month_name[themonth] s = month_name[themonth]
if encoding is not None: if encoding is not None:
s = s.decode(encoding) s = s.decode(encoding)
if withyear: if withyear:
s = "%s %r" % (s, theyear) s = "%s %r" % (s, theyear)
result = s.center(width) return s.center(width)
finally:
locale.setlocale(locale.LC_TIME, oldlocale)
return result
class LocaleHTMLCalendar(HTMLCalendar): class LocaleHTMLCalendar(HTMLCalendar):
...@@ -538,30 +544,20 @@ class LocaleHTMLCalendar(HTMLCalendar): ...@@ -538,30 +544,20 @@ class LocaleHTMLCalendar(HTMLCalendar):
self.locale = locale self.locale = locale
def formatweekday(self, day): def formatweekday(self, day):
oldlocale = locale.setlocale(locale.LC_TIME, self.locale) with TimeEncoding(self.locale) as encoding:
try:
encoding = locale.getlocale(locale.LC_TIME)[1]
s = day_abbr[day] s = day_abbr[day]
if encoding is not None: if encoding is not None:
s = s.decode(encoding) s = s.decode(encoding)
result = '<th class="%s">%s</th>' % (self.cssclasses[day], s) return '<th class="%s">%s</th>' % (self.cssclasses[day], s)
finally:
locale.setlocale(locale.LC_TIME, oldlocale)
return result
def formatmonthname(self, theyear, themonth, withyear=True): def formatmonthname(self, theyear, themonth, withyear=True):
oldlocale = locale.setlocale(locale.LC_TIME, self.locale) with TimeEncoding(self.locale) as encoding:
try:
encoding = locale.getlocale(locale.LC_TIME)[1]
s = month_name[themonth] s = month_name[themonth]
if encoding is not None: if encoding is not None:
s = s.decode(encoding) s = s.decode(encoding)
if withyear: if withyear:
s = '%s %s' % (s, theyear) s = '%s %s' % (s, theyear)
result = '<tr><th colspan="7" class="month">%s</th></tr>' % s return '<tr><th colspan="7" class="month">%s</th></tr>' % s
finally:
locale.setlocale(locale.LC_TIME, oldlocale)
return result
# Support for old module level interface # Support for old module level interface
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment