File size: 4,479 Bytes
7885a28 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
import codecs
import locale
import os
import pytest
from pandas._config.localization import (
can_set_locale,
get_locales,
set_locale,
)
from pandas.compat import ISMUSL
import pandas as pd
_all_locales = get_locales()
_current_locale = locale.setlocale(locale.LC_ALL) # getlocale() is wrong, see GH#46595
# Don't run any of these tests if we have no locales.
pytestmark = pytest.mark.skipif(not _all_locales, reason="Need locales")
_skip_if_only_one_locale = pytest.mark.skipif(
len(_all_locales) <= 1, reason="Need multiple locales for meaningful test"
)
def _get_current_locale(lc_var: int = locale.LC_ALL) -> str:
# getlocale is not always compliant with setlocale, use setlocale. GH#46595
return locale.setlocale(lc_var)
@pytest.mark.parametrize("lc_var", (locale.LC_ALL, locale.LC_CTYPE, locale.LC_TIME))
def test_can_set_current_locale(lc_var):
# Can set the current locale
before_locale = _get_current_locale(lc_var)
assert can_set_locale(before_locale, lc_var=lc_var)
after_locale = _get_current_locale(lc_var)
assert before_locale == after_locale
@pytest.mark.parametrize("lc_var", (locale.LC_ALL, locale.LC_CTYPE, locale.LC_TIME))
def test_can_set_locale_valid_set(lc_var):
# Can set the default locale.
before_locale = _get_current_locale(lc_var)
assert can_set_locale("", lc_var=lc_var)
after_locale = _get_current_locale(lc_var)
assert before_locale == after_locale
@pytest.mark.parametrize(
"lc_var",
(
locale.LC_ALL,
locale.LC_CTYPE,
pytest.param(
locale.LC_TIME,
marks=pytest.mark.skipif(
ISMUSL, reason="MUSL allows setting invalid LC_TIME."
),
),
),
)
def test_can_set_locale_invalid_set(lc_var):
# Cannot set an invalid locale.
before_locale = _get_current_locale(lc_var)
assert not can_set_locale("non-existent_locale", lc_var=lc_var)
after_locale = _get_current_locale(lc_var)
assert before_locale == after_locale
@pytest.mark.parametrize(
"lang,enc",
[
("it_CH", "UTF-8"),
("en_US", "ascii"),
("zh_CN", "GB2312"),
("it_IT", "ISO-8859-1"),
],
)
@pytest.mark.parametrize("lc_var", (locale.LC_ALL, locale.LC_CTYPE, locale.LC_TIME))
def test_can_set_locale_no_leak(lang, enc, lc_var):
# Test that can_set_locale does not leak even when returning False. See GH#46595
before_locale = _get_current_locale(lc_var)
can_set_locale((lang, enc), locale.LC_ALL)
after_locale = _get_current_locale(lc_var)
assert before_locale == after_locale
def test_can_set_locale_invalid_get(monkeypatch):
# see GH#22129
# In some cases, an invalid locale can be set,
# but a subsequent getlocale() raises a ValueError.
def mock_get_locale():
raise ValueError()
with monkeypatch.context() as m:
m.setattr(locale, "getlocale", mock_get_locale)
assert not can_set_locale("")
def test_get_locales_at_least_one():
# see GH#9744
assert len(_all_locales) > 0
@_skip_if_only_one_locale
def test_get_locales_prefix():
first_locale = _all_locales[0]
assert len(get_locales(prefix=first_locale[:2])) > 0
@_skip_if_only_one_locale
@pytest.mark.parametrize(
"lang,enc",
[
("it_CH", "UTF-8"),
("en_US", "ascii"),
("zh_CN", "GB2312"),
("it_IT", "ISO-8859-1"),
],
)
def test_set_locale(lang, enc):
before_locale = _get_current_locale()
enc = codecs.lookup(enc).name
new_locale = lang, enc
if not can_set_locale(new_locale):
msg = "unsupported locale setting"
with pytest.raises(locale.Error, match=msg):
with set_locale(new_locale):
pass
else:
with set_locale(new_locale) as normalized_locale:
new_lang, new_enc = normalized_locale.split(".")
new_enc = codecs.lookup(enc).name
normalized_locale = new_lang, new_enc
assert normalized_locale == new_locale
# Once we exit the "with" statement, locale should be back to what it was.
after_locale = _get_current_locale()
assert before_locale == after_locale
def test_encoding_detected():
system_locale = os.environ.get("LC_ALL")
system_encoding = system_locale.split(".")[-1] if system_locale else "utf-8"
assert (
codecs.lookup(pd.options.display.encoding).name
== codecs.lookup(system_encoding).name
)
|