Reputation: 5027
Getting the locale with python on Windows seems to be broken:
(trash0) PS C:\Users\myname\venv\trash0\Lib\site-packages> python.exe
Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 17:26:49) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.platform
'win32'
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'fr-FR')
'fr-FR'
>>> locale.getlocale()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files\Python36-32\lib\locale.py", line 581, in getlocale
return _parse_localename(localename)
File "C:\Program Files\Python36-32\lib\locale.py", line 490, in _parse_localename
raise ValueError('unknown locale: %s' % localename)
ValueError: unknown locale: fr-FR
>>>
I do not know much about Windows but I have checked fr-FR
belongs to the correct locale names for Windows. Note that using en-US
or en-GB
get the same result.
Yet setting the locale works correctly because:
locale.setlocale()
with any unknown value would raise an exception: >>> locale.setlocale(locale.LC_ALL, 'anythingundefined')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files\Python36-32\lib\locale.py", line 598, in setlocale
return _setlocale(category, locale)
locale.Error: unsupported locale setting
>>>
>>> locale.setlocale(locale.LC_ALL, 'fr-FR')
'fr-FR'
>>> locale.str(12.3)
'12,3'
>>> locale.setlocale(locale.LC_ALL, 'en-GB')
'en-GB'
>>> locale.str(12.3)
'12.3'
>>>
I need to temporarily set the locale to en-US
(in order to perform some things that require this locale) and then switch back to the default locale. How is it possible to do it if locale.getlocale()
is broken? I've read the python doc about locale but can't figure out any workaround to achieve this (nor whether it is possible at all).
Upvotes: 2
Views: 2461
Reputation: 123531
Here's how to monkey patch the locale
module as I was trying to describe in my comments under your question.
First the monkey-patching module, locale_patch.py
:
""" Module that monkey-patches the locale module so it remembers the last
arguments to setlocale() that didn't raise an exception and will allow them to
be retrieved later by calling a new function named setting_values() which also
gets added.
"""
import locale as _locale
_last_category, _last_locale = None, None
def my_setlocale(category, locale=None):
global _last_category, _last_locale
try:
result = _orig_setlocale(category, locale)
except _locale.Error:
raise # Didn't work, ignore arguments.
if locale is not None: # Was a setting modified by call?
_last_category, _last_locale = category, locale # Remember args.
return result
def setting_values():
global _last_category, _last_locale
if _last_category is None:
raise _locale.Error('setlocale() has never been called to change settings')
return _last_category, _last_locale
# Monkey-patch the module.
_orig_setlocale = _locale.setlocale
_locale.setlocale = my_setlocale
_locale.setting_values = setting_values # New module function.
Sample usage:
import locale
import locale_patch # Apply monkey-patch(es).
try:
locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8') # locale.Error: unsupported locale setting
except locale.Error:
print("locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8') didn't work")
try:
print(locale.setting_values())
except locale.Error:
print("locale.setting_values() didn't work") # Expected.
try:
locale.setlocale(locale.LC_ALL, locale='fr_FR.UTF-8')
except locale.Error:
print("locale.setlocale(locale.LC_ALL, locale='fr_FR.UTF-8') didn't work")
try:
print(locale.setting_values())
except locale.Error:
print("locale.setting_values() didn't work") # Expected.
locale.setlocale(locale.LC_ALL, 'fr-FR')
results = locale.setting_values()
print(results) # -> (0, 'fr-FR') # The 0 is the numeric value of locale.LC_ALL
locale.setlocale(*results) # Works OK.
Upvotes: 2