Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdcc4fb2

Browse files
gh-124969: Make locale.nl_langinfo(locale.ALT_DIGITS) returning a string again (GH-125774)
This is a follow up ofGH-124974. Only Glibc needed a fix.Now the returned value is a string consisting of semicolon-separatedsymbols on all Posix platforms.
1 parent5ca4e34 commitdcc4fb2

File tree

4 files changed

+50
-27
lines changed

4 files changed

+50
-27
lines changed

‎Doc/library/locale.rst‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,7 @@ The :mod:`locale` module defines the following exception and functions:
158158

159159
..function::nl_langinfo(option)
160160

161-
Return some locale-specific information as a string (or a tuple for
162-
``ALT_DIGITS``). This function is not
161+
Return some locale-specific information as a string. This function is not
163162
available on all systems, and the set of possible options might also vary
164163
across platforms. The possible argument values are numbers, for which
165164
symbolic constants are available in the locale module.
@@ -312,7 +311,9 @@ The :mod:`locale` module defines the following exception and functions:
312311

313312
..data::ALT_DIGITS
314313

315-
Get a tuple of up to 100 strings used to represent the values 0 to 99.
314+
Get a string consisting of up to 100 semicolon-separated symbols used
315+
to represent the values 0 to 99 in a locale-specific way.
316+
In most locales this is an empty string.
316317

317318
The function temporarily sets the ``LC_CTYPE`` locale to the locale
318319
of the category that determines the requested value (``LC_TIME``,

‎Lib/test/test__locale.py‎

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@
2626
'bs_BA','fr_LU','kl_GL','fa_IR','de_BE','sv_SE','it_CH','uk_UA',
2727
'eu_ES','vi_VN','af_ZA','nb_NO','en_DK','tg_TJ','ps_AF','en_US',
2828
'fr_FR.ISO8859-1','fr_FR.UTF-8','fr_FR.ISO8859-15@euro',
29-
'ru_RU.KOI8-R','ko_KR.eucKR']
29+
'ru_RU.KOI8-R','ko_KR.eucKR',
30+
'ja_JP.UTF-8','lzh_TW.UTF-8','my_MM.UTF-8','or_IN.UTF-8','shn_MM.UTF-8',
31+
'ar_AE.UTF-8','bn_IN.UTF-8','mr_IN.UTF-8','th_TH.TIS620',
32+
]
3033

3134
defsetUpModule():
3235
globalcandidate_locales
@@ -78,11 +81,13 @@ def accept(loc):
7881
'C': (0, {}),
7982
'en_US': (0, {}),
8083
'fa_IR': (100, {0:'\u06f0\u06f0',10:'\u06f1\u06f0',99:'\u06f9\u06f9'}),
81-
'ja_JP': (100, {0:'\u3007',10:'\u5341',99:'\u4e5d\u5341\u4e5d'}),
84+
'ja_JP': (100, {1:'\u4e00',10:'\u5341',99:'\u4e5d\u5341\u4e5d'}),
8285
'lzh_TW': (32, {0:'\u3007',10:'\u5341',31:'\u5345\u4e00'}),
8386
'my_MM': (100, {0:'\u1040\u1040',10:'\u1041\u1040',99:'\u1049\u1049'}),
8487
'or_IN': (100, {0:'\u0b66',10:'\u0b67\u0b66',99:'\u0b6f\u0b6f'}),
8588
'shn_MM': (100, {0:'\u1090\u1090',10:'\u1091\u1090',99:'\u1099\u1099'}),
89+
'ar_AE': (100, {0:'\u0660',10:'\u0661\u0660',99:'\u0669\u0669'}),
90+
'bn_IN': (100, {0:'\u09e6',10:'\u09e7\u09e6',99:'\u09ef\u09ef'}),
8691
}
8792

