GeezerVison is showing github.com — calendar displays month names in a genitive case for some locales · Issue #131146 · python/cpython
calendar displays month names in a genitive case for some locales #131146DescriptionBug report
Bug description:
A calendar module CLI displays month names in a Polish, and other Slavic languages using the genitive case, as it is used in a phrase "in January". However, for standalone usage, month names should appear in the nominative case to be grammatically correct. For instance, in Polish, "January" should be written as "styczeń" instead of "stycznia"; similarly, in Russian, it should be "январь" rather than "января". This issue likely affects Baltic languages and Greek as well.
Example command demonstrating the issue:
python3 -m calendar --locale pl_PL --encoding utf
This problem occurs because the calendar module uses the strftime %B format specifier, which returns month names suitable for complete date contexts (genitive case). Instead, a nominative form is required when months are mentioned independently:
|
# Full and abbreviated names of months (1-based arrays!!!) |
|
month_name = _localized_month('%B') |
|
month_abbr = _localized_month('%b') |
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Reacted by Kirill Podoprigora Activitypicnixz commented on Mar 12, 2025
This problem occurs because the calendar module uses the strftime %B format specifier, which returns month names suitable for complete date contexts (genitive case). Instead, a nominative form is required when months are mentioned independently:
What would be the format specifier in this case? plashchynski commented on Mar 12, 2025 ContributorAuthor More actions @picnixz to address this issue, I suggest using the %OB format specifier, which returns month names in the nominative case. This specifier is part of the C2x standard and is already supported by most major platforms. Specifically, it has been available in glibc since version 2.27, macOS since 15.3, and Windows as well (tested on Windows 11).
For platforms that do not support %OB, we can continue using %B as a fallback. This way, the module will work correctly on all platforms, but will provide better results on platforms that support %OB. As calendar.month_name is used in other places in the standard library, I suggest adding a new lists alt_month_name and alt_month_abbr to not interfere with the existing behavior. picnixz commented on Mar 12, 2025 Ideally, I would want to avoid having a discrepency between platforms (for instance, parsing could be affected) =/ CPython only requires C11 so we can't really assume C2x. However, if this is implemented by major compilers and platforms, maybe we can make an exception? Otherwise, we'll need to wait until C2x is supported officially.
cc @hugovk as the RM picnixz commented on Mar 12, 2025 Also, while it is a bug per se, I think we should treat it as a feature instead so to avoid breaking stable Python releases (namely make it only Python 3.14+) plashchynski commented on Mar 12, 2025 ContributorAuthor More actions @picnixz thank you for your comments. Just wanted to add that this only affects calendars displayed by TextCalendar and HTMLCalendar when the affected locale is specified, so side effects are minimal.
Also, for locales, discrepancies across platforms are somewhat inevitable. One locale might have alternative ways of writing. A language might have multiple names for a month. For instance, in Belarusian, "May" has two alternative names "май" and "травень". So, it is generally not safe to assume that month names will be strictly consistent across platforms. picnixz commented on Mar 12, 2025
So, it is generally not safe to assume that month names will be strictly consistent across platforms.
Oh, I see. So I don't need to bother about the discrepency as we already have possible ones. kulikjak commented on Aug 4, 2025 Hi! Atfer this change, test_months and test_standalone_month_name_and_abbr_C_locale started failing on Solaris. The reason is that the %0b specifier doesn't exist there and the standalone_month_abbr array becomes just a bunch of '%Ob's because of that.
I see that you added except ValueError: likely to catch issues like this, but I don't think that strftime ever raises a ValueError in that case? (I wasn't able to force it on MacOS with nonexistent specifiers.)
Full failure:
======================================================================
FAIL: test_months (test.test_calendar.CalendarTestCase.test_months)
----------------------------------------------------------------------
Traceback (most recent call last):
File "..../build/components/python/pythonmain/cpython-main/Lib/test/test_calendar.py", line 557, in test_months
self.assertEqual(len(set(value)), 13)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: 2 != 13
======================================================================
FAIL: test_standalone_month_name_and_abbr_C_locale (test.test_calendar.CalendarTestCase.test_standalone_month_name_and_abbr_C_locale)
----------------------------------------------------------------------
Traceback (most recent call last):
File "..../build/components/python/pythonmain/cpython-main/Lib/test/test_calendar.py", line 590, in test_standalone_month_name_and_abbr_C_locale
self.assertListEqual(list(calendar.month_abbr),
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^
list(calendar.standalone_month_abbr))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Lists differ: ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', [36 chars]Dec'] != ['', '%Ob', '%Ob', '%Ob', '%Ob', '%Ob', '%Ob', [36 chars]%Ob']
First differing element 1:
'Jan'
'%Ob'
['',
- 'Jan',
- 'Feb',
- 'Mar',
- 'Apr',
- 'May',
- 'Jun',
- 'Jul',
- 'Aug',
- 'Sep',
- 'Oct',
- 'Nov',
- 'Dec']
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob',
+ '%Ob']
added 2 commits that reference this issue on Aug 12, 2025gh-131146: Fall back to `month_name` if `standalone_month_name`s aren…
MetadataMetadataStatusShow more project fields StatusShow more project fields
DevelopmentNo branches or pull requestsIssue actions
|