gh-69998: Fix decoding error in locale.nl_langinfo() (GH-124963) · python/cpython@93b9e6b · GitHub
Skip to content

Commit 93b9e6b

Browse files
gh-69998: Fix decoding error in locale.nl_langinfo() (GH-124963)
The function now sets temporarily the LC_CTYPE locale to the locale of the category that determines the requested value if the locales are different and the resulting string is non-ASCII. This temporary change affects other threads.
1 parent 2739099 commit 93b9e6b

5 files changed

Lines changed: 153 additions & 70 deletions

File tree

Doc/library/locale.rst

Lines changed: 9 additions & 0 deletions

Doc/whatsnew/3.14.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,12 @@ Changes in the Python API
587587
Wrap it in :func:`staticmethod` if you want to preserve the old behavior.
588588
(Contributed by Serhiy Storchaka and Dominykas Grigonis in :gh:`121027`.)
589589

590+
* The :func:`locale.nl_langinfo` function now sets temporarily the ``LC_CTYPE``
591+
locale in some cases.
592+
This temporary change affects other threads.
593+
(Contributed by Serhiy Storchaka in :gh:`69998`.)
594+
595+
590596
Build Changes
591597
=============
592598

Lib/test/test__locale.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,16 +115,17 @@ def numeric_tester(self, calc_type, calc_value, data_type, used_locale):
115115
def test_lc_numeric_nl_langinfo(self):
116116
# Test nl_langinfo against known values
117117
tested = False
118+
oldloc = setlocale(LC_CTYPE)
118119
for loc in candidate_locales:
119120
try:
120121
setlocale(LC_NUMERIC, loc)
121-
setlocale(LC_CTYPE, loc)
122122
except Error:
123123
continue
124124
for li, lc in ((RADIXCHAR, "decimal_point"),
125125
(THOUSEP, "thousands_sep")):
126126
if self.numeric_tester('nl_langinfo', nl_langinfo(li), lc, loc):
127127
tested = True
128+
self.assertEqual(setlocale(LC_CTYPE), oldloc)
128129
if not tested:
129130
self.skipTest('no suitable locales')
130131

@@ -135,28 +136,29 @@ def test_lc_numeric_nl_langinfo(self):
135136
def test_lc_numeric_localeconv(self):
136137
# Test localeconv against known values
137138
tested = False
139+
oldloc = setlocale(LC_CTYPE)
138140
for loc in candidate_locales:
139141
try:
140142
setlocale(LC_NUMERIC, loc)
141-
setlocale(LC_CTYPE, loc)
142143
except Error:
143144
continue
144145
formatting = localeconv()
145146
for lc in ("decimal_point",
146147
"thousands_sep"):
147148
if self.numeric_tester('localeconv', formatting[lc], lc, loc):
148149
tested = True
150+
self.assertEqual(setlocale(LC_CTYPE), oldloc)
149151
if not tested:
150152
self.skipTest('no suitable locales')
151153

152154
@unittest.skipUnless(nl_langinfo, "nl_langinfo is not available")
153155
def test_lc_numeric_basic(self):
154156
# Test nl_langinfo against localeconv
155157
tested = False
158+
oldloc = setlocale(LC_CTYPE)
156159
for loc in candidate_locales:
157160
try:
158161
setlocale(LC_NUMERIC, loc)
159-
setlocale(LC_CTYPE, loc)
160162
except Error:
161163
continue
162164
for li, lc in ((RADIXCHAR, "decimal_point"),
@@ -173,17 +175,18 @@ def test_lc_numeric_basic(self):
173175
nl_radixchar, li_radixchar,
174176
loc, set_locale))
175177
tested = True
178+
self.assertEqual(setlocale(LC_CTYPE), oldloc)
176179
if not tested:
177180
self.skipTest('no suitable locales')
178181

179182
def test_float_parsing(self):
180183
# Bug #1391872: Test whether float parsing is okay on European
181184
# locales.
182185
tested = False
186+
oldloc = setlocale(LC_CTYPE)
183187
for loc in candidate_locales:
184188
try:
185189
setlocale(LC_NUMERIC, loc)
186-
setlocale(LC_CTYPE, loc)
187190
except Error:
188191
continue
189192

@@ -199,6 +202,7 @@ def test_float_parsing(self):
199202
self.assertRaises(ValueError, float,
200203
localeconv()['decimal_point'].join(['1', '23']))
201204
tested = True
205+
self.assertEqual(setlocale(LC_CTYPE), oldloc)
202206
if not tested:
203207
self.skipTest('no suitable locales')
204208

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :func:`locale.nl_langinfo` in case when different categories have
2+
different locales. The function now sets temporarily the ``LC_CTYPE`` locale
3+
in some cases. This temporary change affects other threads.

Modules/_localemodule.c

Lines changed: 127 additions & 66 deletions

0 commit comments

Comments
 (0)