Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f9715c4

Browse filesBrowse files
authored
Merge pull request #4669 from carlosmiei/update-calendar
Update calendar.py from CPython 3.11
2 parents e73a1c3 + 7710ed0 commit f9715c4
Copy full SHA for f9715c4

File tree

Expand file treeCollapse file tree

2 files changed

+76
-33
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+76
-33
lines changed

‎Lib/calendar.py

Copy file name to clipboardExpand all lines: Lib/calendar.py
+25-27Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
"monthcalendar", "prmonth", "month", "prcal", "calendar",
1616
"timegm", "month_name", "month_abbr", "day_name", "day_abbr",
1717
"Calendar", "TextCalendar", "HTMLCalendar", "LocaleTextCalendar",
18-
"LocaleHTMLCalendar", "weekheader"]
18+
"LocaleHTMLCalendar", "weekheader",
19+
"MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY",
20+
"SATURDAY", "SUNDAY"]
1921

2022
# Exception raised for bad input (with string parameter for details)
2123
error = ValueError
@@ -546,71 +548,67 @@ def formatyearpage(self, theyear, width=3, css='calendar.css', encoding=None):
546548
class different_locale:
547549
def __init__(self, locale):
548550
self.locale = locale
551+
self.oldlocale = None
549552

550553
def __enter__(self):
551-
self.oldlocale = _locale.getlocale(_locale.LC_TIME)
554+
self.oldlocale = _locale.setlocale(_locale.LC_TIME, None)
552555
_locale.setlocale(_locale.LC_TIME, self.locale)
553556

554557
def __exit__(self, *args):
558+
if self.oldlocale is None:
559+
return
555560
_locale.setlocale(_locale.LC_TIME, self.oldlocale)
556561

557562

563+
def _get_default_locale():
564+
locale = _locale.setlocale(_locale.LC_TIME, None)
565+
if locale == "C":
566+
with different_locale(""):
567+
# The LC_TIME locale does not seem to be configured:
568+
# get the user preferred locale.
569+
locale = _locale.setlocale(_locale.LC_TIME, None)
570+
return locale
571+
572+
558573
class LocaleTextCalendar(TextCalendar):
559574
"""
560575
This class can be passed a locale name in the constructor and will return
561-
month and weekday names in the specified locale. If this locale includes
562-
an encoding all strings containing month and weekday names will be returned
563-
as unicode.
576+
month and weekday names in the specified locale.
564577
"""
565578

566579
def __init__(self, firstweekday=0, locale=None):
567580
TextCalendar.__init__(self, firstweekday)
568581
if locale is None:
569-
locale = _locale.getdefaultlocale()
582+
locale = _get_default_locale()
570583
self.locale = locale
571584

572585
def formatweekday(self, day, width):
573586
with different_locale(self.locale):
574-
if width >= 9:
575-
names = day_name
576-
else:
577-
names = day_abbr
578-
name = names[day]
579-
return name[:width].center(width)
587+
return super().formatweekday(day, width)
580588

581589
def formatmonthname(self, theyear, themonth, width, withyear=True):
582590
with different_locale(self.locale):
583-
s = month_name[themonth]
584-
if withyear:
585-
s = "%s %r" % (s, theyear)
586-
return s.center(width)
591+
return super().formatmonthname(theyear, themonth, width, withyear)
587592

588593

589594
class LocaleHTMLCalendar(HTMLCalendar):
590595
"""
591596
This class can be passed a locale name in the constructor and will return
592-
month and weekday names in the specified locale. If this locale includes
593-
an encoding all strings containing month and weekday names will be returned
594-
as unicode.
597+
month and weekday names in the specified locale.
595598
"""
596599
def __init__(self, firstweekday=0, locale=None):
597600
HTMLCalendar.__init__(self, firstweekday)
598601
if locale is None:
599-
locale = _locale.getdefaultlocale()
602+
locale = _get_default_locale()
600603
self.locale = locale
601604

602605
def formatweekday(self, day):
603606
with different_locale(self.locale):
604-
s = day_abbr[day]
605-
return '<th class="%s">%s</th>' % (self.cssclasses[day], s)
607+
return super().formatweekday(day)
606608

607609
def formatmonthname(self, theyear, themonth, withyear=True):
608610
with different_locale(self.locale):
609-
s = month_name[themonth]
610-
if withyear:
611-
s = '%s %s' % (s, theyear)
612-
return '<tr><th colspan="7" class="month">%s</th></tr>' % s
613-
611+
return super().formatmonthname(theyear, themonth, withyear)
614612

