Mercurial > hg
comparison mercurial/pycompat.py @ 45001:a25343d16ebe
compat: initialize LC_CTYPE locale on all Python versions and platforms
Previously, the LC_CTYPE locale was not initialized according to user settings
on all Python versions (e.g. never on Python 2) and platforms (e.g. not on
some Python < 3.8 on Windows).
This broke e.g. non-ASCII filenames passed to the Subversion bindings on Python
2, resulting in error messages like "file:///tmp/a%C3%A4 does not look like a
Subversion repository to libsvn version 1.14.0".
The following command could be used to test this functionality. Adding it to the
test suite would be pointless, as the locale is always set to "C" during test
runs.
@command(b'check_initial_codeset', norepo=True)
def check_initial_codeset(ui):
codeset1 = locale.nl_langinfo(locale.CODESET)
locale.setlocale(locale.LC_ALL, '')
codeset2 = locale.nl_langinfo(locale.CODESET)
assert codeset1 == codeset2
author | Manuel Jacob <me@manueljacob.de> |
---|---|
date | Fri, 26 Jun 2020 04:07:50 +0200 |
parents | f2de8f31cb59 |
children | f2dc337117b9 |
comparison
equal
deleted
inserted
replaced
45000:3fadbdc47aed | 45001:a25343d16ebe |
---|---|
11 from __future__ import absolute_import | 11 from __future__ import absolute_import |
12 | 12 |
13 import getopt | 13 import getopt |
14 import inspect | 14 import inspect |
15 import json | 15 import json |
16 import locale | |
16 import os | 17 import os |
17 import shlex | 18 import shlex |
18 import sys | 19 import sys |
19 import tempfile | 20 import tempfile |
20 | 21 |
89 """ | 90 """ |
90 if f is identity: | 91 if f is identity: |
91 # fast path mainly for py2 | 92 # fast path mainly for py2 |
92 return xs | 93 return xs |
93 return _rapply(f, xs) | 94 return _rapply(f, xs) |
95 | |
96 | |
97 # Passing the '' locale means that the locale should be set according to the | |
98 # user settings (environment variables). | |
99 # Python sometimes avoids setting the global locale settings. When interfacing | |
100 # with C code (e.g. the curses module or the Subversion bindings), the global | |
101 # locale settings must be initialized correctly. Python 2 does not initialize | |
102 # the global locale settings on interpreter startup. Python 3 sometimes | |
103 # initializes LC_CTYPE, but not consistently at least on Windows. Therefore we | |
104 # explicitly initialize it to get consistent behavior if it's not already | |
105 # initialized. Since CPython commit 177d921c8c03d30daa32994362023f777624b10d, | |
106 # LC_CTYPE is always initialized. If we require Python 3.8+, we should re-check | |
107 # if we can remove this code. | |
108 if locale.setlocale(locale.LC_CTYPE, None) == 'C': | |
109 try: | |
110 locale.setlocale(locale.LC_CTYPE, '') | |
111 except locale.Error: | |
112 # The likely case is that the locale from the environment variables is | |
113 # unknown. | |
114 pass | |
94 | 115 |
95 | 116 |
96 if ispy3: | 117 if ispy3: |
97 import builtins | 118 import builtins |
98 import codecs | 119 import codecs |