1313import locale
1414import gettext
1515import globalVars
16+ from logging import log
1617
1718#a few Windows locale constants
1819LOCALE_SLANGUAGE = 0x2
@@ -156,19 +157,6 @@ def setLanguage(lang):
156157 else :
157158 trans = gettext .translation ("nvda" , localedir = "locale" , languages = [lang ])
158159 curLang = lang
159- localeChanged = False
160- #Try setting Python's locale to lang
161- try :
162- locale .setlocale (locale .LC_ALL ,lang )
163- localeChanged = True
164- except :
165- pass
166- if not localeChanged and '_' in lang :
167- #Python couldn'tsupport the language_country locale, just try language.
168- try :
169- locale .setlocale (locale .LC_ALL ,lang .split ('_' )[0 ])
170- except :
171- pass
172160 #Set the windows locale for this thread (NVDA core) to this locale.
173161 LCID = localeNameToWindowsLCID (lang )
174162 ctypes .windll .kernel32 .SetThreadLocale (LCID )
@@ -177,6 +165,63 @@ def setLanguage(lang):
177165 curLang = "en"
178166 # #9207: Python 3.8 adds gettext.pgettext, so add it to the built-in namespace.
179167 trans .install (names = ["pgettext" ])
168+ setLocale (curLang )
169+
170+
171+ def setLocale (localeName ):
172+ '''
173+ Set python's locale using a `localeName` set by `setLanguage`.
174+ Python 3.8's locale system allows you to set locales that you cannot get
175+ so we must test for both ValueErrors and locale.Errors
176+ '''
177+
178+ r'''
179+ >>> import locale
180+ >>> locale.setlocale(locale.LC_ALL, 'foobar')
181+ Traceback (most recent call last):
182+ File "<stdin>", line 1, in <module>
183+ File "Python38-32\lib\locale.py", line 608, in setlocale
184+ return _setlocale(category, locale)
185+ locale.Error: unsupported locale setting
186+ >>> locale.setlocale(locale.LC_ALL, 'en-GB')
187+ 'en-GB'
188+ >>> locale.getlocale()
189+ Traceback (most recent call last):
190+ File "<stdin>", line 1, in <module>
191+ File "Python38-32\lib\locale.py", line 591, in getlocale
192+ return _parse_localename(localename)
193+ File "Python38-32\lib\locale.py", line 499, in _parse_localename
194+ raise ValueError('unknown locale: %s' % localename)
195+ ValueError: unknown locale: en-GB
196+ '''
197+ # Try setting Python's locale to lang
198+ localeChanged = False
199+ try :
200+ locale .setlocale (locale .LC_ALL , localeName )
201+ locale .getlocale ()
202+ localeChanged = True
203+ except (locale .Error , ValueError ):
204+ pass
205+ if not localeChanged and '-' in localeName :
206+ # Python couldn't support the language-country locale, try language_country.
207+ try :
208+ localeName = localeName .replace ('-' , '_' )
209+ locale .setlocale (locale .LC_ALL , localeName )
210+ locale .getlocale ()
211+ localeChanged = True
212+ except (locale .Error , ValueError ):
213+ pass
214+ if not localeChanged and '_' in localeName :
215+ # Python couldn't support the language_country locale, just try language.
216+ try :
217+ localeName = localeName .split ('_' )[0 ]
218+ locale .setlocale (locale .LC_ALL , localeName )
219+ locale .getlocale ()
220+ localeChanged = True
221+ except (locale .Error , ValueError ):
222+ pass
223+ if not localeChanged :
224+ log .warning ("python locale could not be set" )
180225
181226
182227def getLanguage () -> str :
0 commit comments