diff --git a/Lib/calendar.py b/Lib/calendar.py index 45bb265a65602c..3b7f0b49a0236b 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -370,7 +370,7 @@ def formatweekday(self, day, width): """ Returns a formatted week day name. """ - if width >= 9: + if width >= max(map(len, day_name)): names = day_name else: names = day_abbr diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 589a21baf7bd61..410063e01582f9 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -696,6 +696,52 @@ def test_locale_calendar_formatweekday(self): except locale.Error: raise unittest.SkipTest('cannot set the en_US locale') + # These locales have weekday names all shorter than English's longest + # 'Wednesday'. They should not be abbreviated unnecessarily + @support.run_with_locales("LC_ALL", + 'Chinese', 'zh_CN.UTF-8', + 'French', 'fr_FR.UTF-8', + 'Norwegian', 'nb_NO.UTF-8', + 'Malay', 'ms_MY.UTF8' + ) + def test_locale_calendar_short_weekday_names(self): + names = (datetime.date(2001, 1, i+1).strftime('%A') for i in range(7)) + max_length = max(map(len, names)) + if max_length >= 9: + self.skipTest('weekday names are too long') + + def get_weekday_names(width): + return calendar.TextCalendar().formatweekheader(width).split() + + # Weekday names should not be abbreviated if the width is sufficient + self.assertEqual( + get_weekday_names(max_length), + get_weekday_names(max_length + 10) + ) + + # Any width shorter than necessary should produce abbreviations + self.assertNotEqual( + get_weekday_names(max_length), + get_weekday_names(max_length - 1) + ) + + # These locales have a weekday name longer than 'Wednesday' + # They should be properly abbreviated rather than truncated + @support.run_with_locales("LC_ALL", + 'Portuguese', 'pt_PT.UTF-8', + 'German', 'de_DE.UTF-8', + 'Russian', 'ru_RU.UTF-8', + ) + def test_locale_calendar_long_weekday_names(self): + names = (datetime.date(2001, 1, i+1).strftime('%A') for i in range(7)) + max_length = max(map(len, names)) + if max_length <= 9: + self.skipTest('weekday names are too short') + + def get_weekday_names(width): + return calendar.TextCalendar().formatweekheader(width).split() + self.assertEqual(get_weekday_names(4), get_weekday_names(9)) + def test_locale_calendar_formatmonthname(self): try: # formatmonthname uses the same month names regardless of the width argument. diff --git a/Misc/NEWS.d/next/Library/2025-08-06-16-54-22.gh-issue-137481.eSTkK0.rst b/Misc/NEWS.d/next/Library/2025-08-06-16-54-22.gh-issue-137481.eSTkK0.rst new file mode 100644 index 00000000000000..57d8d0521e39aa --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-08-06-16-54-22.gh-issue-137481.eSTkK0.rst @@ -0,0 +1,2 @@ +Calendar uses the lengths of the locale's weekdays to decide if the width +requires abbreviation.