615613
# Support for old module level interface
616614
c = TextCalendar()

‎Lib/test/test_calendar.py

Copy file name to clipboardExpand all lines: Lib/test/test_calendar.py
+51-6Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,43 @@ def test_locale_calendars(self):
564564
new_october = calendar.TextCalendar().formatmonthname(2010, 10, 10)
565565
self.assertEqual(old_october, new_october)
566566

567+
def test_locale_calendar_formatweekday(self):
568+
try:
569+
# formatweekday uses different day names based on the available width.
570+
cal = calendar.LocaleTextCalendar(locale='en_US')
571+
# For short widths, a centered, abbreviated name is used.
572+
self.assertEqual(cal.formatweekday(0, 5), " Mon ")
573+
# For really short widths, even the abbreviated name is truncated.
574+
self.assertEqual(cal.formatweekday(0, 2), "Mo")
575+
# For long widths, the full day name is used.
576+
self.assertEqual(cal.formatweekday(0, 10), " Monday ")
577+
except locale.Error:
578+
raise unittest.SkipTest('cannot set the en_US locale')
579+
580+
def test_locale_html_calendar_custom_css_class_month_name(self):
581+
try:
582+
cal = calendar.LocaleHTMLCalendar(locale='')
583+
local_month = cal.formatmonthname(2010, 10, 10)
584+
except locale.Error:
585+
# cannot set the system default locale -- skip rest of test
586+
raise unittest.SkipTest('cannot set the system default locale')
587+
self.assertIn('class="month"', local_month)
588+
cal.cssclass_month_head = "text-center month"
589+
local_month = cal.formatmonthname(2010, 10, 10)
590+
self.assertIn('class="text-center month"', local_month)
591+
592+
def test_locale_html_calendar_custom_css_class_weekday(self):
593+
try:
594+
cal = calendar.LocaleHTMLCalendar(locale='')
595+
local_weekday = cal.formatweekday(6)
596+
except locale.Error:
597+
# cannot set the system default locale -- skip rest of test
598+
raise unittest.SkipTest('cannot set the system default locale')
599+
self.assertIn('class="sun"', local_weekday)
600+
cal.cssclasses_weekday_head = ["mon2", "tue2", "wed2", "thu2", "fri2", "sat2", "sun2"]
601+
local_weekday = cal.formatweekday(6)
602+
self.assertIn('class="sun2"', local_weekday)
603+
567604
def test_itermonthdays3(self):
568605
# ensure itermonthdays3 doesn't overflow after datetime.MAXYEAR
569606
list(calendar.Calendar().itermonthdays3(datetime.MAXYEAR, 12))
@@ -595,6 +632,14 @@ def test_itermonthdays2(self):
595632
self.assertEqual(days[0][1], firstweekday)
596633
self.assertEqual(days[-1][1], (firstweekday - 1) % 7)
597634

635+
def test_iterweekdays(self):
636+
week0 = list(range(7))
637+
for firstweekday in range(7):
638+
cal = calendar.Calendar(firstweekday)
639+
week = list(cal.iterweekdays())
640+
expected = week0[firstweekday:] + week0[:firstweekday]
641+
self.assertEqual(week, expected)
642+
598643

599644
class MonthCalendarTestCase(unittest.TestCase):
600645
def setUp(self):
@@ -837,7 +882,8 @@ def test_option_locale(self):
837882
self.assertFailure('-L')
838883
self.assertFailure('--locale')
839884
self.assertFailure('-L', 'en')
840-
lang, enc = locale.getdefaultlocale()
885+
886+
lang, enc = locale.getlocale()
841887
lang = lang or 'C'
842888
enc = enc or 'UTF-8'
843889
try:
@@ -912,11 +958,10 @@ def test_html_output_year_css(self):
912958

913959
class MiscTestCase(unittest.TestCase):
914960
def test__all__(self):
915-
not_exported = {'mdays', 'January', 'February', 'EPOCH',
916-
'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY',
917-
'SATURDAY', 'SUNDAY', 'different_locale', 'c',
918-
'prweek', 'week', 'format', 'formatstring', 'main',
919-
'monthlen', 'prevmonth', 'nextmonth'}
961+
not_exported = {
962+
'mdays', 'January', 'February', 'EPOCH',
963+
'different_locale', 'c', 'prweek', 'week', 'format',
964+
'formatstring', 'main', 'monthlen', 'prevmonth', 'nextmonth'}
920965
support.check__all__(self, calendar, not_exported=not_exported)
921966

922967

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.