Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reset locale back to original after changing it in Python?

Tags:

python

locale

After changing the locale in a Python program, what is the safe way to change it back to its original value?

What I have tried so far is to store the original locale as returned by locale.getlocale before making changes and then using locale.setlocale afterwards to change back to it.

Example program:

import datetime
import locale

now = datetime.datetime.now()

locale.setlocale(locale.LC_ALL, '')
print("Date using your locale      : %s" % now.strftime('%c'))

saved = locale.getlocale(locale.LC_TIME)
locale.setlocale(locale.LC_TIME, 'C')
print("Date using the C locale     : %s" % now.strftime('%c'))

locale.setlocale(locale.LC_TIME, saved)
print("Date using your locale again: %s" % now.strftime('%c'))

However, this does not always work as expected. It seems that the problem arises with locales that have a modifier (the bit after the '@' sign). Trying the following with Python 3.7 on a Debian 10 system illustrates the problem:

$ LC_TIME=sr_RS.utf8@latin python3 example.py
Date using your locale      : četvrtak, 01. avgust 2019. 14:43:43 
Date using the C locale     : Thu Aug  1 14:43:43 2019
Date using your locale again: четвртак, 01. август 2019. 14:43:43

So it appears to change back to the sr_RS.utf8 locale instead of the original sr_RS.utf8@latin locale, forgetting about the @latin modifier.

Furthermore, if the corresponding locale without the modifier is not available, there will be an error when trying to switch back. For example on a system where the nan_TW.utf8@latin locale is present, but nan_TW.utf8 is not:

$ LC_TIME=nan_TW.utf8@latin python3 example.py
Date using your locale      : 2019 8g 01 (p4) 14:44:29 
Date using the C locale     : Thu Aug  1 14:44:29 2019
Traceback (most recent call last):
  File "example.py", line 13, in <module>
    locale.setlocale(locale.LC_TIME, saved)
  File "/usr/local/lib/python3.7/locale.py", line 604, in setlocale
    return _setlocale(category, locale)
locale.Error: unsupported locale setting

Is there a safe way to switch back to the original locale setting? Something that could be used for example in a library routine intended to be used within a larger locale-aware program to temporarily switch the locale (for example, for formatting dates in another locale) and then switching it back, without permanently interfering with the locale of the calling program.

like image 656
Jukka Matilainen Avatar asked Aug 01 '19 15:08

Jukka Matilainen


People also ask

What is locale dependent in Python?

In the manual is written: For 8-bit strings, this method is locale-dependent. How is this method locale-depedent? In what locales are there digits that are outside the 0-9 range? Also, if this is locale dependent, does python have a method for checking it with a specific locale (i.e. only 0-9 digits).


1 Answers

Is there a safe way to switch back to the original locale setting? (if it uses modifiers as e.g. latin)

No, not with standard function calls: locale.getlocale() ignores all modifiers except euro, see source.

A workaround is to use the internal function _setlocale, i.e. reverse engineer getlocale without the _parse_localename part:

import datetime
import locale

now = datetime.datetime.now()

locale.setlocale(locale.LC_ALL, '')
print("Date using your locale      : %s" % now.strftime('%c'))

saved = locale._setlocale(locale.LC_TIME)

locale.setlocale(locale.LC_TIME, 'C')
print("Date using the C locale     : %s" % now.strftime('%c'))

locale.setlocale(locale.LC_TIME, saved)
print("Date using your locale again: %s" % now.strftime('%c'))

Example:

$ LC_TIME=sr_RS.utf8@latin python3 so57312038.py
Date using your locale      : sreda, 21. avgust 2019. 00:00:29 
Date using the C locale     : Wed Aug 21 00:00:29 2019
Date using your locale again: sreda, 21. avgust 2019. 00:00:29 
like image 198
Stef Avatar answered Oct 22 '22 07:10

Stef