Skip to content

Commit c780f95

Browse files
committed
TST: Patch locale handling
Backported from pandas-devgh-21739. Backport of pandas-devgh-22213.
1 parent 530a21f commit c780f95

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

pandas/tests/util/test_util.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,26 @@ def teardown_class(cls):
433433
del cls.locales
434434
del cls.current_locale
435435

436+
def test_can_set_locale_valid_set(self):
437+
# Setting the default locale should return True
438+
assert tm.can_set_locale('') is True
439+
440+
def test_can_set_locale_invalid_set(self):
441+
# Setting an invalid locale should return False
442+
assert tm.can_set_locale('non-existent_locale') is False
443+
444+
def test_can_set_locale_invalid_get(self, monkeypatch):
445+
# In some cases, an invalid locale can be set,
446+
# but a subsequent getlocale() raises a ValueError
447+
# See GH 22129
448+
449+
def mockgetlocale():
450+
raise ValueError()
451+
452+
with monkeypatch.context() as m:
453+
m.setattr(locale, 'getlocale', mockgetlocale)
454+
assert tm.can_set_locale('') is False
455+
436456
def test_get_locales(self):
437457
# all systems should have at least a single locale
438458
assert len(tm.get_locales()) > 0
@@ -466,7 +486,7 @@ def test_set_locale(self):
466486
enc = codecs.lookup(enc).name
467487
new_locale = lang, enc
468488

469-
if not tm._can_set_locale(new_locale):
489+
if not tm.can_set_locale(new_locale):
470490
with pytest.raises(locale.Error):
471491
with tm.set_locale(new_locale):
472492
pass

pandas/util/testing.py

+17-15
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,8 @@ def set_locale(new_locale, lc_var=locale.LC_ALL):
478478
A string of the form <language_country>.<encoding>. For example to set
479479
the current locale to US English with a UTF8 encoding, you would pass
480480
"en_US.UTF-8".
481+
lc_var : int, default `locale.LC_ALL`
482+
The category of the locale being set.
481483
482484
Notes
483485
-----
@@ -489,37 +491,37 @@ def set_locale(new_locale, lc_var=locale.LC_ALL):
489491

490492
try:
491493
locale.setlocale(lc_var, new_locale)
492-
493-
try:
494-
normalized_locale = locale.getlocale()
495-
except ValueError:
496-
yield new_locale
494+
normalized_locale = locale.getlocale()
495+
if com._all_not_none(*normalized_locale):
496+
yield '.'.join(normalized_locale)
497497
else:
498-
if com._all_not_none(*normalized_locale):
499-
yield '.'.join(normalized_locale)
500-
else:
501-
yield new_locale
498+
yield new_locale
502499
finally:
503500
locale.setlocale(lc_var, current_locale)
504501

505502

506-
def _can_set_locale(lc):
507-
"""Check to see if we can set a locale without throwing an exception.
503+
def can_set_locale(lc, lc_var=locale.LC_ALL):
504+
"""
505+
Check to see if we can set a locale, and subsequently get the locale,
506+
without raising an Exception.
508507
509508
Parameters
510509
----------
511510
lc : str
512511
The locale to attempt to set.
512+
lc_var : int, default `locale.LC_ALL`
513+
The category of the locale being set.
513514
514515
Returns
515516
-------
516-
isvalid : bool
517+
is_valid : bool
517518
Whether the passed locale can be set
518519
"""
519520
try:
520-
with set_locale(lc):
521+
with set_locale(lc, lc_var=lc_var):
521522
pass
522-
except locale.Error: # horrible name for a Exception subclass
523+
except (ValueError,
524+
locale.Error): # horrible name for a Exception subclass
523525
return False
524526
else:
525527
return True
@@ -546,7 +548,7 @@ def _valid_locales(locales, normalize):
546548
else:
547549
normalizer = lambda x: x.strip()
548550

549-
return list(filter(_can_set_locale, map(normalizer, locales)))
551+
return list(filter(can_set_locale, map(normalizer, locales)))
550552

551553
# -----------------------------------------------------------------------------
552554
# Stdout / stderr decorators

0 commit comments

Comments
 (0)