diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-03-21 21:34:22 -0600 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2018-03-24 09:52:42 -0600 |
commit | e8389cb15f8d8fd902ea9f7aad0da64bce0f2583 (patch) | |
tree | 9a8f0630f95273cb23a2d8ba3aa954204d5a9571 | |
parent | 04c23fa59e71fbfbbcf24849954d7651cc72285e (diff) | |
download | python-numpy-e8389cb15f8d8fd902ea9f7aad0da64bce0f2583.tar.gz python-numpy-e8389cb15f8d8fd902ea9f7aad0da64bce0f2583.tar.bz2 python-numpy-e8389cb15f8d8fd902ea9f7aad0da64bce0f2583.zip |
TST: Remove nose dependence of locale tests.
Add class CommaDecimalPointLocale that can be used for testing in a
LC_NUMERIC locale where the decimal point is a comma. It functions
either as a context manager or as a base class with setup and teardown
methods. Both uses raise SkipTest when no suitable locale is available.
-rw-r--r-- | numpy/core/tests/_locales.py | 76 | ||||
-rw-r--r-- | numpy/core/tests/test_longdouble.py | 84 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 19 | ||||
-rw-r--r-- | numpy/core/tests/test_print.py | 53 |
4 files changed, 139 insertions, 93 deletions
diff --git a/numpy/core/tests/_locales.py b/numpy/core/tests/_locales.py new file mode 100644 index 000000000..28eebb14d --- /dev/null +++ b/numpy/core/tests/_locales.py @@ -0,0 +1,76 @@ +"""Provide class for testing in French locale + +""" +from __future__ import division, absolute_import, print_function + +import sys +import locale + +from numpy.testing import SkipTest + +__ALL__ = ['CommaDecimalPointLocale'] + + +def find_comma_decimal_point_locale(): + """See if platform has a decimal point as comma locale. + + Find a locale that uses a comma instead of a period as the + decimal point. + + Returns + ------- + old_locale: str + Locale when the function was called. + new_locale: {str, None) + First French locale found, None if none found. + + """ + if sys.platform == 'win32': + locales = ['FRENCH'] + else: + locales = ['fr_FR', 'fr_FR.UTF-8', 'fi_FI', 'fi_FI.UTF-8'] + + old_locale = locale.getlocale(locale.LC_NUMERIC) + new_locale = None + try: + for loc in locales: + try: + locale.setlocale(locale.LC_NUMERIC, loc) + new_locale = loc + break + except locale.Error: + pass + finally: + locale.setlocale(locale.LC_NUMERIC, locale=old_locale) + return old_locale, new_locale + + +class CommaDecimalPointLocale(object): + """Sets LC_NUMERIC to a locale with comma as decimal point. + + Classes derived from this class have setup and teardown methods that run + tests with locale.LC_NUMERIC set to a locale where commas (',') are used as + the decimal point instead of periods ('.'). On exit the locale is restored + to the initial locale. It also serves as context manager with the same + effect. If no such locale is available, it raises SkipTest in both cases. + + .. versionadded:: 1.15.0 + + """ + (cur_locale, tst_locale) = find_comma_decimal_point_locale() + + def setup(self): + if self.tst_locale is None: + raise SkipTest("No French locale available") + locale.setlocale(locale.LC_NUMERIC, locale=self.tst_locale) + + def teardown(self): + locale.setlocale(locale.LC_NUMERIC, locale=self.cur_locale) + + def __enter__(self): + if self.tst_locale is None: + raise SkipTest("No French locale available") + locale.setlocale(locale.LC_NUMERIC, locale=self.tst_locale) + + def __exit__(self, type, value, traceback): + locale.setlocale(locale.LC_NUMERIC, locale=self.cur_locale) diff --git a/numpy/core/tests/test_longdouble.py b/numpy/core/tests/test_longdouble.py index 625d40c1b..7cd5b04d8 100644 --- a/numpy/core/tests/test_longdouble.py +++ b/numpy/core/tests/test_longdouble.py @@ -7,7 +7,7 @@ from numpy.testing import ( run_module_suite, assert_, assert_equal, dec, assert_raises, assert_array_equal, temppath, ) -from .test_print import in_foreign_locale +from ._locales import CommaDecimalPointLocale LD_INFO = np.finfo(np.longdouble) longdouble_longer_than_double = (LD_INFO.eps < np.finfo(np.double).eps) @@ -50,25 +50,12 @@ def test_bytes(): np.longdouble(b"1.2") -@in_foreign_locale -def test_fromstring_foreign_repr(): - f = 1.234 - a = np.fromstring(repr(f), dtype=float, sep=" ") - assert_equal(a[0], f) - - @dec.knownfailureif(string_to_longdouble_inaccurate, "Need strtold_l") def test_repr_roundtrip_bytes(): o = 1 + LD_INFO.eps assert_equal(np.longdouble(repr(o).encode("ascii")), o) -@in_foreign_locale -def test_repr_roundtrip_foreign(): - o = 1.5 - assert_equal(o, np.longdouble(repr(o))) - - def test_bogus_string(): assert_raises(ValueError, np.longdouble, "spam") assert_raises(ValueError, np.longdouble, "1.0 flub") @@ -83,18 +70,6 @@ def test_fromstring(): err_msg="reading '%s'" % s) -@in_foreign_locale -def test_fromstring_best_effort_float(): - assert_equal(np.fromstring("1,234", dtype=float, sep=" "), - np.array([1.])) - - -@in_foreign_locale -def test_fromstring_best_effort(): - assert_equal(np.fromstring("1,234", dtype=np.longdouble, sep=" "), - np.array([1.])) - - def test_fromstring_bogus(): assert_equal(np.fromstring("1. 2. 3. flop 4.", dtype=float, sep=" "), np.array([1., 2., 3.])) @@ -155,26 +130,6 @@ class TestFileBased(object): assert_equal(res, self.tgt) -@in_foreign_locale -def test_fromstring_foreign(): - s = "1.234" - a = np.fromstring(s, dtype=np.longdouble, sep=" ") - assert_equal(a[0], np.longdouble(s)) - - -@in_foreign_locale -def test_fromstring_foreign_sep(): - a = np.array([1, 2, 3, 4]) - b = np.fromstring("1,2,3,4,", dtype=np.longdouble, sep=",") - assert_array_equal(a, b) - - -@in_foreign_locale -def test_fromstring_foreign_value(): - b = np.fromstring("1,234", dtype=np.longdouble, sep=" ") - assert_array_equal(b[0], 1) - - # Conversions long double -> string @@ -207,6 +162,43 @@ def test_array_repr(): raise ValueError("precision loss creating arrays") assert_(repr(a) != repr(b)) +# +# Locale tests: scalar types formatting should be independent of the locale +# + +class TestCommaDecimalPointLocale(CommaDecimalPointLocale): + + def test_repr_roundtrip_foreign(self): + o = 1.5 + assert_equal(o, np.longdouble(repr(o))) + + def test_fromstring_foreign_repr(self): + f = 1.234 + a = np.fromstring(repr(f), dtype=float, sep=" ") + assert_equal(a[0], f) + + def test_fromstring_best_effort_float(self): + assert_equal(np.fromstring("1,234", dtype=float, sep=" "), + np.array([1.])) + + def test_fromstring_best_effort(self): + assert_equal(np.fromstring("1,234", dtype=np.longdouble, sep=" "), + np.array([1.])) + + def test_fromstring_foreign(self): + s = "1.234" + a = np.fromstring(s, dtype=np.longdouble, sep=" ") + assert_equal(a[0], np.longdouble(s)) + + def test_fromstring_foreign_sep(self): + a = np.array([1, 2, 3, 4]) + b = np.fromstring("1,2,3,4,", dtype=np.longdouble, sep=",") + assert_array_equal(a, b) + + def test_fromstring_foreign_value(self): + b = np.fromstring("1,234", dtype=np.longdouble, sep=" ") + assert_array_equal(b[0], 1) + if __name__ == "__main__": run_module_suite() diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 6050f303e..da0ccf9eb 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -26,7 +26,6 @@ from decimal import Decimal import numpy as np from numpy.compat import strchar, unicode -from numpy.core.tests.test_print import in_foreign_locale from numpy.core.multiarray_tests import ( test_neighborhood_iterator, test_neighborhood_iterator_oob, test_pydatamem_seteventhook_start, test_pydatamem_seteventhook_end, @@ -38,6 +37,7 @@ from numpy.testing import ( assert_array_almost_equal, assert_allclose, IS_PYPY, HAS_REFCOUNT, assert_array_less, runstring, dec, SkipTest, temppath, suppress_warnings ) +from ._locales import CommaDecimalPointLocale # Need to test an object that does not fully implement math interface from datetime import timedelta, datetime @@ -4475,14 +4475,15 @@ class TestIO(object): assert_equal(s, '1.51,2.00,3.51,4.00') def test_locale(self): - in_foreign_locale(self.test_numbers)() - in_foreign_locale(self.test_nan)() - in_foreign_locale(self.test_inf)() - in_foreign_locale(self.test_counted_string)() - in_foreign_locale(self.test_ascii)() - in_foreign_locale(self.test_malformed)() - in_foreign_locale(self.test_tofile_sep)() - in_foreign_locale(self.test_tofile_format)() + with CommaDecimalPointLocale(): + self.test_numbers() + self.test_nan() + self.test_inf() + self.test_counted_string() + self.test_ascii() + self.test_malformed() + self.test_tofile_sep() + self.test_tofile_format() class TestFromBuffer(object): diff --git a/numpy/core/tests/test_print.py b/numpy/core/tests/test_print.py index 6ebb4733c..f432711a9 100644 --- a/numpy/core/tests/test_print.py +++ b/numpy/core/tests/test_print.py @@ -2,12 +2,14 @@ from __future__ import division, absolute_import, print_function import sys import locale +import contextlib import nose import numpy as np from numpy.testing import ( - run_module_suite, assert_, assert_equal, SkipTest + run_module_suite, assert_, assert_equal, SkipTest, dec ) +from ._locales import CommaDecimalPointLocale if sys.version_info[0] >= 3: @@ -201,46 +203,21 @@ def test_scalar_format(): (fmat, repr(val), repr(valtype), str(e))) +# # Locale tests: scalar types formatting should be independent of the locale -def in_foreign_locale(func): - """ - Swap LC_NUMERIC locale to one in which the decimal point is ',' and not '.' - If not possible, raise SkipTest +# - """ - if sys.platform == 'win32': - locales = ['FRENCH'] - else: - locales = ['fr_FR', 'fr_FR.UTF-8', 'fi_FI', 'fi_FI.UTF-8'] +class TestCommaDecimalPointLocale(CommaDecimalPointLocale): + + def test_locale_single(self): + assert_equal(str(np.float32(1.2)), str(float(1.2))) + + def test_locale_double(self): + assert_equal(str(np.double(1.2)), str(float(1.2))) + + def test_locale_longdouble(self): + assert_equal(str(np.longdouble('1.2')), str(float(1.2))) - def wrapper(*args, **kwargs): - curloc = locale.getlocale(locale.LC_NUMERIC) - try: - for loc in locales: - try: - locale.setlocale(locale.LC_NUMERIC, loc) - break - except locale.Error: - pass - else: - raise SkipTest("Skipping locale test, because " - "French locale not found") - return func(*args, **kwargs) - finally: - locale.setlocale(locale.LC_NUMERIC, locale=curloc) - return nose.tools.make_decorator(func)(wrapper) - -@in_foreign_locale -def test_locale_single(): - assert_equal(str(np.float32(1.2)), str(float(1.2))) - -@in_foreign_locale -def test_locale_double(): - assert_equal(str(np.double(1.2)), str(float(1.2))) - -@in_foreign_locale -def test_locale_longdouble(): - assert_equal(str(np.longdouble('1.2')), str(float(1.2))) if __name__ == "__main__": run_module_suite() |