-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
bpo-46659: Enhance LocaleTextCalendar for C locale #31214
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Lib/calendar.py
Outdated
self.oldlocale = _locale.setlocale(_locale.LC_TIME, None) | ||
if self.locale is not None: | ||
_locale.setlocale(_locale.LC_TIME, self.locale) | ||
else: | ||
if self.oldlocale in ("C", "POSIX"): | ||
# The locale does not seem to be configured: | ||
# get the user preferred locale. | ||
_locale.setlocale(_locale.LC_TIME, "") | ||
else: | ||
# Otherwise simply use the current LC_TIME locale. | ||
# The locale is not changed, __exit__() does nothing. | ||
self.oldlocale = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this is that it can change based on environment variables:
>>> locale.setlocale(locale.LC_TIME, '')
'ru_RU.utf8'
>>> os.environ['LC_ALL'] = 'en_US.utf8'
>>> locale.setlocale(locale.LC_TIME, '')
'en_US.utf8'
But the instance is supposed to capture the preferred locale when it's created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it so important for you to get the locale when Python is started? As you shown, there are many ways to change locales. And using an locale set before all the changes is irrelevant, so it's now outdated, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The previous code based on getdefaultlocale()
was a one time check of LC_ALL
, LC_CTYPE
, and LANG
. This was technically wrong, but in practice the default LC_TIME
is usually the same as the default LC_CTYPE
.
I think it's correct to use the current LC_TIME
locale, if it was configured already. Not doing so was a bug. However, it should try to remain close to the previous default behavior when instantiating LocaleTextCalendar()
when LC_TIME
is the initial "C" value, which is usually the case if a script doesn't explicitly set LC_ALL
or LC_TIME
.
But changing it to re-evaluate the default via setlocale(LC_TIME, "")
for every formatweekday()
call is going too far. That depends on the current values of the environment variables LC_ALL
, LC_TIME
, and LANG
, which is very different from the one-time getdefaultlocale()
call in the previous code.
Lib/calendar.py
Outdated
if locale is None: | ||
locale = _locale.getlocale(_locale.LC_TIME) | ||
self.locale = locale |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion:
if locale is None:
locale = _locale.getlocale(_locale.LC_TIME)
if locale == (None, None):
with different_locale(""):
locale = _locale.getlocale(_locale.LC_TIME)
self.locale = locale
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to not change the locale in the constructor. That's why I proposed this specific PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is not okay to temporarily modify LC_TIME
in __init__()
, but fine to do so in formatweekday()
and formatmonthname()
? The class is documented as not thread safe with respect to the process locale.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is ok to call setlocale() in __init__()
. But setlocale() affects all threads, so I prefer to avoid calling it if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that change is the less of the two. I don't think it's worth changing the behavior from the previous code that looked up the default locale to use via getdefaultlocale()
only once, instead of calling it on every entry of different_locale
. But that's just me voicing one opinion. I'd prefer for other people to way in on exactly which default behaviors are important to preserve, or whether the entire default behavior of locale=None
should change to use the LC_TIME
locale even if it's "C".
If the LC_TIME locale is "C", use the user preferred locale.
@eryksun: I modified the implementation to only get the user preferred locale once, in the constructor. Is it better? |
I tested manually the change on FreeBSD: it works, LC_TIME is also FreeBSD has a "POSIX" locale, but it's not used when LC_ALL, LC_CTYPE and LANG environment variable at not set: LC_CTYPE is "C" in this case. |
I merged my PR. Thanks @eryksun for your feedback and the nice idea of reusing calendar should now be a little bit better in some corner cases, but for the regular use case, there should be no change between Python 3.10 and 3.11. |
If the LC_TIME locale is "C", use the user preferred locale.
If the LC_TIME locale is "C", use the user preferred locale.
https://bugs.python.org/issue46659