8893
ifsys.platform=='win32':
@@ -199,21 +204,28 @@ def test_lc_numeric_basic(self):
199204
deftest_alt_digits_nl_langinfo(self):
200205
# Test nl_langinfo(ALT_DIGITS)
201206
tested=False
202-
forloc, (count,samples)inknown_alt_digits.items():
207+
forlocincandidate_locales:
203208
withself.subTest(locale=loc):
204209
try:
205210
setlocale(LC_TIME,loc)
206211
exceptError:
207212
self.skipTest(f'no locale{loc!r}')
208213
continue
214+
209215
withself.subTest(locale=loc):
210216
alt_digits=nl_langinfo(locale.ALT_DIGITS)
211-
self.assertIsInstance(alt_digits,tuple)
212-
ifcountandnotalt_digitsandsupport.is_apple:
213-
self.skipTest(f'ALT_DIGITS is not set for locale{loc!r} on Apple platforms')
214-
self.assertEqual(len(alt_digits),count)
215-
foriinsamples:
216-
self.assertEqual(alt_digits[i],samples[i])
217+
self.assertIsInstance(alt_digits,str)
218+
alt_digits=alt_digits.split(';')ifalt_digitselse []
219+
ifalt_digits:
220+
self.assertGreaterEqual(len(alt_digits),10,alt_digits)
221+
loc1=loc.split('.',1)[0]
222+
ifloc1inknown_alt_digits:
223+
count,samples=known_alt_digits[loc1]
224+
ifcountandnotalt_digits:
225+
self.skipTest(f'ALT_DIGITS is not set for locale{loc!r} on this platform')
226+
self.assertEqual(len(alt_digits),count,alt_digits)
227+
foriinsamples:
228+
self.assertEqual(alt_digits[i],samples[i])
217229
tested=True
218230
ifnottested:
219231
self.skipTest('no suitable locales')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
``locale.nl_langinfo(locale.ALT_DIGITS)`` now returns a string again. The
2+
returned value consists of up to 100 semicolon-separated symbols.

‎Modules/_localemodule.c‎

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -667,28 +667,36 @@ _locale_nl_langinfo_impl(PyObject *module, int item)
667667
returnNULL;
668668
}
669669
PyObject*pyresult;
670+
#ifdef__GLIBC__
670671
#ifdefALT_DIGITS
671-
if (item==ALT_DIGITS) {
672-
/* The result is a sequence of up to 100 NUL-separated strings. */
673-
constchar*s=result;
672+
if (item==ALT_DIGITS&&*result) {
673+
/* According to the POSIX specification the result must be
674+
* a sequence of up to 100 semicolon-separated strings.
675+
* But in Glibc they are NUL-separated. */
676+
Py_ssize_ti=0;
674677
intcount=0;
675-
for (;count<100&&*s;count++) {
676-
s+=strlen(s)+1;
678+
for (;count<100&&result[i];count++) {
679+
i+=strlen(result+i)+1;
677680
}
678-
pyresult=PyTuple_New(count);
679-
if (pyresult!=NULL) {
680-
for (inti=0;i<count;i++) {
681-
PyObject*unicode=PyUnicode_DecodeLocale(result,NULL);
682-
if (unicode==NULL) {
683-
Py_CLEAR(pyresult);
684-
break;
685-
}
686-
PyTuple_SET_ITEM(pyresult,i,unicode);
687-
result+=strlen(result)+1;
681+
char*buf=PyMem_Malloc(i);
682+
if (buf==NULL) {
683+
PyErr_NoMemory();
684+
pyresult=NULL;
685+
}
686+
else {
687+
memcpy(buf,result,i);
688+
/* Replace all NULs with semicolons. */
689+
i=0;
690+
while (--count) {
691+
i+=strlen(buf+i);
692+
buf[i++]=';';
688693
}
694+
pyresult=PyUnicode_DecodeLocale(buf,NULL);
695+
PyMem_Free(buf);
689696
}
690697
}
691698
else
699+
#endif
692700
#endif
693701
{
694702
pyresult=PyUnicode_DecodeLocale(result,NULL);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp