diff --git a/.github/workflows/posix.yml b/.github/workflows/posix.yml index 3fa9341bd0fef..807e8a4c1d3bd 100644 --- a/.github/workflows/posix.yml +++ b/.github/workflows/posix.yml @@ -25,23 +25,20 @@ jobs: strategy: matrix: settings: [ - [actions-38-minimum_versions.yaml, "not slow and not network and not clipboard", "", "", "", "", ""], - [actions-38-locale_slow.yaml, "slow", "language-pack-it xsel", "it_IT.utf8", "it_IT.utf8", "", ""], - [actions-38.yaml, "not slow and not clipboard", "", "", "", "", ""], - [actions-38-slow.yaml, "slow", "", "", "", "", ""], - [actions-38-locale.yaml, "not slow and not network", "language-pack-zh-hans xsel", "zh_CN.utf8", "zh_CN.utf8", "", ""], - [actions-39-slow.yaml, "slow", "", "", "", "", ""], - [actions-pypy-38.yaml, "not slow and not clipboard", "", "", "", "", "--max-worker-restart 0"], - [actions-39-numpydev.yaml, "not slow and not network", "xsel", "", "", "deprecate", "-W error"], - [actions-39.yaml, "not slow and not clipboard", "", "", "", "", ""] + [actions-38-minimum_versions.yaml, "not slow and not network and not clipboard", "", "", ""], + [actions-38-locale_clipboard.yaml, "not slow and not network", "language-pack-zh-hans language-pack-it xsel", "", ""], + [actions-38-slow.yaml, "slow", "", "", ""], + [actions-39-slow.yaml, "slow", "", "", ""], + [actions-38.yaml, "not slow and not clipboard", "", "", ""], + [actions-39.yaml, "not slow and not clipboard", "", "", ""], + [actions-pypy-38.yaml, "not slow and not clipboard", "", "", "--max-worker-restart 0"], + [actions-39-numpydev.yaml, "not slow and not network", "xsel", "deprecate", "-W error"], ] fail-fast: false env: ENV_FILE: ci/deps/${{ matrix.settings[0] }} PATTERN: ${{ matrix.settings[1] }} EXTRA_APT: ${{ matrix.settings[2] }} - LANG: ${{ matrix.settings[3] }} - LC_ALL: ${{ matrix.settings[4] }} PANDAS_TESTING_MODE: ${{ matrix.settings[5] }} TEST_ARGS: ${{ matrix.settings[6] }} PYTEST_TARGET: pandas diff --git a/ci/deps/actions-38-locale.yaml b/ci/deps/actions-38-locale_clipboard.yaml similarity index 100% rename from ci/deps/actions-38-locale.yaml rename to ci/deps/actions-38-locale_clipboard.yaml diff --git a/ci/deps/actions-38-locale_slow.yaml b/ci/deps/actions-38-locale_slow.yaml deleted file mode 100644 index e90acafa8bb2b..0000000000000 --- a/ci/deps/actions-38-locale_slow.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: pandas-dev -channels: - - defaults - - conda-forge -dependencies: - - python=3.8 - - # tools - - cython>=0.29.24 - - pytest>=6.0 - - pytest-cov - - pytest-xdist>=1.31 - - hypothesis>=5.5.3 - - # pandas dependencies - - beautifulsoup4=4.8.2 - - bottleneck=1.3.1 - - lxml - - matplotlib=3.3.2 - - numpy=1.18 - - openpyxl=3.0.2 - - python-dateutil - - python-blosc - - pytz=2020.1 - - scipy - - sqlalchemy=1.4.0 - - xlrd=2.0.1 - - xlsxwriter=1.2.2 - - xlwt=1.3.0 - - html5lib=1.1 diff --git a/ci/setup_env.sh b/ci/setup_env.sh index d51ff98b241a6..88425f900f38c 100755 --- a/ci/setup_env.sh +++ b/ci/setup_env.sh @@ -1,18 +1,5 @@ #!/bin/bash -e -# edit the locale file if needed -if [[ "$(uname)" == "Linux" && -n "$LC_ALL" ]]; then - echo "Adding locale to the first line of pandas/__init__.py" - rm -f pandas/__init__.pyc - SEDC="3iimport locale\nlocale.setlocale(locale.LC_ALL, '$LC_ALL')\n" - sed -i "$SEDC" pandas/__init__.py - - echo "[head -4 pandas/__init__.py]" - head -4 pandas/__init__.py - echo -fi - - echo "Install Miniconda" DEFAULT_CONDA_URL="https://repo.continuum.io/miniconda/Miniconda3-latest" if [[ "$(uname -m)" == 'aarch64' ]]; then diff --git a/pandas/_libs/tslibs/nattype.pyx b/pandas/_libs/tslibs/nattype.pyx index 141bc01716c4d..abb11907b270e 100644 --- a/pandas/_libs/tslibs/nattype.pyx +++ b/pandas/_libs/tslibs/nattype.pyx @@ -530,7 +530,7 @@ class NaTType(_NaT): Examples -------- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651') - >>> ts.strftime('%Y-%m-%d %X') + >>> ts.strftime('%Y-%m-%d %H:%M:%S') '2020-03-14 15:32:52' """, ) diff --git a/pandas/_libs/tslibs/timestamps.pyx b/pandas/_libs/tslibs/timestamps.pyx index 1c26793876e5a..7819ae0da4da5 100644 --- a/pandas/_libs/tslibs/timestamps.pyx +++ b/pandas/_libs/tslibs/timestamps.pyx @@ -1199,7 +1199,7 @@ class Timestamp(_Timestamp): Examples -------- >>> ts = pd.Timestamp('2020-03-14T15:32:52.192548651') - >>> ts.strftime('%Y-%m-%d %X') + >>> ts.strftime('%Y-%m-%d %H:%M:%S') '2020-03-14 15:32:52' """ return datetime.strftime(self, format) diff --git a/pandas/_testing/__init__.py b/pandas/_testing/__init__.py index 5154626dc3c7c..f182929692eb8 100644 --- a/pandas/_testing/__init__.py +++ b/pandas/_testing/__init__.py @@ -26,6 +26,7 @@ ) from pandas._typing import Dtype +from pandas.compat import is_platform_linux from pandas.core.dtypes.common import ( is_float_dtype, @@ -190,6 +191,13 @@ EMPTY_STRING_PATTERN = re.compile("^$") +# Our Linux CI environments install the associated language packs +if os.environ.get("PANDAS_CI", "0") == "1" and is_platform_linux(): + ci_locales = get_locales() or [] +else: + ci_locales = [] +TESTING_LOCALES = [loc for loc in ci_locales if loc in {"it_IT.UTF-8", "zh_CN.UTF-8"}] + # set testing_mode _testing_mode_warnings = (DeprecationWarning, ResourceWarning) diff --git a/pandas/tests/config/test_localization.py b/pandas/tests/config/test_localization.py index 21b1b7ed6ee65..e4d75f0ca455a 100644 --- a/pandas/tests/config/test_localization.py +++ b/pandas/tests/config/test_localization.py @@ -13,6 +13,7 @@ from pandas.compat import is_platform_windows import pandas as pd +import pandas._testing as tm _all_locales = get_locales() or [] _current_locale = locale.getlocale() @@ -62,21 +63,9 @@ def test_get_locales_prefix(): @_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): - if all(x is None for x in _current_locale): - # Not sure why, but on some Travis runs with pytest, - # getlocale() returned (None, None). - pytest.skip("Current locale is not set.") - +@pytest.mark.parametrize("test_local", tm.TESTING_LOCALES) +def test_set_locale(test_local): + lang, enc = test_local.split(".") enc = codecs.lookup(enc).name new_locale = lang, enc diff --git a/pandas/tests/frame/conftest.py b/pandas/tests/frame/conftest.py index b512664b57ade..1f14ba49a6f8c 100644 --- a/pandas/tests/frame/conftest.py +++ b/pandas/tests/frame/conftest.py @@ -9,6 +9,12 @@ import pandas._testing as tm +@pytest.fixture(params=tm.TESTING_LOCALES, autouse=True) +def with_locale(request): + with tm.set_locale(request.param): + yield + + @pytest.fixture def float_frame_with_na(): """ diff --git a/pandas/tests/frame/methods/test_between_time.py b/pandas/tests/frame/methods/test_between_time.py index d8a742c644e9e..3122181cf6a1f 100644 --- a/pandas/tests/frame/methods/test_between_time.py +++ b/pandas/tests/frame/methods/test_between_time.py @@ -2,12 +2,12 @@ datetime, time, ) +import locale import numpy as np import pytest from pandas._libs.tslibs import timezones -import pandas.util._test_decorators as td from pandas import ( DataFrame, @@ -18,14 +18,9 @@ class TestBetweenTime: - @td.skip_if_has_locale - def test_between_time_formats(self, frame_or_series): - # GH#11818 - rng = date_range("1/1/2000", "1/5/2000", freq="5min") - ts = DataFrame(np.random.randn(len(rng), 2), index=rng) - ts = tm.get_obj(ts, frame_or_series) - - strings = [ + @pytest.mark.parametrize( + "time_string", + [ ("2:00", "2:30"), ("0200", "0230"), ("2:00am", "2:30am"), @@ -34,11 +29,23 @@ def test_between_time_formats(self, frame_or_series): ("020000", "023000"), ("2:00:00am", "2:30:00am"), ("020000am", "023000am"), - ] - expected_length = 28 + ], + ) + def test_between_time_formats(self, request, time_string, frame_or_series): + # GH#11818 + request.node.add_marker( + pytest.mark.xfail( + "am" in time_string[0] and locale.getlocale()[0] == "zh_CN", + reason="Does not pass with LC_ALL=zh_CN.utf8", + ) + ) + rng = date_range("1/1/2000", "1/5/2000", freq="5min") + ts = DataFrame(np.random.randn(len(rng), 2), index=rng) + if frame_or_series is Series: + ts = ts[0] - for time_string in strings: - assert len(ts.between_time(*time_string)) == expected_length + expected_length = 28 + assert len(ts.between_time(*time_string)) == expected_length @pytest.mark.parametrize("tzstr", ["US/Eastern", "dateutil/US/Eastern"]) def test_localized_between_time(self, tzstr, frame_or_series): diff --git a/pandas/tests/io/conftest.py b/pandas/tests/io/conftest.py index 86842f6a608d6..8fd18f069ad2f 100644 --- a/pandas/tests/io/conftest.py +++ b/pandas/tests/io/conftest.py @@ -17,6 +17,12 @@ from pandas.io.parsers import read_csv +@pytest.fixture(params=tm.TESTING_LOCALES, autouse=True) +def with_locale(request): + with tm.set_locale(request.param): + yield + + @pytest.fixture def tips_file(datapath): """Path to the tips dataset""" diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index 7d18c2e63e74f..b3ceef1a1bb7b 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -738,9 +738,10 @@ def test_bad_sheetname_raises(self, read_ext, sheet_name): def test_missing_file_raises(self, read_ext): bad_file = f"foo{read_ext}" - # CI tests with zh_CN.utf8, translates to "No such file or directory" + # Error message matches CI locales: "No such file or directory" with pytest.raises( - FileNotFoundError, match=r"(No such file or directory|没有那个文件或目录)" + FileNotFoundError, + match=r"(No such file or directory|没有那个文件或目录|File o directory)", ): pd.read_excel(bad_file) diff --git a/pandas/tests/io/parser/common/test_index.py b/pandas/tests/io/parser/common/test_index.py index 69afb9fe56472..50dc7db918c9c 100644 --- a/pandas/tests/io/parser/common/test_index.py +++ b/pandas/tests/io/parser/common/test_index.py @@ -4,6 +4,7 @@ """ from datetime import datetime from io import StringIO +import locale import os import pytest @@ -85,7 +86,7 @@ def test_pass_names_with_index(all_parsers, data, kwargs, expected): @pytest.mark.parametrize("index_col", [[0, 1], [1, 0]]) -def test_multi_index_no_level_names(all_parsers, index_col): +def test_multi_index_no_level_names(request, all_parsers, index_col): data = """index1,index2,A,B,C,D foo,one,2,3,4,5 foo,two,7,8,9,10 @@ -93,6 +94,12 @@ def test_multi_index_no_level_names(all_parsers, index_col): bar,one,12,13,14,15 bar,two,12,13,14,15 """ + if locale.getlocale()[0] != "zh_CN": + request.node.add_marker( + pytest.mark.xfail( + reason="Only passes with LC_ALL=zh_CN.utf8", + ) + ) headless_data = "\n".join(data.split("\n")[1:]) names = ["A", "B", "C", "D"] diff --git a/pandas/tests/io/parser/test_parse_dates.py b/pandas/tests/io/parser/test_parse_dates.py index 1dfd81366de72..aeb65a13c0f7c 100644 --- a/pandas/tests/io/parser/test_parse_dates.py +++ b/pandas/tests/io/parser/test_parse_dates.py @@ -8,6 +8,7 @@ datetime, ) from io import StringIO +import locale import warnings from dateutil.parser import parse as du_parse @@ -862,7 +863,7 @@ def test_parse_dates_column_list(all_parsers, parse_dates): @xfail_pyarrow @pytest.mark.parametrize("index_col", [[0, 1], [1, 0]]) -def test_multi_index_parse_dates(all_parsers, index_col): +def test_multi_index_parse_dates(request, all_parsers, index_col): data = """index1,index2,A,B,C 20090101,one,a,1,2 20090101,two,b,3,4 @@ -874,6 +875,12 @@ def test_multi_index_parse_dates(all_parsers, index_col): 20090103,two,b,3,4 20090103,three,c,4,5 """ + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] == "it_IT" and index_col == ["index2", "index1"], + reason="Only passes with LC_ALL=zh_CN.utf8", + ) + ) parser = all_parsers index = MultiIndex.from_product( [ @@ -1841,7 +1848,7 @@ def test_parse_dates_and_keep_orgin_column(all_parsers): tm.assert_frame_equal(result, expected) -def test_dayfirst_warnings(): +def test_dayfirst_warnings(request): # GH 12585 warning_msg_day_first = ( "Parsing '31/12/2014' in DD/MM/YYYY format. Provide " @@ -1883,6 +1890,12 @@ def test_dayfirst_warnings(): # D. infer_datetime_format=True overrides dayfirst default # no warning + correct result + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] == "zh_CN", + reason="Does not pass with LC_ALL=zh_CN.utf8", + ) + ) res4 = read_csv( StringIO(input), parse_dates=["date"], diff --git a/pandas/tests/strings/conftest.py b/pandas/tests/strings/conftest.py index 15cc5af97a2d6..8e52f1f5a5f13 100644 --- a/pandas/tests/strings/conftest.py +++ b/pandas/tests/strings/conftest.py @@ -2,8 +2,16 @@ import pytest from pandas import Series +import pandas._testing as tm from pandas.core import strings as strings + +@pytest.fixture(params=tm.TESTING_LOCALES, autouse=True) +def with_locale(request): + with tm.set_locale(request.param): + yield + + _any_string_method = [ ("cat", (), {"sep": ","}), ("cat", (Series(list("zyx")),), {"sep": ",", "join": "left"}), diff --git a/pandas/tests/tools/conftest.py b/pandas/tests/tools/conftest.py new file mode 100644 index 0000000000000..e054eec7fa383 --- /dev/null +++ b/pandas/tests/tools/conftest.py @@ -0,0 +1,9 @@ +import pytest + +import pandas._testing as tm + + +@pytest.fixture(params=tm.TESTING_LOCALES, autouse=True) +def with_locale(request): + with tm.set_locale(request.param): + yield diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py index 013af7eb90cd3..3c8cc09d208da 100644 --- a/pandas/tests/tools/test_to_datetime.py +++ b/pandas/tests/tools/test_to_datetime.py @@ -282,43 +282,42 @@ def test_to_datetime_format_microsecond(self, cache): "%m/%d/%Y %H:%M:%S", Timestamp("2010-01-10 13:56:01"), ], - pytest.param( + [ "01/10/2010 08:14 PM", "%m/%d/%Y %I:%M %p", Timestamp("2010-01-10 20:14"), - marks=pytest.mark.xfail( - locale.getlocale()[0] == "zh_CN", - reason="fail on a CI build with LC_ALL=zh_CN.utf8", - ), - ), - pytest.param( + ], + [ "01/10/2010 07:40 AM", "%m/%d/%Y %I:%M %p", Timestamp("2010-01-10 07:40"), - marks=pytest.mark.xfail( - locale.getlocale()[0] == "zh_CN", - reason="fail on a CI build with LC_ALL=zh_CN.utf8", - ), - ), - pytest.param( + ], + [ "01/10/2010 09:12:56 AM", "%m/%d/%Y %I:%M:%S %p", Timestamp("2010-01-10 09:12:56"), - marks=pytest.mark.xfail( - locale.getlocale()[0] == "zh_CN", - reason="fail on a CI build with LC_ALL=zh_CN.utf8", - ), - ), + ], ], ) - def test_to_datetime_format_time(self, cache, value, format, dt): + def test_to_datetime_format_time(self, request, cache, value, format, dt): + request.node.add_marker( + pytest.mark.xfail( + "%p" in format and locale.getlocale()[0] == "zh_CN", + reason="Does not pass with LC_ALL=zh_CN.utf8", + ) + ) assert to_datetime(value, format=format, cache=cache) == dt - @td.skip_if_has_locale - def test_to_datetime_with_non_exact(self, cache): + def test_to_datetime_with_non_exact(self, request, cache): # GH 10834 # 8904 # exact kw + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] != "en_US", + reason="Only passes with LC_ALL=en_US.utf8", + ) + ) ser = Series( ["19MAY11", "foobar19MAY11", "19MAY11:00:00:00", "19MAY11 00:00:00Z"] ) @@ -1670,21 +1669,29 @@ def test_to_datetime_with_space_in_series(self, cache): result_ignore = to_datetime(ser, errors="ignore", cache=cache) tm.assert_series_equal(result_ignore, ser) - @td.skip_if_has_locale - def test_to_datetime_with_apply(self, cache): - # this is only locale tested with US/None locales + def test_to_datetime_with_apply(self, request, cache): # GH 5195 # with a format and coerce a single item to_datetime fails + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] != "en_US", + reason="Only passes with LC_ALL=en_US.utf8", + ) + ) td = Series(["May 04", "Jun 02", "Dec 11"], index=[1, 2, 3]) expected = to_datetime(td, format="%b %y", cache=cache) result = td.apply(to_datetime, format="%b %y", cache=cache) tm.assert_series_equal(result, expected) - @td.skip_if_has_locale - def test_to_datetime_with_apply_with_empty_str(self, cache): - # this is only locale tested with US/None locales + def test_to_datetime_with_apply_with_empty_str(self, request, cache): # GH 5195 # with a format and coerce a single item to_datetime fails + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] != "en_US", + reason="Only passes with LC_ALL=en_US.utf8", + ) + ) td = Series(["May 04", "Jun 02", ""], index=[1, 2, 3]) msg = r"time data '' does not match format '%b %y' \(match\)" with pytest.raises(ValueError, match=msg): @@ -1891,7 +1898,7 @@ def test_dayfirst(self, cache): tm.assert_index_equal(expected, idx5) tm.assert_index_equal(expected, idx6) - def test_dayfirst_warnings_valid_input(self): + def test_dayfirst_warnings_valid_input(self, request): # GH 12585 warning_msg_day_first = ( "Parsing '31/12/2014' in DD/MM/YYYY format. Provide " @@ -1923,6 +1930,12 @@ def test_dayfirst_warnings_valid_input(self): # D. infer_datetime_format=True overrides dayfirst default # no warning + correct result + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] == "zh_CN", + reason="Does not pass with LC_ALL=zh_CN.utf8", + ) + ) res4 = to_datetime(arr, infer_datetime_format=True) tm.assert_index_equal(expected_consistent, res4) @@ -1979,7 +1992,6 @@ def test_to_datetime_dta_tz(self, klass): class TestGuessDatetimeFormat: - @td.skip_if_not_us_locale @pytest.mark.parametrize( "test_array", [ @@ -1992,7 +2004,13 @@ class TestGuessDatetimeFormat: ["2011-12-30 00:00:00.000000", "random_string"], ], ) - def test_guess_datetime_format_for_array(self, test_array): + def test_guess_datetime_format_for_array(self, request, test_array): + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] == "zh_CN", + reason="Does not pass with LC_ALL=zh_CN.utf8", + ) + ) expected_format = "%Y-%m-%d %H:%M:%S.%f" assert tools._guess_datetime_format_for_array(test_array) == expected_format diff --git a/pandas/tests/tools/test_to_time.py b/pandas/tests/tools/test_to_time.py index 968102ce9edde..e7ad82e0dbfed 100644 --- a/pandas/tests/tools/test_to_time.py +++ b/pandas/tests/tools/test_to_time.py @@ -9,11 +9,6 @@ from pandas.core.tools.datetimes import to_time as to_time_alias from pandas.core.tools.times import to_time -fails_on_zh_cn = pytest.mark.xfail( - locale.getlocale()[0] == "zh_CN", - reason="fail on a CI build with LC_ALL=zh_CN.utf8", -) - class TestToTime: @pytest.mark.parametrize( @@ -21,17 +16,25 @@ class TestToTime: [ "14:15", "1415", - pytest.param("2:15pm", marks=fails_on_zh_cn), - pytest.param("0215pm", marks=fails_on_zh_cn), + "2:15pm", + "0215pm", "14:15:00", "141500", - pytest.param("2:15:00pm", marks=fails_on_zh_cn), - pytest.param("021500pm", marks=fails_on_zh_cn), + "2:15:00pm", + "021500pm", time(14, 15), ], ) - def test_parsers_time(self, time_string): + def test_parsers_time(self, request, time_string): # GH#11818 + request.node.add_marker( + pytest.mark.xfail( + isinstance(time_string, str) + and "pm" in time_string + and locale.getlocale()[0] == "zh_CN", + reason="fail on a CI build with LC_ALL=zh_CN.utf8", + ) + ) assert to_time(time_string) == time(14, 15) def test_odd_format(self): diff --git a/pandas/tests/tslibs/conftest.py b/pandas/tests/tslibs/conftest.py new file mode 100644 index 0000000000000..e054eec7fa383 --- /dev/null +++ b/pandas/tests/tslibs/conftest.py @@ -0,0 +1,9 @@ +import pytest + +import pandas._testing as tm + + +@pytest.fixture(params=tm.TESTING_LOCALES, autouse=True) +def with_locale(request): + with tm.set_locale(request.param): + yield diff --git a/pandas/tests/tslibs/test_parsing.py b/pandas/tests/tslibs/test_parsing.py index 3d2daec442c38..f5c5b79a6b46a 100644 --- a/pandas/tests/tslibs/test_parsing.py +++ b/pandas/tests/tslibs/test_parsing.py @@ -2,6 +2,7 @@ Tests for Timestamp parsing, aimed at pandas/_libs/tslibs/parsing.pyx """ from datetime import datetime +import locale import re from dateutil.parser import parse @@ -10,7 +11,6 @@ from pandas._libs.tslibs import parsing from pandas._libs.tslibs.parsing import parse_time_string -import pandas.util._test_decorators as td import pandas._testing as tm @@ -135,7 +135,6 @@ def test_parsers_month_freq(date_str, expected): assert result == expected -@td.skip_if_not_us_locale @pytest.mark.parametrize( "string,fmt", [ @@ -171,7 +170,19 @@ def test_parsers_month_freq(date_str, expected): ("Tuesday 24 Aug 2021 01:30:48 AM", "%A %d %b %Y %H:%M:%S %p"), ], ) -def test_guess_datetime_format_with_parseable_formats(string, fmt): +def test_guess_datetime_format_with_parseable_formats(request, string, fmt): + request.node.add_marker( + pytest.mark.xfail( + fmt and fmt.endswith("%p") and locale.getlocale()[0] == "it_IT", + reason="Only passes with LC_ALL=en_US.utf8", + ) + ) + request.node.add_marker( + pytest.mark.xfail( + fmt not in (None, "%Y%m%d") and locale.getlocale()[0] == "zh_CN", + reason="Only passes with LC_ALL=en_US.utf8", + ) + ) result = parsing.guess_datetime_format(string) assert result == fmt @@ -183,7 +194,6 @@ def test_guess_datetime_format_with_dayfirst(dayfirst, expected): assert result == expected -@td.skip_if_has_locale @pytest.mark.parametrize( "string,fmt", [ @@ -192,7 +202,13 @@ def test_guess_datetime_format_with_dayfirst(dayfirst, expected): ("30/Dec/2011 00:00:00", "%d/%b/%Y %H:%M:%S"), ], ) -def test_guess_datetime_format_with_locale_specific_formats(string, fmt): +def test_guess_datetime_format_with_locale_specific_formats(request, string, fmt): + request.node.add_marker( + pytest.mark.xfail( + locale.getlocale()[0] != "en_US", + reason="Only passes with LC_ALL=en_US.utf8", + ) + ) result = parsing.guess_datetime_format(string) assert result == fmt diff --git a/pandas/util/_test_decorators.py b/pandas/util/_test_decorators.py index 7c5c0959ceaa0..7ce5460867fa9 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -101,12 +101,6 @@ def _skip_if_no_mpl(): return True -def _skip_if_has_locale(): - lang, _ = locale.getlocale() - if lang is not None: - return True - - def _skip_if_not_us_locale(): lang, _ = locale.getlocale() if lang != "en_US": @@ -184,9 +178,6 @@ def skip_if_no(package: str, min_version: str | None = None): skip_if_mpl = pytest.mark.skipif(not _skip_if_no_mpl(), reason="matplotlib is present") skip_if_32bit = pytest.mark.skipif(not IS64, reason="skipping for 32 bit") skip_if_windows = pytest.mark.skipif(is_platform_windows(), reason="Running on Windows") -skip_if_has_locale = pytest.mark.skipif( - _skip_if_has_locale(), reason=f"Specific locale is set {locale.getlocale()[0]}" -) skip_if_not_us_locale = pytest.mark.skipif( _skip_if_not_us_locale(), reason=f"Specific locale is set {locale.getlocale()[0]}" )