Skip to content

Deprecation of locale.getdefaultlocale breaks POSIX compatibility on Windows platform #130796

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

Open
Wedge009 opened this issue Mar 3, 2025 · 6 comments
Labels
pending The issue will be closed if no feedback is provided stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@Wedge009
Copy link

Wedge009 commented Mar 3, 2025

Bug report

Bug description:

Follow-up to #90817.

In summary, without getdetfaultlocale, tools that rely on POSIX locales cannot reliably get the same information from getlocale or setlocale on Windows.

For example, Linux will return something like 'en_AU'. But on Windows, getlocale will return something like 'English_Australia'.

CPython versions tested on:

3.12, 3.13

Operating systems tested on:

Windows, Linux

@Wedge009 Wedge009 added the type-bug An unexpected behavior, bug, or error label Mar 3, 2025
@picnixz picnixz added the stdlib Python modules in the Lib dir label Mar 3, 2025
@picnixz picnixz added type-feature A feature request or enhancement and removed type-bug An unexpected behavior, bug, or error labels Mar 3, 2025
@picnixz
Copy link
Member

picnixz commented Mar 3, 2025

I'm afraid that this issue is too late because the ship has already sailed. I don't remember well which alternatives there are for that kind of issue so I'll tag @vstinner who was responsible for the original patch. However, I doubt that we would reinstate locale.getdefaultlocale (or we would do something else).

EDIT: Actually it seems to only be deprecated and planned for removal in 3.15: #111187.

@picnixz picnixz added the pending The issue will be closed if no feedback is provided label Mar 3, 2025
@Wedge009
Copy link
Author

Wedge009 commented Mar 3, 2025

I don't think I - or others - was asking for a reinstatement, just a viable alternative for the cases where POSIX locales are expected for use with other tools such as gettext.

And yes, removal is planned for 3.15, hence the discussion now. As noted in wesnoth/wesnoth#9972 (comment), it's difficult to know how to work around the removal of getdefaultlocale when we don't know what future plans are - if any - for any replacement functionality.

@vstinner
Copy link
Member

vstinner commented Mar 3, 2025

On my Windows 11 VM, getlocale() returns a "POSIX" locale as expected:

vstinner@WIN C:\victor\python\main>python
Python 3.14.0a5+ (heads/pr/130452-dirty:6a5dc1a8ba6, Feb 26 2025, 17:30:51) [MSC v.1943 32 bit (Intel)] on win32
>>> import locale
>>> locale.getlocale()
('fr_FR', 'cp1252')
>>> locale.setlocale(locale.LC_CTYPE, None)
'French_France.1252'

Can you please elaborate your issue? What are the results of locale.getlocale() and locale.setlocale(locale.LC_CTYPE, None)?

@Wedge009
Copy link
Author

Wedge009 commented Mar 3, 2025

It's as I described above and in #90817 (comment).

Python 3.13.2 (tags/v3.13.2:4f8bb39, Feb  4 2025, 15:23:48) [MSC v.1942 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
import locale
locale.getlocale()
('English_Australia', '1252')
locale.setlocale(locale.LC_CTYPE)
'English_Australia.1252'
locale.getdefaultlocale()

Warning (from warnings module):
  File "<pyshell#3>", line 1
DeprecationWarning: 'locale.getdefaultlocale' is deprecated and slated for removal in Python 3.15. Use setlocale(), getencoding() and getlocale() instead.
('en_AU', 'cp1252')

@shineworld reported something similar in #90817 (comment)

@Elvish-Hunter reports the same in wesnoth/wesnoth#9972 (comment)

@2trvl
Copy link
Contributor

2trvl commented Mar 6, 2025

The reason why POSIX compatibility breaks is this:

The windows_locale dictionary is only used by the locale.getdefaultlocale() function and this function is deprecated: it will be removed in Python 3.15.

Windows 22H2, Python 3.13.1:

>>> locale.setlocale(locale.LC_CTYPE)
'English_United States.1252'

>>> locale.getlocale()
('English_United States', '1252')

>>> locale.getdefaultlocale()
('en_US', 'cp1252')

@2trvl
Copy link
Contributor

2trvl commented Mar 7, 2025

I would like to know how can I find out the system locale for LC_TIME without using defaultlocale?

>>> locale.getdefaultlocale(["LC_TIME"])
('ru_RU', 'UTF-8')

>>> locale.setlocale(locale.LC_TIME)
'C'

>>> locale.getlocale(locale.LC_TIME)
(None, None)

Apparently I have no other option than to change the interpreter locale:

>>> locale.setlocale(locale.LC_TIME, "")
'ru_RU.UTF-8'

>>> locale.getlocale(locale.LC_TIME)
('ru_RU', 'UTF-8')

It is generally a bad idea to call setlocale() in some library routine, since as a side effect it affects the entire program. Saving and restoring it is almost as bad: it is expensive and affects other threads that happen to run before the settings have been restored.

I see that the original reason for removal is the use of non-ASCII characters in locale. Do you think this is a common case?

If fixing the problem is difficult or impossible, perhaps it is worth introducing a similar function called getpreferredlocale?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pending The issue will be closed if no feedback is provided stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
Development

No branches or pull requests

4 participants