From a49d86a1a70a35fc6a308fa7cf57fd6a0a375f90 Mon Sep 17 00:00:00 2001 From: Debian Science Team Date: Mon, 21 Oct 2024 19:43:11 +0100 Subject: [PATCH] Avoid failing when a dependency is too old (some of them are pulled in by other dependencies, so just not including them in d/control doesn't stop them being installed) Most of the content of this patch was generated by the following Python code: import pathlib import re basedir = pathlib.Path.cwd() if not (basedir / 'pandas/tests').exists(): raise FileNotFoundError('must be run from the pandas root') for source_file in basedir.glob('pandas/**/*.py'): with open(source_file, 'r') as fd: source_text = fd.read() if 'pytest.importorskip' in source_text: source_text = re.sub(r'pytest\.importorskip(.*)minversion', r'td.versioned_importorskip\1min_version', source_text) source_text = re.sub(r'pytest\.importorskip', r'td.versioned_importorskip', source_text) if '_test_decorators as td' not in source_text: # add the import if it isn't already present source_text, count = re.subn(r'^(import pandas|from pandas.*import)',r'import pandas.util._test_decorators as td\n\1', source_text, count=1, flags=re.MULTILINE) if count != 1: raise KeyError("failed to add import") with open(source_file, 'w') as fd: fd.write(source_text) Author: Rebecca N. Palmer Forwarded: no Gbp-Pq: Name versioned_importorskip.patch --- pandas/_testing/_io.py | 4 +- pandas/conftest.py | 4 +- pandas/tests/apply/test_frame_apply.py | 3 +- pandas/tests/apply/test_numba.py | 2 +- .../tests/arrays/categorical/test_warnings.py | 3 +- .../arrays/datetimes/test_constructors.py | 7 +- .../arrays/interval/test_interval_pyarrow.py | 13 ++-- .../tests/arrays/masked/test_arrow_compat.py | 3 +- .../tests/arrays/period/test_arrow_compat.py | 3 +- pandas/tests/arrays/sparse/test_accessor.py | 21 +++--- .../tests/arrays/sparse/test_constructors.py | 7 +- pandas/tests/arrays/string_/test_string.py | 7 +- .../tests/arrays/string_/test_string_arrow.py | 20 +++--- pandas/tests/computation/test_compat.py | 5 +- pandas/tests/copy_view/test_astype.py | 6 +- pandas/tests/dtypes/test_common.py | 2 +- pandas/tests/dtypes/test_inference.py | 3 +- pandas/tests/extension/test_arrow.py | 2 +- pandas/tests/extension/test_string.py | 3 +- pandas/tests/frame/indexing/test_indexing.py | 4 +- pandas/tests/frame/indexing/test_setitem.py | 2 +- pandas/tests/frame/methods/test_astype.py | 2 +- .../frame/methods/test_convert_dtypes.py | 15 +++-- pandas/tests/frame/methods/test_cov_corr.py | 18 ++--- pandas/tests/frame/methods/test_describe.py | 3 +- pandas/tests/frame/methods/test_dot.py | 3 +- pandas/tests/frame/methods/test_info.py | 3 +- .../tests/frame/methods/test_interpolate.py | 6 +- pandas/tests/frame/methods/test_join.py | 3 +- pandas/tests/frame/methods/test_rank.py | 9 +-- pandas/tests/frame/test_api.py | 5 +- pandas/tests/frame/test_arrow_interface.py | 2 +- pandas/tests/frame/test_constructors.py | 8 +-- pandas/tests/frame/test_query_eval.py | 4 +- pandas/tests/frame/test_reductions.py | 6 +- pandas/tests/frame/test_repr.py | 5 +- pandas/tests/frame/test_subclass.py | 3 +- pandas/tests/frame/test_ufunc.py | 3 +- pandas/tests/generic/test_finalize.py | 3 +- pandas/tests/generic/test_to_xarray.py | 3 +- pandas/tests/groupby/aggregate/test_numba.py | 33 +++++----- pandas/tests/groupby/test_counting.py | 3 +- pandas/tests/groupby/test_groupby.py | 2 +- pandas/tests/groupby/test_numba.py | 3 +- pandas/tests/groupby/test_reductions.py | 2 +- pandas/tests/groupby/test_timegrouper.py | 3 +- pandas/tests/groupby/transform/test_numba.py | 27 ++++---- .../indexes/base_class/test_constructors.py | 3 +- .../tests/indexes/base_class/test_reshape.py | 3 +- .../tests/indexes/multi/test_constructors.py | 3 +- pandas/tests/indexes/numeric/test_indexing.py | 5 +- pandas/tests/indexes/test_base.py | 2 +- pandas/tests/indexing/test_datetime.py | 3 +- pandas/tests/indexing/test_loc.py | 6 +- pandas/tests/interchange/test_impl.py | 29 ++++---- pandas/tests/interchange/test_utils.py | 3 +- pandas/tests/io/conftest.py | 10 +-- pandas/tests/io/excel/test_odf.py | 3 +- pandas/tests/io/excel/test_odswriter.py | 3 +- pandas/tests/io/excel/test_openpyxl.py | 3 +- pandas/tests/io/excel/test_readers.py | 2 +- pandas/tests/io/excel/test_style.py | 20 +++--- pandas/tests/io/excel/test_xlrd.py | 3 +- pandas/tests/io/excel/test_xlsxwriter.py | 5 +- pandas/tests/io/formats/style/test_bar.py | 3 +- .../tests/io/formats/style/test_exceptions.py | 3 +- pandas/tests/io/formats/style/test_format.py | 3 +- .../tests/io/formats/style/test_highlight.py | 3 +- pandas/tests/io/formats/style/test_html.py | 3 +- .../tests/io/formats/style/test_matplotlib.py | 11 ++-- .../tests/io/formats/style/test_non_unique.py | 3 +- pandas/tests/io/formats/style/test_style.py | 2 +- .../tests/io/formats/style/test_to_latex.py | 3 +- .../tests/io/formats/style/test_to_string.py | 3 +- pandas/tests/io/formats/style/test_tooltip.py | 3 +- pandas/tests/io/formats/test_format.py | 5 +- pandas/tests/io/formats/test_to_excel.py | 3 +- pandas/tests/io/formats/test_to_latex.py | 3 +- pandas/tests/io/formats/test_to_markdown.py | 3 +- pandas/tests/io/formats/test_to_string.py | 3 +- pandas/tests/io/json/test_pandas.py | 8 +-- pandas/tests/io/json/test_readlines.py | 3 +- pandas/tests/io/parser/conftest.py | 3 +- .../io/parser/dtypes/test_dtypes_basic.py | 9 +-- .../io/parser/test_concatenate_chunks.py | 5 +- pandas/tests/io/parser/test_network.py | 8 +-- .../io/parser/test_python_parser_only.py | 3 +- pandas/tests/io/parser/test_read_fwf.py | 7 +- pandas/tests/io/parser/test_upcast.py | 3 +- pandas/tests/io/pytables/common.py | 3 +- pandas/tests/io/pytables/test_append.py | 2 +- pandas/tests/io/pytables/test_compat.py | 3 +- pandas/tests/io/pytables/test_read.py | 2 +- pandas/tests/io/pytables/test_round_trip.py | 2 +- pandas/tests/io/pytables/test_store.py | 3 +- pandas/tests/io/pytables/test_subclass.py | 3 +- pandas/tests/io/test_clipboard.py | 5 +- pandas/tests/io/test_common.py | 18 ++--- pandas/tests/io/test_feather.py | 3 +- pandas/tests/io/test_fsspec.py | 30 ++++----- pandas/tests/io/test_gcs.py | 14 ++-- pandas/tests/io/test_html.py | 14 ++-- pandas/tests/io/test_http_headers.py | 2 +- pandas/tests/io/test_orc.py | 13 ++-- pandas/tests/io/test_parquet.py | 27 ++++---- pandas/tests/io/test_pickle.py | 2 +- pandas/tests/io/test_s3.py | 7 +- pandas/tests/io/test_spss.py | 5 +- pandas/tests/io/test_sql.py | 40 +++++------ pandas/tests/io/test_stata.py | 4 +- pandas/tests/io/xml/test_to_xml.py | 32 ++++----- pandas/tests/io/xml/test_xml.py | 66 +++++++++---------- pandas/tests/plotting/conftest.py | 7 +- pandas/tests/plotting/frame/test_frame.py | 22 +++---- .../tests/plotting/frame/test_frame_color.py | 25 +++---- .../plotting/frame/test_frame_groupby.py | 3 +- .../tests/plotting/frame/test_frame_legend.py | 12 ++-- .../plotting/frame/test_frame_subplots.py | 5 +- .../tests/plotting/frame/test_hist_box_by.py | 3 +- pandas/tests/plotting/test_boxplot_method.py | 5 +- pandas/tests/plotting/test_common.py | 3 +- pandas/tests/plotting/test_converter.py | 19 +++--- pandas/tests/plotting/test_datetimelike.py | 5 +- pandas/tests/plotting/test_groupby.py | 3 +- pandas/tests/plotting/test_hist_method.py | 17 ++--- pandas/tests/plotting/test_misc.py | 10 +-- pandas/tests/plotting/test_series.py | 20 +++--- pandas/tests/plotting/test_style.py | 3 +- pandas/tests/reductions/test_reductions.py | 3 +- .../tests/reductions/test_stat_reductions.py | 5 +- pandas/tests/resample/test_datetime_index.py | 2 +- pandas/tests/reshape/merge/test_merge.py | 5 +- pandas/tests/reshape/test_melt.py | 3 +- .../series/accessors/test_list_accessor.py | 3 +- .../series/accessors/test_struct_accessor.py | 5 +- .../series/methods/test_convert_dtypes.py | 5 +- pandas/tests/series/methods/test_cov_corr.py | 5 +- .../series/methods/test_drop_duplicates.py | 5 +- pandas/tests/series/methods/test_explode.py | 5 +- .../tests/series/methods/test_interpolate.py | 38 +++++------ pandas/tests/series/methods/test_rank.py | 6 +- .../tests/series/methods/test_reset_index.py | 3 +- pandas/tests/series/test_api.py | 3 +- pandas/tests/series/test_constructors.py | 12 ++-- pandas/tests/series/test_formats.py | 3 +- pandas/tests/series/test_logical_ops.py | 3 +- pandas/tests/series/test_reductions.py | 3 +- pandas/tests/strings/test_extract.py | 3 +- pandas/tests/test_algos.py | 3 +- pandas/tests/test_downstream.py | 34 +++++----- pandas/tests/test_nanops.py | 12 ++-- pandas/tests/test_optional_dependency.py | 3 +- pandas/tests/tools/test_to_datetime.py | 6 +- pandas/tests/tools/test_to_numeric.py | 10 +-- pandas/tests/tools/test_to_timedelta.py | 5 +- pandas/tests/window/test_online.py | 3 +- pandas/tests/window/test_rolling_skew_kurt.py | 11 ++-- pandas/tests/window/test_win_type.py | 47 ++++++------- pandas/util/_test_decorators.py | 23 ++++++- 159 files changed, 689 insertions(+), 563 deletions(-) diff --git a/pandas/_testing/_io.py b/pandas/_testing/_io.py index 95977edb..ca5750b2 100644 --- a/pandas/_testing/_io.py +++ b/pandas/_testing/_io.py @@ -107,9 +107,9 @@ def round_trip_localpath(writer, reader, path: str | None = None): pandas object The original object that was serialized and then re-read. """ - import pytest + import pandas.util._test_decorators as td - LocalPath = pytest.importorskip("py.path").local + LocalPath = td.versioned_importorskip("py.path").local if path is None: path = "___localpath___" with ensure_clean(path) as path: diff --git a/pandas/conftest.py b/pandas/conftest.py index 91e07f85..a08c8721 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -1816,7 +1816,7 @@ def ip(): Will raise a skip if IPython is not installed. """ - pytest.importorskip("IPython", minversion="6.0.0") + td.versioned_importorskip("IPython", min_version="6.0.0") from IPython.core.interactiveshell import InteractiveShell # GH#35711 make sure sqlite history file handle is not leaked @@ -1833,7 +1833,7 @@ def spmatrix(request): """ Yields scipy sparse matrix classes. """ - sparse = pytest.importorskip("scipy.sparse") + sparse = td.versioned_importorskip("scipy.sparse") return getattr(sparse, request.param + "_matrix") diff --git a/pandas/tests/apply/test_frame_apply.py b/pandas/tests/apply/test_frame_apply.py index b7eac6b8..166bb641 100644 --- a/pandas/tests/apply/test_frame_apply.py +++ b/pandas/tests/apply/test_frame_apply.py @@ -4,6 +4,7 @@ import warnings import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.core.dtypes.dtypes import CategoricalDtype import pandas as pd @@ -35,7 +36,7 @@ def int_frame_const_col(): @pytest.fixture(params=["python", pytest.param("numba", marks=pytest.mark.single_cpu)]) def engine(request): if request.param == "numba": - pytest.importorskip("numba") + td.versioned_importorskip("numba") return request.param diff --git a/pandas/tests/apply/test_numba.py b/pandas/tests/apply/test_numba.py index 57b81711..f6abf903 100644 --- a/pandas/tests/apply/test_numba.py +++ b/pandas/tests/apply/test_numba.py @@ -26,7 +26,7 @@ def test_numba_vs_python_noop(float_frame, apply_axis): def test_numba_vs_python_string_index(): # GH#56189 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( 1, index=Index(["a", "b"], dtype="string[pyarrow_numpy]"), diff --git a/pandas/tests/arrays/categorical/test_warnings.py b/pandas/tests/arrays/categorical/test_warnings.py index 68c59706..2cfef3fc 100644 --- a/pandas/tests/arrays/categorical/test_warnings.py +++ b/pandas/tests/arrays/categorical/test_warnings.py @@ -1,12 +1,13 @@ import pytest +import pandas.util._test_decorators as td import pandas._testing as tm class TestCategoricalWarnings: def test_tab_complete_warning(self, ip): # https://github.com/pandas-dev/pandas/issues/16409 - pytest.importorskip("IPython", minversion="6.0.0") + td.versioned_importorskip("IPython", min_version="6.0.0") from IPython.core.completer import provisionalcompleter code = "import pandas as pd; c = pd.Categorical([])" diff --git a/pandas/tests/arrays/datetimes/test_constructors.py b/pandas/tests/arrays/datetimes/test_constructors.py index 3652b5fe..1431dc25 100644 --- a/pandas/tests/arrays/datetimes/test_constructors.py +++ b/pandas/tests/arrays/datetimes/test_constructors.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs import iNaT from pandas.core.dtypes.dtypes import DatetimeTZDtype @@ -226,7 +227,7 @@ COARSE_TO_FINE_SAFE = [123, None, -123] def test_from_arrow_with_different_units_and_timezones_with( pa_unit, pd_unit, pa_tz, pd_tz, data ): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") pa_type = pa.timestamp(pa_unit, tz=pa_tz) arr = pa.array(data, type=pa_type) @@ -253,7 +254,7 @@ def test_from_arrow_with_different_units_and_timezones_with( ], ) def test_from_arrow_from_empty(unit, tz): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") data = [] arr = pa.array(data) @@ -269,7 +270,7 @@ def test_from_arrow_from_empty(unit, tz): def test_from_arrow_from_integers(): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") data = [0, 123456789, None, 2**63 - 1, iNaT, -123456789] arr = pa.array(data) diff --git a/pandas/tests/arrays/interval/test_interval_pyarrow.py b/pandas/tests/arrays/interval/test_interval_pyarrow.py index ef8701be..455b0262 100644 --- a/pandas/tests/arrays/interval/test_interval_pyarrow.py +++ b/pandas/tests/arrays/interval/test_interval_pyarrow.py @@ -1,13 +1,14 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm from pandas.core.arrays import IntervalArray def test_arrow_extension_type(): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.core.arrays.arrow.extension_types import ArrowIntervalType @@ -23,7 +24,7 @@ def test_arrow_extension_type(): def test_arrow_array(): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.core.arrays.arrow.extension_types import ArrowIntervalType @@ -52,7 +53,7 @@ def test_arrow_array(): def test_arrow_array_missing(): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.core.arrays.arrow.extension_types import ArrowIntervalType @@ -89,7 +90,7 @@ def test_arrow_array_missing(): ids=["float", "datetime64[ns]"], ) def test_arrow_table_roundtrip(breaks): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.core.arrays.arrow.extension_types import ArrowIntervalType @@ -125,7 +126,7 @@ def test_arrow_table_roundtrip(breaks): ids=["float", "datetime64[ns]"], ) def test_arrow_table_roundtrip_without_metadata(breaks): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") arr = IntervalArray.from_breaks(breaks) arr[1] = None @@ -145,7 +146,7 @@ def test_from_arrow_from_raw_struct_array(): # in case pyarrow lost the Interval extension type (eg on parquet roundtrip # with datetime64[ns] subtype, see GH-45881), still allow conversion # from arrow to IntervalArray - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") arr = pa.array([{"left": 0, "right": 1}, {"left": 1, "right": 2}]) dtype = pd.IntervalDtype(np.dtype("int64"), closed="neither") diff --git a/pandas/tests/arrays/masked/test_arrow_compat.py b/pandas/tests/arrays/masked/test_arrow_compat.py index 7a89656b..9d8137ff 100644 --- a/pandas/tests/arrays/masked/test_arrow_compat.py +++ b/pandas/tests/arrays/masked/test_arrow_compat.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm @@ -8,7 +9,7 @@ pytestmark = pytest.mark.filterwarnings( "ignore:Passing a BlockManager to DataFrame:DeprecationWarning" ) -pa = pytest.importorskip("pyarrow") +pa = td.versioned_importorskip("pyarrow") from pandas.core.arrays.arrow._arrow_utils import pyarrow_array_to_numpy_and_mask diff --git a/pandas/tests/arrays/period/test_arrow_compat.py b/pandas/tests/arrays/period/test_arrow_compat.py index 431309ac..11e5d343 100644 --- a/pandas/tests/arrays/period/test_arrow_compat.py +++ b/pandas/tests/arrays/period/test_arrow_compat.py @@ -1,5 +1,6 @@ import pytest +import pandas.util._test_decorators as td from pandas.compat.pyarrow import pa_version_under10p1 from pandas.core.dtypes.dtypes import PeriodDtype @@ -16,7 +17,7 @@ pytestmark = pytest.mark.filterwarnings( ) -pa = pytest.importorskip("pyarrow") +pa = td.versioned_importorskip("pyarrow") def test_arrow_extension_type(): diff --git a/pandas/tests/arrays/sparse/test_accessor.py b/pandas/tests/arrays/sparse/test_accessor.py index 87eb7bcf..8f9034af 100644 --- a/pandas/tests/arrays/sparse/test_accessor.py +++ b/pandas/tests/arrays/sparse/test_accessor.py @@ -3,6 +3,7 @@ import string import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import SparseDtype import pandas._testing as tm @@ -26,7 +27,7 @@ class TestSeriesAccessor: assert result == expected def test_from_coo(self): - scipy_sparse = pytest.importorskip("scipy.sparse") + scipy_sparse = td.versioned_importorskip("scipy.sparse") row = [0, 3, 1, 0] col = [0, 3, 1, 2] @@ -64,7 +65,7 @@ class TestSeriesAccessor: def test_to_coo( self, sort_labels, expected_rows, expected_cols, expected_values_pos ): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") values = SparseArray([0, np.nan, 1, 0, None, 3], fill_value=0) index = pd.MultiIndex.from_tuples( @@ -107,7 +108,7 @@ class TestFrameAccessor: @pytest.mark.parametrize("labels", [None, list(string.ascii_letters[:10])]) @pytest.mark.parametrize("dtype", ["float64", "int64"]) def test_from_spmatrix(self, format, labels, dtype): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") sp_dtype = SparseDtype(dtype, np.array(0, dtype=dtype).item()) @@ -120,7 +121,7 @@ class TestFrameAccessor: @pytest.mark.parametrize("format", ["csc", "csr", "coo"]) def test_from_spmatrix_including_explicit_zero(self, format): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") mat = sp_sparse.random(10, 2, density=0.5, format=format) mat.data[0] = 0 @@ -134,7 +135,7 @@ class TestFrameAccessor: [["a", "b"], pd.MultiIndex.from_product([["A"], ["a", "b"]]), ["a", "a"]], ) def test_from_spmatrix_columns(self, columns): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") dtype = SparseDtype("float64", 0.0) @@ -147,7 +148,7 @@ class TestFrameAccessor: "colnames", [("A", "B"), (1, 2), (1, pd.NA), (0.1, 0.2), ("x", "x"), (0, 0)] ) def test_to_coo(self, colnames): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") df = pd.DataFrame( {colnames[0]: [0, 1, 0], colnames[1]: [1, 0, 0]}, dtype="Sparse[int64, 0]" @@ -158,7 +159,7 @@ class TestFrameAccessor: @pytest.mark.parametrize("fill_value", [1, np.nan]) def test_to_coo_nonzero_fill_val_raises(self, fill_value): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = pd.DataFrame( { "A": SparseArray( @@ -174,7 +175,7 @@ class TestFrameAccessor: def test_to_coo_midx_categorical(self): # GH#50996 - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") midx = pd.MultiIndex.from_arrays( [ @@ -219,7 +220,7 @@ class TestFrameAccessor: @pytest.mark.parametrize("dtype", ["int64", "float64"]) @pytest.mark.parametrize("dense_index", [True, False]) def test_series_from_coo(self, dtype, dense_index): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") A = sp_sparse.eye(3, format="coo", dtype=dtype) result = pd.Series.sparse.from_coo(A, dense_index=dense_index) @@ -239,7 +240,7 @@ class TestFrameAccessor: def test_series_from_coo_incorrect_format_raises(self): # gh-26554 - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") m = sp_sparse.csr_matrix(np.array([[0, 1], [0, 0]])) with pytest.raises( diff --git a/pandas/tests/arrays/sparse/test_constructors.py b/pandas/tests/arrays/sparse/test_constructors.py index 2831c8ab..e66a041e 100644 --- a/pandas/tests/arrays/sparse/test_constructors.py +++ b/pandas/tests/arrays/sparse/test_constructors.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs.sparse import IntIndex import pandas as pd @@ -188,7 +189,7 @@ class TestConstructors: @pytest.mark.parametrize("format", ["coo", "csc", "csr"]) @pytest.mark.parametrize("size", [0, 10]) def test_from_spmatrix(self, size, format): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") mat = sp_sparse.random(size, 1, density=0.5, format=format) result = SparseArray.from_spmatrix(mat) @@ -199,7 +200,7 @@ class TestConstructors: @pytest.mark.parametrize("format", ["coo", "csc", "csr"]) def test_from_spmatrix_including_explicit_zero(self, format): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") mat = sp_sparse.random(10, 1, density=0.5, format=format) mat.data[0] = 0 @@ -210,7 +211,7 @@ class TestConstructors: tm.assert_numpy_array_equal(result, expected) def test_from_spmatrix_raises(self): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") mat = sp_sparse.eye(5, 4, format="csc") diff --git a/pandas/tests/arrays/string_/test_string.py b/pandas/tests/arrays/string_/test_string.py index 320bdca6..1c132809 100644 --- a/pandas/tests/arrays/string_/test_string.py +++ b/pandas/tests/arrays/string_/test_string.py @@ -7,6 +7,7 @@ import operator import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.compat.pyarrow import pa_version_under12p0 from pandas.core.dtypes.common import is_dtype_equal @@ -486,7 +487,7 @@ def test_fillna_args(dtype, arrow_string_storage): def test_arrow_array(dtype): # protocol added in 0.15.0 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") import pyarrow.compute as pc data = pd.array(["a", "b", "c"], dtype=dtype) @@ -502,7 +503,7 @@ def test_arrow_array(dtype): @pytest.mark.filterwarnings("ignore:Passing a BlockManager:DeprecationWarning") def test_arrow_roundtrip(dtype, string_storage2, request, using_infer_string): # roundtrip possible from arrow 1.0.0 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") if using_infer_string and string_storage2 != "pyarrow_numpy": request.applymarker( @@ -532,7 +533,7 @@ def test_arrow_load_from_zero_chunks( dtype, string_storage2, request, using_infer_string ): # GH-41040 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") if using_infer_string and string_storage2 != "pyarrow_numpy": request.applymarker( diff --git a/pandas/tests/arrays/string_/test_string_arrow.py b/pandas/tests/arrays/string_/test_string_arrow.py index d7811b6f..89ca9738 100644 --- a/pandas/tests/arrays/string_/test_string_arrow.py +++ b/pandas/tests/arrays/string_/test_string_arrow.py @@ -19,7 +19,7 @@ from pandas.core.arrays.string_arrow import ( def test_eq_all_na(): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") a = pd.array([pd.NA, pd.NA], dtype=StringDtype("pyarrow")) result = a == a expected = pd.array([pd.NA, pd.NA], dtype="boolean[pyarrow]") @@ -48,7 +48,7 @@ def test_config_bad_storage_raises(): @pytest.mark.parametrize("chunked", [True, False]) @pytest.mark.parametrize("array", ["numpy", "pyarrow"]) def test_constructor_not_string_type_raises(array, chunked, arrow_string_storage): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") array = pa if array in arrow_string_storage else np @@ -69,7 +69,7 @@ def test_constructor_not_string_type_raises(array, chunked, arrow_string_storage @pytest.mark.parametrize("chunked", [True, False]) def test_constructor_not_string_type_value_dictionary_raises(chunked): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") arr = pa.array([1, 2, 3], pa.dictionary(pa.int32(), pa.int32())) if chunked: @@ -87,7 +87,7 @@ def test_constructor_not_string_type_value_dictionary_raises(chunked): ) @pytest.mark.parametrize("chunked", [True, False]) def test_constructor_valid_string_type_value_dictionary(chunked): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") arr = pa.array(["1", "2", "3"], pa.large_string()).dictionary_encode() if chunked: @@ -99,14 +99,14 @@ def test_constructor_valid_string_type_value_dictionary(chunked): def test_constructor_from_list(): # GH#27673 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") result = pd.Series(["E"], dtype=StringDtype(storage="pyarrow")) assert isinstance(result.dtype, StringDtype) assert result.dtype.storage == "pyarrow" def test_from_sequence_wrong_dtype_raises(using_infer_string): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") with pd.option_context("string_storage", "python"): ArrowStringArray._from_sequence(["a", None, "c"], dtype="string") @@ -199,7 +199,7 @@ def test_pyarrow_not_installed_raises(): ], ) def test_setitem(multiple_chunks, key, value, expected): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") result = pa.array(list("abcde")) expected = pa.array(expected) @@ -216,7 +216,7 @@ def test_setitem(multiple_chunks, key, value, expected): def test_setitem_invalid_indexer_raises(): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") arr = ArrowStringArray(pa.array(list("abcde"))) @@ -242,7 +242,7 @@ def test_setitem_invalid_indexer_raises(): @pytest.mark.parametrize("dtype", ["string[pyarrow]", "string[pyarrow_numpy]"]) def test_pickle_roundtrip(dtype): # GH 42600 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = pd.Series(range(10), dtype=dtype) expected_sliced = expected.head(2) full_pickled = pickle.dumps(expected) @@ -259,7 +259,7 @@ def test_pickle_roundtrip(dtype): def test_string_dtype_error_message(): # GH#55051 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") msg = "Storage must be 'python', 'pyarrow' or 'pyarrow_numpy'." with pytest.raises(ValueError, match=msg): StringDtype("bla") diff --git a/pandas/tests/computation/test_compat.py b/pandas/tests/computation/test_compat.py index 856a5b3a..c63cd8c9 100644 --- a/pandas/tests/computation/test_compat.py +++ b/pandas/tests/computation/test_compat.py @@ -1,5 +1,6 @@ import pytest +import pandas.util._test_decorators as td from pandas.compat._optional import VERSIONS import pandas as pd @@ -13,7 +14,7 @@ def test_compat(): from pandas.core.computation.check import NUMEXPR_INSTALLED - ne = pytest.importorskip("numexpr") + ne = td.versioned_importorskip("numexpr") ver = ne.__version__ if Version(ver) < Version(VERSIONS["numexpr"]): @@ -26,7 +27,7 @@ def test_compat(): @pytest.mark.parametrize("parser", expr.PARSERS) def test_invalid_numexpr_version(engine, parser): if engine == "numexpr": - pytest.importorskip("numexpr") + td.versioned_importorskip("numexpr") a, b = 1, 2 # noqa: F841 res = pd.eval("a + b", engine=engine, parser=parser) assert res == 3 diff --git a/pandas/tests/copy_view/test_astype.py b/pandas/tests/copy_view/test_astype.py index d462ce3d..50093a72 100644 --- a/pandas/tests/copy_view/test_astype.py +++ b/pandas/tests/copy_view/test_astype.py @@ -45,7 +45,7 @@ def test_astype_single_dtype(using_copy_on_write): @pytest.mark.parametrize("new_dtype", ["int64", "Int64", "int64[pyarrow]"]) def test_astype_avoids_copy(using_copy_on_write, dtype, new_dtype): if new_dtype == "int64[pyarrow]": - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [1, 2, 3]}, dtype=dtype) df_orig = df.copy() df2 = df.astype(new_dtype) @@ -70,7 +70,7 @@ def test_astype_avoids_copy(using_copy_on_write, dtype, new_dtype): @pytest.mark.parametrize("dtype", ["float64", "int32", "Int32", "int32[pyarrow]"]) def test_astype_different_target_dtype(using_copy_on_write, dtype): if dtype == "int32[pyarrow]": - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [1, 2, 3]}) df_orig = df.copy() df2 = df.astype(dtype) @@ -198,7 +198,7 @@ def test_astype_different_timezones_different_reso(using_copy_on_write): def test_astype_arrow_timestamp(using_copy_on_write): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( { "a": [ diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index c34c97b6..d0fcfb19 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -214,7 +214,7 @@ def test_is_sparse(check_scipy): def test_is_scipy_sparse(): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") assert com.is_scipy_sparse(sp_sparse.bsr_matrix([1, 2, 3])) diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py index 0567be73..2f3530c5 100644 --- a/pandas/tests/dtypes/test_inference.py +++ b/pandas/tests/dtypes/test_inference.py @@ -28,6 +28,7 @@ import numpy as np import pytest import pytz +import pandas.util._test_decorators as td from pandas._libs import ( lib, missing as libmissing, @@ -1984,7 +1985,7 @@ def test_nan_to_nat_conversions(): @pytest.mark.filterwarnings("ignore::PendingDeprecationWarning") def test_is_scipy_sparse(spmatrix): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") assert is_scipy_sparse(spmatrix([[0, 1]])) assert not is_scipy_sparse(np.array([1])) diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index d9a3033b..bec83526 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -62,7 +62,7 @@ from pandas.api.types import ( ) from pandas.tests.extension import base -pa = pytest.importorskip("pyarrow") +pa = td.versioned_importorskip("pyarrow") from pandas.core.arrays.arrow.array import ArrowExtensionArray from pandas.core.arrays.arrow.extension_types import ArrowPeriodType diff --git a/pandas/tests/extension/test_string.py b/pandas/tests/extension/test_string.py index 2d5a134f..be356038 100644 --- a/pandas/tests/extension/test_string.py +++ b/pandas/tests/extension/test_string.py @@ -21,6 +21,7 @@ from typing import cast import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm from pandas.api.types import is_string_dtype @@ -35,7 +36,7 @@ def maybe_split_array(arr, chunked): elif arr.dtype.storage != "pyarrow": return arr - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") arrow_array = arr._pa_array split = len(arrow_array) // 2 diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index 22d9c7f2..2e761a57 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -1945,7 +1945,7 @@ def test_adding_new_conditional_column() -> None: ) def test_adding_new_conditional_column_with_string(dtype, infer_string) -> None: # https://github.com/pandas-dev/pandas/issues/56204 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [1, 2], "b": [3, 4]}) with pd.option_context("future.infer_string", infer_string): @@ -1958,7 +1958,7 @@ def test_adding_new_conditional_column_with_string(dtype, infer_string) -> None: def test_add_new_column_infer_string(): # GH#55366 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"x": [1]}) with pd.option_context("future.infer_string", True): df.loc[df["x"] == 1, "y"] = "1" diff --git a/pandas/tests/frame/indexing/test_setitem.py b/pandas/tests/frame/indexing/test_setitem.py index a58dd701..9d441e88 100644 --- a/pandas/tests/frame/indexing/test_setitem.py +++ b/pandas/tests/frame/indexing/test_setitem.py @@ -760,7 +760,7 @@ class TestDataFrameSetItem: def test_setitem_string_option_object_index(self): # GH#55638 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [1, 2]}) with pd.option_context("future.infer_string", True): df["b"] = Index(["a", "b"], dtype=object) diff --git a/pandas/tests/frame/methods/test_astype.py b/pandas/tests/frame/methods/test_astype.py index 5a1e3cd7..4c67c5b8 100644 --- a/pandas/tests/frame/methods/test_astype.py +++ b/pandas/tests/frame/methods/test_astype.py @@ -893,7 +893,7 @@ def test_frame_astype_no_copy(): @pytest.mark.parametrize("dtype", ["int64", "Int64"]) def test_astype_copies(dtype): # GH#50984 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [1, 2, 3]}, dtype=dtype) result = df.astype("int64[pyarrow]", copy=True) df.iloc[0, 0] = 100 diff --git a/pandas/tests/frame/methods/test_convert_dtypes.py b/pandas/tests/frame/methods/test_convert_dtypes.py index 521d2cb1..d822f599 100644 --- a/pandas/tests/frame/methods/test_convert_dtypes.py +++ b/pandas/tests/frame/methods/test_convert_dtypes.py @@ -3,6 +3,7 @@ import datetime import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm @@ -49,7 +50,7 @@ class TestConvertDtypes: assert result.columns.name == "cols" def test_pyarrow_dtype_backend(self): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") df = pd.DataFrame( { "a": pd.Series([1, 2, 3], dtype=np.dtype("int32")), @@ -105,13 +106,13 @@ class TestConvertDtypes: tm.assert_frame_equal(result, expected) def test_pyarrow_dtype_backend_already_pyarrow(self): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = pd.DataFrame([1, 2, 3], dtype="int64[pyarrow]") result = expected.convert_dtypes(dtype_backend="pyarrow") tm.assert_frame_equal(result, expected) def test_pyarrow_dtype_backend_from_pandas_nullable(self): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") df = pd.DataFrame( { "a": pd.Series([1, 2, None], dtype="Int32"), @@ -135,7 +136,7 @@ class TestConvertDtypes: def test_pyarrow_dtype_empty_object(self): # GH 50970 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = pd.DataFrame(columns=[0]) result = expected.convert_dtypes(dtype_backend="pyarrow") tm.assert_frame_equal(result, expected) @@ -152,7 +153,7 @@ class TestConvertDtypes: def test_pyarrow_backend_no_conversion(self): # GH#52872 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame({"a": [1, 2], "b": 1.5, "c": True, "d": "x"}) expected = df.copy() result = df.convert_dtypes( @@ -166,7 +167,7 @@ class TestConvertDtypes: def test_convert_dtypes_pyarrow_to_np_nullable(self): # GH 53648 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = pd.DataFrame(range(2), dtype="int32[pyarrow]") result = ser.convert_dtypes(dtype_backend="numpy_nullable") expected = pd.DataFrame(range(2), dtype="Int32") @@ -174,7 +175,7 @@ class TestConvertDtypes: def test_convert_dtypes_pyarrow_timestamp(self): # GH 54191 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = pd.Series(pd.date_range("2020-01-01", "2020-01-02", freq="1min")) expected = ser.astype("timestamp[ms][pyarrow]") result = expected.convert_dtypes(dtype_backend="pyarrow") diff --git a/pandas/tests/frame/methods/test_cov_corr.py b/pandas/tests/frame/methods/test_cov_corr.py index 04a08c8b..23f2cb60 100644 --- a/pandas/tests/frame/methods/test_cov_corr.py +++ b/pandas/tests/frame/methods/test_cov_corr.py @@ -105,7 +105,7 @@ class TestDataFrameCorr: @pytest.mark.parametrize("method", ["pearson", "kendall", "spearman"]) def test_corr_scipy_method(self, float_frame, method): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") float_frame.loc[float_frame.index[:5], "A"] = np.nan float_frame.loc[float_frame.index[5:10], "B"] = np.nan float_frame.loc[float_frame.index[:10], "A"] = float_frame["A"][10:20].copy() @@ -126,7 +126,7 @@ class TestDataFrameCorr: @pytest.mark.parametrize("meth", ["pearson", "kendall", "spearman"]) def test_corr_nooverlap(self, meth): # nothing in common - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame( { "A": [1, 1.5, 1, np.nan, np.nan, np.nan], @@ -159,7 +159,7 @@ class TestDataFrameCorr: # when dtypes of pandas series are different # then ndarray will have dtype=object, # so it need to be properly handled - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame({"a": [True, False], "b": [1, 0]}) expected = DataFrame(np.ones((2, 2)), index=["a", "b"], columns=["a", "b"]) @@ -201,7 +201,7 @@ class TestDataFrameCorr: @pytest.mark.parametrize("method", ["pearson", "spearman", "kendall"]) def test_corr_nullable_integer(self, nullable_column, other_column, method): # https://github.com/pandas-dev/pandas/issues/33803 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") data = DataFrame({"a": nullable_column, "b": other_column}) result = data.corr(method=method) expected = DataFrame(np.ones((2, 2)), columns=["a", "b"], index=["a", "b"]) @@ -250,7 +250,7 @@ class TestDataFrameCorr: @pytest.mark.parametrize("method", ["pearson", "spearman", "kendall"]) def test_corr_min_periods_greater_than_length(self, method): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame({"A": [1, 2], "B": [1, 2]}) result = df.corr(method=method, min_periods=3) expected = DataFrame( @@ -264,7 +264,7 @@ class TestDataFrameCorr: # when dtypes of pandas series are different # then ndarray will have dtype=object, # so it need to be properly handled - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame({"a": [1, 0], "b": [1, 0], "c": ["x", "y"]}) expected = DataFrame(np.ones((2, 2)), index=["a", "b"], columns=["a", "b"]) if numeric_only: @@ -433,7 +433,7 @@ class TestDataFrameCorrWith: def test_corrwith_spearman(self): # GH#21925 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).random(size=(100, 3))) result = df.corrwith(df**2, method="spearman") expected = Series(np.ones(len(result))) @@ -441,7 +441,7 @@ class TestDataFrameCorrWith: def test_corrwith_kendall(self): # GH#21925 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).random(size=(100, 3))) result = df.corrwith(df**2, method="kendall") expected = Series(np.ones(len(result))) @@ -449,7 +449,7 @@ class TestDataFrameCorrWith: def test_corrwith_spearman_with_tied_data(self): # GH#48826 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df1 = DataFrame( { "A": [1, np.nan, 7, 8], diff --git a/pandas/tests/frame/methods/test_describe.py b/pandas/tests/frame/methods/test_describe.py index 5beb0994..f3ddeb17 100644 --- a/pandas/tests/frame/methods/test_describe.py +++ b/pandas/tests/frame/methods/test_describe.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( Categorical, @@ -398,7 +399,7 @@ class TestDataFrameDescribe: def test_describe_exclude_pa_dtype(self): # GH#52570 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") df = DataFrame( { "a": Series([1, 2, 3], dtype=pd.ArrowDtype(pa.int8())), diff --git a/pandas/tests/frame/methods/test_dot.py b/pandas/tests/frame/methods/test_dot.py index 3e01f67c..995a6569 100644 --- a/pandas/tests/frame/methods/test_dot.py +++ b/pandas/tests/frame/methods/test_dot.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Series, @@ -144,7 +145,7 @@ class TestDataFrameDot(DotSharedTests): [("Float32", "Float64"), ("Int16", "Int32"), ("float[pyarrow]", "double[pyarrow]")], ) def test_arrow_dtype(dtype, exp_dtype): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") cols = ["a", "b"] df_a = DataFrame([[1, 2], [3, 4], [5, 6]], columns=cols, dtype="int32") diff --git a/pandas/tests/frame/methods/test_info.py b/pandas/tests/frame/methods/test_info.py index fcb7677f..6c995963 100644 --- a/pandas/tests/frame/methods/test_info.py +++ b/pandas/tests/frame/methods/test_info.py @@ -7,6 +7,7 @@ import textwrap import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.compat import ( IS64, PYPY, @@ -527,7 +528,7 @@ def test_memory_usage_empty_no_warning(): @pytest.mark.single_cpu def test_info_compute_numba(): # GH#51922 - pytest.importorskip("numba") + td.versioned_importorskip("numba") df = DataFrame([[1, 2], [3, 4]]) with option_context("compute.use_numba", True): diff --git a/pandas/tests/frame/methods/test_interpolate.py b/pandas/tests/frame/methods/test_interpolate.py index 252b9500..3262c3a1 100644 --- a/pandas/tests/frame/methods/test_interpolate.py +++ b/pandas/tests/frame/methods/test_interpolate.py @@ -213,7 +213,7 @@ class TestDataFrameInterpolate: df.interpolate(method="values") def test_interp_various(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame( {"A": [1, 2, np.nan, 4, 5, np.nan, 7], "C": [1, 2, 3, 5, 8, 13, 21]} ) @@ -252,7 +252,7 @@ class TestDataFrameInterpolate: tm.assert_frame_equal(result, expected, check_dtype=False) def test_interp_alt_scipy(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame( {"A": [1, 2, np.nan, 4, 5, np.nan, 7], "C": [1, 2, 3, 5, 8, 13, 21]} ) @@ -541,7 +541,7 @@ class TestDataFrameInterpolate: ) def test_interpolate_arrow(self, dtype): # GH#55347 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [1, None, None, None, 3]}, dtype=dtype + "[pyarrow]") result = df.interpolate(limit=2) expected = DataFrame({"a": [1, 1.5, 2.0, None, 3]}, dtype="float64[pyarrow]") diff --git a/pandas/tests/frame/methods/test_join.py b/pandas/tests/frame/methods/test_join.py index 735f6c50..cd8c017a 100644 --- a/pandas/tests/frame/methods/test_join.py +++ b/pandas/tests/frame/methods/test_join.py @@ -3,6 +3,7 @@ from datetime import datetime import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import MergeError import pandas as pd @@ -163,7 +164,7 @@ def test_join_on_single_col_dup_on_right(left_no_dup, right_w_dups, dtype): # GH 46622 # Dups on right allowed by one_to_many constraint if dtype == "string[pyarrow]": - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") left_no_dup = left_no_dup.astype(dtype) right_w_dups.index = right_w_dups.index.astype(dtype) left_no_dup.join( diff --git a/pandas/tests/frame/methods/test_rank.py b/pandas/tests/frame/methods/test_rank.py index 8d7a0b37..4a9f1aff 100644 --- a/pandas/tests/frame/methods/test_rank.py +++ b/pandas/tests/frame/methods/test_rank.py @@ -6,6 +6,7 @@ from datetime import ( import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs.algos import ( Infinity, NegInfinity, @@ -39,7 +40,7 @@ class TestRank: return request.param def test_rank(self, float_frame): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") float_frame.loc[::2, "A"] = np.nan float_frame.loc[::3, "B"] = np.nan @@ -143,7 +144,7 @@ class TestRank: float_string_frame.rank(axis=1) def test_rank_na_option(self, float_frame): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") float_frame.loc[::2, "A"] = np.nan float_frame.loc[::3, "B"] = np.nan @@ -227,7 +228,7 @@ class TestRank: @pytest.mark.parametrize("ax", [0, 1]) @pytest.mark.parametrize("m", ["average", "min", "max", "first", "dense"]) def test_rank_methods_frame(self, ax, m): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") xs = np.random.default_rng(2).integers(0, 21, (100, 26)) xs = (xs - 10.0) / 10.0 @@ -503,7 +504,7 @@ class TestRank: ) def test_rank_string_dtype(self, dtype, exp_dtype): # GH#55362 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") obj = Series(["foo", "foo", None, "foo"], dtype=dtype) result = obj.rank(method="first") expected = Series([1, 2, None, 3], dtype=exp_dtype) diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py index c7b44404..bf84ff8c 100644 --- a/pandas/tests/frame/test_api.py +++ b/pandas/tests/frame/test_api.py @@ -5,6 +5,7 @@ import pydoc import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._config import using_pyarrow_string_dtype from pandas._config.config import option_context @@ -288,7 +289,7 @@ class TestDataFrameMisc: def test_tab_complete_warning(self, ip, frame_or_series): # GH 16409 - pytest.importorskip("IPython", minversion="6.0.0") + td.versioned_importorskip("IPython", min_version="6.0.0") from IPython.core.completer import provisionalcompleter if frame_or_series is DataFrame: @@ -383,7 +384,7 @@ class TestDataFrameMisc: def test_inspect_getmembers(self): # GH38740 - pytest.importorskip("jinja2") + td.versioned_importorskip("jinja2") df = DataFrame() msg = "DataFrame._data is deprecated" with tm.assert_produces_warning( diff --git a/pandas/tests/frame/test_arrow_interface.py b/pandas/tests/frame/test_arrow_interface.py index 098d1829..cf6a9b42 100644 --- a/pandas/tests/frame/test_arrow_interface.py +++ b/pandas/tests/frame/test_arrow_interface.py @@ -6,7 +6,7 @@ import pandas.util._test_decorators as td import pandas as pd -pa = pytest.importorskip("pyarrow") +pa = td.versioned_importorskip("pyarrow") @td.skip_if_no("pyarrow", min_version="14.0") diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index cae2f6e8..95d0867f 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -2704,7 +2704,7 @@ class TestDataFrameConstructors: def test_frame_string_inference(self): # GH#54430 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype = "string[pyarrow_numpy]" expected = DataFrame( {"a": ["a", "b"]}, dtype=dtype, columns=Index(["a"], dtype=dtype) @@ -2739,7 +2739,7 @@ class TestDataFrameConstructors: def test_frame_string_inference_array_string_dtype(self): # GH#54496 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype = "string[pyarrow_numpy]" expected = DataFrame( {"a": ["a", "b"]}, dtype=dtype, columns=Index(["a"], dtype=dtype) @@ -2764,7 +2764,7 @@ class TestDataFrameConstructors: def test_frame_string_inference_block_dim(self): # GH#55363 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") with pd.option_context("future.infer_string", True): df = DataFrame(np.array([["hello", "goodbye"], ["hello", "Hello"]])) assert df._mgr.blocks[0].ndim == 2 @@ -2852,7 +2852,7 @@ class TestDataFrameConstructorIndexInference: ) def test_dict_data_arrow_column_expansion(self, key_val, col_vals, col_type): # GH 53617 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") cols = pd.arrays.ArrowExtensionArray( pa.array(col_vals, type=pa.dictionary(pa.int8(), getattr(pa, col_type)())) ) diff --git a/pandas/tests/frame/test_query_eval.py b/pandas/tests/frame/test_query_eval.py index 2c807c72..76b43b77 100644 --- a/pandas/tests/frame/test_query_eval.py +++ b/pandas/tests/frame/test_query_eval.py @@ -1384,7 +1384,7 @@ class TestDataFrameQueryBacktickQuoting: @pytest.mark.parametrize("dtype", ["int64", "Int64", "int64[pyarrow]"]) def test_query_ea_dtypes(self, dtype): if dtype == "int64[pyarrow]": - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") # GH#50261 df = DataFrame({"a": Series([1, 2], dtype=dtype)}) ref = {2} # noqa: F841 @@ -1402,7 +1402,7 @@ class TestDataFrameQueryBacktickQuoting: if engine == "numexpr" and not NUMEXPR_INSTALLED: pytest.skip("numexpr not installed") if dtype == "int64[pyarrow]": - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( {"A": Series([1, 1, 2], dtype="Int64"), "B": Series([1, 2, 2], dtype=dtype)} ) diff --git a/pandas/tests/frame/test_reductions.py b/pandas/tests/frame/test_reductions.py index bd0e38ba..b2f25854 100644 --- a/pandas/tests/frame/test_reductions.py +++ b/pandas/tests/frame/test_reductions.py @@ -369,7 +369,7 @@ class TestDataFrameAnalytics: ) def test_stat_op_calc_skew_kurtosis(self, float_frame_with_na): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") def skewness(x): if len(x) < 3: @@ -1162,7 +1162,7 @@ class TestDataFrameAnalytics: def test_idxmax_arrow_types(self): # GH#55368 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [2, 3, 1], "b": [2, 1, 1]}, dtype="int64[pyarrow]") result = df.idxmax() @@ -2020,7 +2020,7 @@ def test_reduction_axis_none_returns_scalar(method, numeric_only, dtype): result = getattr(df, method)(axis=None, numeric_only=numeric_only) np_arr = df.to_numpy(dtype=np.float64) if method in {"skew", "kurt"}: - comp_mod = pytest.importorskip("scipy.stats") + comp_mod = td.versioned_importorskip("scipy.stats") if method == "kurt": method = "kurtosis" expected = getattr(comp_mod, method)(np_arr, bias=False, axis=None) diff --git a/pandas/tests/frame/test_repr.py b/pandas/tests/frame/test_repr.py index 776007fb..0aba14d9 100644 --- a/pandas/tests/frame/test_repr.py +++ b/pandas/tests/frame/test_repr.py @@ -7,6 +7,7 @@ from io import StringIO import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._config import using_pyarrow_string_dtype from pandas import ( @@ -287,7 +288,7 @@ NaT 4""" assert "StringCol" in repr(df) def test_latex_repr(self): - pytest.importorskip("jinja2") + td.versioned_importorskip("jinja2") expected = r"""\begin{tabular}{llll} \toprule & 0 & 1 & 2 \\ @@ -475,7 +476,7 @@ NaT 4""" def test_repr_ea_columns(self, any_string_dtype): # GH#54797 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"long_column_name": [1, 2, 3], "col2": [4, 5, 6]}) df.columns = df.columns.astype(any_string_dtype) expected = """ long_column_name col2 diff --git a/pandas/tests/frame/test_subclass.py b/pandas/tests/frame/test_subclass.py index 855b5822..432d6f55 100644 --- a/pandas/tests/frame/test_subclass.py +++ b/pandas/tests/frame/test_subclass.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -669,7 +670,7 @@ class TestDataFrameSubclassing: assert isinstance(result, tm.SubclassedSeries) def test_corrwith(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") index = ["a", "b", "c", "d", "e"] columns = ["one", "two", "three", "four"] df1 = tm.SubclassedDataFrame( diff --git a/pandas/tests/frame/test_ufunc.py b/pandas/tests/frame/test_ufunc.py index 88c62da2..53256cf0 100644 --- a/pandas/tests/frame/test_ufunc.py +++ b/pandas/tests/frame/test_ufunc.py @@ -4,6 +4,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm from pandas.api.types import is_extension_array_dtype @@ -250,7 +251,7 @@ def test_alignment_deprecation_many_inputs_enforced(): # https://github.com/pandas-dev/pandas/issues/39184 # test that the deprecation also works with > 2 inputs -> using a numba # written ufunc for this because numpy itself doesn't have such ufuncs - numba = pytest.importorskip("numba") + numba = td.versioned_importorskip("numba") @numba.vectorize([numba.float64(numba.float64, numba.float64, numba.float64)]) def my_ufunc(x, y, z): diff --git a/pandas/tests/generic/test_finalize.py b/pandas/tests/generic/test_finalize.py index 866e9e20..d0793147 100644 --- a/pandas/tests/generic/test_finalize.py +++ b/pandas/tests/generic/test_finalize.py @@ -7,6 +7,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm @@ -443,7 +444,7 @@ def test_finalize_last(data): @not_implemented_mark def test_finalize_called_eval_numexpr(): - pytest.importorskip("numexpr") + td.versioned_importorskip("numexpr") df = pd.DataFrame({"A": [1, 2]}) df.attrs["A"] = 1 result = df.eval("A + 1", engine="numexpr") diff --git a/pandas/tests/generic/test_to_xarray.py b/pandas/tests/generic/test_to_xarray.py index d8401a8b..2bd235c4 100644 --- a/pandas/tests/generic/test_to_xarray.py +++ b/pandas/tests/generic/test_to_xarray.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( Categorical, DataFrame, @@ -10,7 +11,7 @@ from pandas import ( ) import pandas._testing as tm -pytest.importorskip("xarray") +td.versioned_importorskip("xarray") class TestDataFrameToXArray: diff --git a/pandas/tests/groupby/aggregate/test_numba.py b/pandas/tests/groupby/aggregate/test_numba.py index 1f7890ff..4c922191 100644 --- a/pandas/tests/groupby/aggregate/test_numba.py +++ b/pandas/tests/groupby/aggregate/test_numba.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import NumbaUtilError from pandas import ( @@ -22,7 +23,7 @@ pytestmark = pytest.mark.single_cpu def test_correct_function_signature(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def incorrect_function(x): return sum(x) * 2.7 @@ -39,7 +40,7 @@ def test_correct_function_signature(): def test_check_nopython_kwargs(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def incorrect_function(values, index): return sum(values) * 2.7 @@ -61,7 +62,7 @@ def test_check_nopython_kwargs(): @pytest.mark.parametrize("pandas_obj", ["Series", "DataFrame"]) @pytest.mark.parametrize("as_index", [True, False]) def test_numba_vs_cython(jit, pandas_obj, nogil, parallel, nopython, as_index): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def func_numba(values, index): return np.mean(values) * 2.7 @@ -92,7 +93,7 @@ def test_numba_vs_cython(jit, pandas_obj, nogil, parallel, nopython, as_index): @pytest.mark.parametrize("pandas_obj", ["Series", "DataFrame"]) def test_cache(jit, pandas_obj, nogil, parallel, nopython): # Test that the functions are cached correctly if we switch functions - pytest.importorskip("numba") + td.versioned_importorskip("numba") def func_1(values, index): return np.mean(values) - 3.4 @@ -130,7 +131,7 @@ def test_cache(jit, pandas_obj, nogil, parallel, nopython): def test_use_global_config(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def func_1(values, index): return np.mean(values) - 3.4 @@ -155,7 +156,7 @@ def test_use_global_config(): ], ) def test_multifunc_numba_vs_cython_frame(agg_kwargs): - pytest.importorskip("numba") + td.versioned_importorskip("numba") data = DataFrame( { 0: ["a", "a", "b", "b", "a"], @@ -190,7 +191,7 @@ def test_multifunc_numba_vs_cython_frame(agg_kwargs): ], ) def test_multifunc_numba_udf_frame(agg_kwargs, expected_func): - pytest.importorskip("numba") + td.versioned_importorskip("numba") data = DataFrame( { 0: ["a", "a", "b", "b", "a"], @@ -212,7 +213,7 @@ def test_multifunc_numba_udf_frame(agg_kwargs, expected_func): [{"func": ["min", "max"]}, {"func": "min"}, {"min_val": "min", "max_val": "max"}], ) def test_multifunc_numba_vs_cython_series(agg_kwargs): - pytest.importorskip("numba") + td.versioned_importorskip("numba") labels = ["a", "a", "b", "b", "a"] data = Series([1.0, 2.0, 3.0, 4.0, 5.0]) grouped = data.groupby(labels) @@ -265,7 +266,7 @@ def test_multifunc_numba_vs_cython_series(agg_kwargs): strict=False, ) def test_multifunc_numba_kwarg_propagation(data, agg_kwargs): - pytest.importorskip("numba") + td.versioned_importorskip("numba") labels = ["a", "a", "b", "b", "a"] grouped = data.groupby(labels) result = grouped.agg(**agg_kwargs, engine="numba", engine_kwargs={"parallel": True}) @@ -278,7 +279,7 @@ def test_multifunc_numba_kwarg_propagation(data, agg_kwargs): def test_args_not_cached(): # GH 41647 - pytest.importorskip("numba") + td.versioned_importorskip("numba") def sum_last(values, index, n): return values[-n:].sum() @@ -296,7 +297,7 @@ def test_args_not_cached(): def test_index_data_correctly_passed(): # GH 43133 - pytest.importorskip("numba") + td.versioned_importorskip("numba") def f(values, index): return np.mean(index) @@ -312,7 +313,7 @@ def test_index_data_correctly_passed(): def test_engine_kwargs_not_cached(): # If the user passes a different set of engine_kwargs don't return the same # jitted function - pytest.importorskip("numba") + td.versioned_importorskip("numba") nogil = True parallel = False nopython = True @@ -339,7 +340,7 @@ def test_engine_kwargs_not_cached(): @pytest.mark.filterwarnings("ignore") def test_multiindex_one_key(nogil, parallel, nopython): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def numba_func(values, index): return 1 @@ -354,7 +355,7 @@ def test_multiindex_one_key(nogil, parallel, nopython): def test_multiindex_multi_key_not_supported(nogil, parallel, nopython): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def numba_func(values, index): return 1 @@ -368,7 +369,7 @@ def test_multiindex_multi_key_not_supported(nogil, parallel, nopython): def test_multilabel_numba_vs_cython(numba_supported_reductions): - pytest.importorskip("numba") + td.versioned_importorskip("numba") reduction, kwargs = numba_supported_reductions df = DataFrame( { @@ -389,7 +390,7 @@ def test_multilabel_numba_vs_cython(numba_supported_reductions): def test_multilabel_udf_numba_vs_cython(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") df = DataFrame( { "A": ["foo", "bar", "foo", "bar", "foo", "bar", "foo", "foo"], diff --git a/pandas/tests/groupby/test_counting.py b/pandas/tests/groupby/test_counting.py index 2622895f..1efbc6b8 100644 --- a/pandas/tests/groupby/test_counting.py +++ b/pandas/tests/groupby/test_counting.py @@ -4,6 +4,7 @@ from string import ascii_lowercase import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Index, @@ -385,7 +386,7 @@ def test_count_uses_size_on_exception(): def test_count_arrow_string_array(any_string_dtype): # GH#54751 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( {"a": [1, 2, 3], "b": Series(["a", "b", "a"], dtype=any_string_dtype)} ) diff --git a/pandas/tests/groupby/test_groupby.py b/pandas/tests/groupby/test_groupby.py index 8fddb14e..fb0772af 100644 --- a/pandas/tests/groupby/test_groupby.py +++ b/pandas/tests/groupby/test_groupby.py @@ -2596,7 +2596,7 @@ def test_groupby_column_index_name_lost(func): def test_groupby_duplicate_columns(infer_string): # GH: 31735 if infer_string: - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( {"A": ["f", "e", "g", "h"], "B": ["a", "b", "c", "d"], "C": [1, 2, 3, 4]} ).astype(object) diff --git a/pandas/tests/groupby/test_numba.py b/pandas/tests/groupby/test_numba.py index ee7d3424..f7c08c73 100644 --- a/pandas/tests/groupby/test_numba.py +++ b/pandas/tests/groupby/test_numba.py @@ -1,5 +1,6 @@ import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Series, @@ -9,7 +10,7 @@ import pandas._testing as tm pytestmark = pytest.mark.single_cpu -pytest.importorskip("numba") +td.versioned_importorskip("numba") @pytest.mark.filterwarnings("ignore") diff --git a/pandas/tests/groupby/test_reductions.py b/pandas/tests/groupby/test_reductions.py index 25b0f806..31ee3a78 100644 --- a/pandas/tests/groupby/test_reductions.py +++ b/pandas/tests/groupby/test_reductions.py @@ -701,7 +701,7 @@ def test_groupby_min_max_categorical(func): @pytest.mark.parametrize("func", ["min", "max"]) def test_min_empty_string_dtype(func): # GH#55619 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype = "string[pyarrow_numpy]" df = DataFrame({"a": ["a"], "b": "a", "c": "a"}, dtype=dtype).iloc[:0] result = getattr(df.groupby("a"), func)() diff --git a/pandas/tests/groupby/test_timegrouper.py b/pandas/tests/groupby/test_timegrouper.py index 8ef7c2b8..282ac1a4 100644 --- a/pandas/tests/groupby/test_timegrouper.py +++ b/pandas/tests/groupby/test_timegrouper.py @@ -10,6 +10,7 @@ import numpy as np import pytest import pytz +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -944,7 +945,7 @@ class TestGroupBy: def test_groupby_agg_numba_timegrouper_with_nat( self, groupby_with_truncated_bingrouper ): - pytest.importorskip("numba") + td.versioned_importorskip("numba") # See discussion in GH#43487 gb = groupby_with_truncated_bingrouper diff --git a/pandas/tests/groupby/transform/test_numba.py b/pandas/tests/groupby/transform/test_numba.py index 61fcc930..09bf98f5 100644 --- a/pandas/tests/groupby/transform/test_numba.py +++ b/pandas/tests/groupby/transform/test_numba.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import NumbaUtilError from pandas import ( @@ -14,7 +15,7 @@ pytestmark = pytest.mark.single_cpu def test_correct_function_signature(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def incorrect_function(x): return x + 1 @@ -31,7 +32,7 @@ def test_correct_function_signature(): def test_check_nopython_kwargs(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def incorrect_function(values, index): return values + 1 @@ -53,7 +54,7 @@ def test_check_nopython_kwargs(): @pytest.mark.parametrize("pandas_obj", ["Series", "DataFrame"]) @pytest.mark.parametrize("as_index", [True, False]) def test_numba_vs_cython(jit, pandas_obj, nogil, parallel, nopython, as_index): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def func(values, index): return values + 1 @@ -84,7 +85,7 @@ def test_numba_vs_cython(jit, pandas_obj, nogil, parallel, nopython, as_index): @pytest.mark.parametrize("pandas_obj", ["Series", "DataFrame"]) def test_cache(jit, pandas_obj, nogil, parallel, nopython): # Test that the functions are cached correctly if we switch functions - pytest.importorskip("numba") + td.versioned_importorskip("numba") def func_1(values, index): return values + 1 @@ -121,7 +122,7 @@ def test_cache(jit, pandas_obj, nogil, parallel, nopython): def test_use_global_config(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def func_1(values, index): return values + 1 @@ -141,7 +142,7 @@ def test_use_global_config(): "agg_func", [["min", "max"], "min", {"B": ["min", "max"], "C": "sum"}] ) def test_string_cython_vs_numba(agg_func, numba_supported_reductions): - pytest.importorskip("numba") + td.versioned_importorskip("numba") agg_func, kwargs = numba_supported_reductions data = DataFrame( {0: ["a", "a", "b", "b", "a"], 1: [1.0, 2.0, 3.0, 4.0, 5.0]}, columns=[0, 1] @@ -159,7 +160,7 @@ def test_string_cython_vs_numba(agg_func, numba_supported_reductions): def test_args_not_cached(): # GH 41647 - pytest.importorskip("numba") + td.versioned_importorskip("numba") def sum_last(values, index, n): return values[-n:].sum() @@ -177,7 +178,7 @@ def test_args_not_cached(): def test_index_data_correctly_passed(): # GH 43133 - pytest.importorskip("numba") + td.versioned_importorskip("numba") def f(values, index): return index - 1 @@ -191,7 +192,7 @@ def test_index_data_correctly_passed(): def test_engine_kwargs_not_cached(): # If the user passes a different set of engine_kwargs don't return the same # jitted function - pytest.importorskip("numba") + td.versioned_importorskip("numba") nogil = True parallel = False nopython = True @@ -218,7 +219,7 @@ def test_engine_kwargs_not_cached(): @pytest.mark.filterwarnings("ignore") def test_multiindex_one_key(nogil, parallel, nopython): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def numba_func(values, index): return 1 @@ -233,7 +234,7 @@ def test_multiindex_one_key(nogil, parallel, nopython): def test_multiindex_multi_key_not_supported(nogil, parallel, nopython): - pytest.importorskip("numba") + td.versioned_importorskip("numba") def numba_func(values, index): return 1 @@ -247,7 +248,7 @@ def test_multiindex_multi_key_not_supported(nogil, parallel, nopython): def test_multilabel_numba_vs_cython(numba_supported_reductions): - pytest.importorskip("numba") + td.versioned_importorskip("numba") reduction, kwargs = numba_supported_reductions df = DataFrame( { @@ -264,7 +265,7 @@ def test_multilabel_numba_vs_cython(numba_supported_reductions): def test_multilabel_udf_numba_vs_cython(): - pytest.importorskip("numba") + td.versioned_importorskip("numba") df = DataFrame( { "A": ["foo", "bar", "foo", "bar", "foo", "bar", "foo", "foo"], diff --git a/pandas/tests/indexes/base_class/test_constructors.py b/pandas/tests/indexes/base_class/test_constructors.py index 338509dd..980c53f1 100644 --- a/pandas/tests/indexes/base_class/test_constructors.py +++ b/pandas/tests/indexes/base_class/test_constructors.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( Index, @@ -47,7 +48,7 @@ class TestIndexConstructor: def test_index_string_inference(self): # GH#54430 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype = "string[pyarrow_numpy]" expected = Index(["a", "b"], dtype=dtype) with pd.option_context("future.infer_string", True): diff --git a/pandas/tests/indexes/base_class/test_reshape.py b/pandas/tests/indexes/base_class/test_reshape.py index 814a6a51..4fb6e1b6 100644 --- a/pandas/tests/indexes/base_class/test_reshape.py +++ b/pandas/tests/indexes/base_class/test_reshape.py @@ -4,6 +4,7 @@ Tests for ndarray-like method on the base Index class import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import Index import pandas._testing as tm @@ -58,7 +59,7 @@ class TestReshape: def test_insert_none_into_string_numpy(self): # GH#55365 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") index = Index(["a", "b", "c"], dtype="string[pyarrow_numpy]") result = index.insert(-1, None) expected = Index(["a", "b", None, "c"], dtype="string[pyarrow_numpy]") diff --git a/pandas/tests/indexes/multi/test_constructors.py b/pandas/tests/indexes/multi/test_constructors.py index 8456e6a7..7bcda510 100644 --- a/pandas/tests/indexes/multi/test_constructors.py +++ b/pandas/tests/indexes/multi/test_constructors.py @@ -7,6 +7,7 @@ import itertools import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.core.dtypes.cast import construct_1d_object_array_from_listlike import pandas as pd @@ -648,7 +649,7 @@ def test_from_frame(): def test_from_frame_missing_values_multiIndex(): # GH 39984 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") df = pd.DataFrame( { diff --git a/pandas/tests/indexes/numeric/test_indexing.py b/pandas/tests/indexes/numeric/test_indexing.py index cd28d519..f53d5557 100644 --- a/pandas/tests/indexes/numeric/test_indexing.py +++ b/pandas/tests/indexes/numeric/test_indexing.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import InvalidIndexError from pandas import ( @@ -385,7 +386,7 @@ class TestGetIndexer: def test_get_indexer_masked_na_boolean(self, dtype): # GH#39133 if dtype == "bool[pyarrow]": - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") idx = Index([True, False, NA], dtype=dtype) result = idx.get_loc(False) assert result == 1 @@ -393,7 +394,7 @@ class TestGetIndexer: assert result == 2 def test_get_indexer_arrow_dictionary_target(self): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") target = Index( ArrowExtensionArray( pa.array([1, 2], type=pa.dictionary(pa.int8(), pa.int8())) diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 7eeb626d..4108e3d2 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -1285,7 +1285,7 @@ class TestIndex: def test_tab_complete_warning(self, ip): # https://github.com/pandas-dev/pandas/issues/16409 - pytest.importorskip("IPython", minversion="6.0.0") + td.versioned_importorskip("IPython", min_version="6.0.0") from IPython.core.completer import provisionalcompleter code = "import pandas as pd; idx = pd.Index([1, 2])" diff --git a/pandas/tests/indexing/test_datetime.py b/pandas/tests/indexing/test_datetime.py index af753339..bb551127 100644 --- a/pandas/tests/indexing/test_datetime.py +++ b/pandas/tests/indexing/test_datetime.py @@ -2,6 +2,7 @@ import re import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -174,7 +175,7 @@ class TestDatetimeIndex: def test_getitem_pyarrow_index(self, frame_or_series): # GH 53644 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") obj = frame_or_series( range(5), index=date_range("2020", freq="D", periods=5).astype( diff --git a/pandas/tests/indexing/test_loc.py b/pandas/tests/indexing/test_loc.py index 0cd1390d..ef7f8b48 100644 --- a/pandas/tests/indexing/test_loc.py +++ b/pandas/tests/indexing/test_loc.py @@ -1308,7 +1308,7 @@ class TestLocBaseIndependent: @pytest.mark.parametrize("spmatrix_t", ["coo_matrix", "csc_matrix", "csr_matrix"]) @pytest.mark.parametrize("dtype", [np.int64, np.float64, complex]) def test_loc_getitem_range_from_spmatrix(self, spmatrix_t, dtype): - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") spmatrix_t = getattr(sp_sparse, spmatrix_t) @@ -1337,7 +1337,7 @@ class TestLocBaseIndependent: def test_loc_getitem_sparse_frame(self): # GH34687 - sp_sparse = pytest.importorskip("scipy.sparse") + sp_sparse = td.versioned_importorskip("scipy.sparse") df = DataFrame.sparse.from_spmatrix(sp_sparse.eye(5)) result = df.loc[range(2)] @@ -3078,7 +3078,7 @@ def test_loc_periodindex_3_levels(): def test_loc_setitem_pyarrow_strings(): # GH#52319 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( { "strings": Series(["A", "B", "C"], dtype="string[pyarrow]"), diff --git a/pandas/tests/interchange/test_impl.py b/pandas/tests/interchange/test_impl.py index 25418b8b..c7b7c996 100644 --- a/pandas/tests/interchange/test_impl.py +++ b/pandas/tests/interchange/test_impl.py @@ -6,6 +6,7 @@ from datetime import ( import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs.tslibs import iNaT from pandas.compat import ( is_ci_environment, @@ -67,7 +68,7 @@ def test_categorical_dtype(data, data_categorical): def test_categorical_pyarrow(): # GH 49889 - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") arr = ["Mon", "Tue", "Mon", "Wed", "Mon", "Thu", "Fri", "Sat", "Sun"] table = pa.table({"weekday": pa.array(arr).dictionary_encode()}) @@ -82,7 +83,7 @@ def test_categorical_pyarrow(): def test_empty_categorical_pyarrow(): # https://github.com/pandas-dev/pandas/issues/53077 - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") arr = [None] table = pa.table({"arr": pa.array(arr, "float64").dictionary_encode()}) @@ -94,7 +95,7 @@ def test_empty_categorical_pyarrow(): def test_large_string_pyarrow(): # GH 52795 - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") arr = ["Mon", "Tue"] table = pa.table({"weekday": pa.array(arr, "large_string")}) @@ -120,7 +121,7 @@ def test_large_string_pyarrow(): ) def test_bitmasks_pyarrow(offset, length, expected_values): # GH 52795 - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") arr = [3.3, None, 2.1] table = pa.table({"arr": arr}).slice(offset, length) @@ -282,7 +283,7 @@ def test_categorical_to_numpy_dlpack(): @pytest.mark.parametrize("data", [{}, {"a": []}]) def test_empty_pyarrow(data): # GH 53155 - pytest.importorskip("pyarrow", "11.0.0") + td.versioned_importorskip("pyarrow", "11.0.0") from pyarrow.interchange import from_dataframe as pa_from_dataframe expected = pd.DataFrame(data) @@ -292,7 +293,7 @@ def test_empty_pyarrow(data): def test_multi_chunk_pyarrow() -> None: - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") n_legs = pa.chunked_array([[2, 2, 4], [4, 5, 100]]) names = ["n_legs"] table = pa.table([n_legs], names=names) @@ -305,7 +306,7 @@ def test_multi_chunk_pyarrow() -> None: def test_multi_chunk_column() -> None: - pytest.importorskip("pyarrow", "11.0.0") + td.versioned_importorskip("pyarrow", "11.0.0") ser = pd.Series([1, 2, None], dtype="Int64[pyarrow]") df = pd.concat([ser, ser], ignore_index=True).to_frame("a") df_orig = df.copy() @@ -327,7 +328,7 @@ def test_multi_chunk_column() -> None: def test_timestamp_ns_pyarrow(): # GH 56712 - pytest.importorskip("pyarrow", "11.0.0") + td.versioned_importorskip("pyarrow", "11.0.0") timestamp_args = { "year": 2000, "month": 1, @@ -362,7 +363,7 @@ def test_datetimetzdtype(tz, unit): def test_interchange_from_non_pandas_tz_aware(request): # GH 54239, 54287 - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") import pyarrow.compute as pc if is_platform_windows() and is_ci_environment(): @@ -420,7 +421,7 @@ def test_empty_string_column(): def test_large_string(): # GH#56702 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame({"a": ["x"]}, dtype="large_string[pyarrow]") result = pd.api.interchange.from_dataframe(df.__dataframe__()) expected = pd.DataFrame({"a": ["x"]}, dtype="object") @@ -500,7 +501,7 @@ def test_pandas_nullable_with_missing_values( ) -> None: # https://github.com/pandas-dev/pandas/issues/57643 # https://github.com/pandas-dev/pandas/issues/57664 - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") import pyarrow.interchange as pai if expected_dtype == "timestamp[us, tz=Asia/Kathmandu]": @@ -562,7 +563,7 @@ def test_pandas_nullable_without_missing_values( data: list, dtype: str, expected_dtype: str ) -> None: # https://github.com/pandas-dev/pandas/issues/57643 - pa = pytest.importorskip("pyarrow", "11.0.0") + pa = td.versioned_importorskip("pyarrow", "11.0.0") import pyarrow.interchange as pai if expected_dtype == "timestamp[us, tz=Asia/Kathmandu]": @@ -578,7 +579,7 @@ def test_pandas_nullable_without_missing_values( def test_string_validity_buffer() -> None: # https://github.com/pandas-dev/pandas/issues/57761 - pytest.importorskip("pyarrow", "11.0.0") + td.versioned_importorskip("pyarrow", "11.0.0") df = pd.DataFrame({"a": ["x"]}, dtype="large_string[pyarrow]") result = df.__dataframe__().get_column_by_name("a").get_buffers()["validity"] assert result is None @@ -586,7 +587,7 @@ def test_string_validity_buffer() -> None: def test_string_validity_buffer_no_missing() -> None: # https://github.com/pandas-dev/pandas/issues/57762 - pytest.importorskip("pyarrow", "11.0.0") + td.versioned_importorskip("pyarrow", "11.0.0") df = pd.DataFrame({"a": ["x", None]}, dtype="large_string[pyarrow]") validity = df.__dataframe__().get_column_by_name("a").get_buffers()["validity"] assert validity is not None diff --git a/pandas/tests/interchange/test_utils.py b/pandas/tests/interchange/test_utils.py index a47bc275..47b2fd65 100644 --- a/pandas/tests/interchange/test_utils.py +++ b/pandas/tests/interchange/test_utils.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas.core.interchange.utils import dtype_to_arrow_c_fmt @@ -78,7 +79,7 @@ def test_dtype_to_arrow_c_fmt(pandas_dtype, c_string): # PR01 ) def test_dtype_to_arrow_c_fmt_arrowdtype(pa_dtype, args_kwargs, c_string): # GH 52323 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") if not args_kwargs: pa_type = getattr(pa, pa_dtype)() elif isinstance(args_kwargs, tuple): diff --git a/pandas/tests/io/conftest.py b/pandas/tests/io/conftest.py index ab6cacc4..3bdbf10e 100644 --- a/pandas/tests/io/conftest.py +++ b/pandas/tests/io/conftest.py @@ -58,8 +58,8 @@ def s3_base(worker_id, monkeypatch): Sets up moto server in separate process locally Return url for motoserver/moto CI service """ - pytest.importorskip("s3fs") - pytest.importorskip("boto3") + td.versioned_importorskip("s3fs") + td.versioned_importorskip("boto3") # temporary workaround as moto fails for botocore >= 1.11 otherwise, # see https://github.com/spulec/moto/issues/1924 & 1952 @@ -80,9 +80,9 @@ def s3_base(worker_id, monkeypatch): # set in .github/workflows/unit-tests.yml yield "http://localhost:5000" else: - requests = pytest.importorskip("requests") - pytest.importorskip("moto") - pytest.importorskip("flask") # server mode needs flask too + requests = td.versioned_importorskip("requests") + td.versioned_importorskip("moto") + td.versioned_importorskip("flask") # server mode needs flask too # Launching moto in server mode, i.e., as a separate process # with an S3 endpoint on localhost diff --git a/pandas/tests/io/excel/test_odf.py b/pandas/tests/io/excel/test_odf.py index b5bb9b27..7e2f0e8b 100644 --- a/pandas/tests/io/excel/test_odf.py +++ b/pandas/tests/io/excel/test_odf.py @@ -3,12 +3,13 @@ import functools import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.compat import is_platform_windows import pandas as pd import pandas._testing as tm -pytest.importorskip("odf") +td.versioned_importorskip("odf") if is_platform_windows(): pytestmark = pytest.mark.single_cpu diff --git a/pandas/tests/io/excel/test_odswriter.py b/pandas/tests/io/excel/test_odswriter.py index 1c728ad8..a20193a3 100644 --- a/pandas/tests/io/excel/test_odswriter.py +++ b/pandas/tests/io/excel/test_odswriter.py @@ -6,6 +6,7 @@ import re import pytest +import pandas.util._test_decorators as td from pandas.compat import is_platform_windows import pandas as pd @@ -13,7 +14,7 @@ import pandas._testing as tm from pandas.io.excel import ExcelWriter -odf = pytest.importorskip("odf") +odf = td.versioned_importorskip("odf") if is_platform_windows(): pytestmark = pytest.mark.single_cpu diff --git a/pandas/tests/io/excel/test_openpyxl.py b/pandas/tests/io/excel/test_openpyxl.py index 99c19638..3fbb4bce 100644 --- a/pandas/tests/io/excel/test_openpyxl.py +++ b/pandas/tests/io/excel/test_openpyxl.py @@ -5,6 +5,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.compat import is_platform_windows import pandas as pd @@ -17,7 +18,7 @@ from pandas.io.excel import ( ) from pandas.io.excel._openpyxl import OpenpyxlReader -openpyxl = pytest.importorskip("openpyxl") +openpyxl = td.versioned_importorskip("openpyxl") if is_platform_windows(): pytestmark = pytest.mark.single_cpu diff --git a/pandas/tests/io/excel/test_readers.py b/pandas/tests/io/excel/test_readers.py index ff29d781..0db5e7b3 100644 --- a/pandas/tests/io/excel/test_readers.py +++ b/pandas/tests/io/excel/test_readers.py @@ -667,7 +667,7 @@ class TestReaders: if read_ext in (".xlsb", ".xls"): pytest.skip(f"No engine for filetype: '{read_ext}'") - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") with pd.option_context("mode.string_storage", string_storage): df = DataFrame( diff --git a/pandas/tests/io/excel/test_style.py b/pandas/tests/io/excel/test_style.py index 89615172..f0c093b3 100644 --- a/pandas/tests/io/excel/test_style.py +++ b/pandas/tests/io/excel/test_style.py @@ -16,7 +16,7 @@ import pandas._testing as tm from pandas.io.excel import ExcelWriter from pandas.io.formats.excel import ExcelFormatter -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") # jinja2 is currently required for Styler.__init__(). Technically Styler.to_excel # could compute styles and render to excel without jinja2, since there is no # 'template' file, but this needs the import error to delayed until render time. @@ -41,14 +41,14 @@ def assert_equal_cell_styles(cell1, cell2): ) def test_styler_to_excel_unstyled(engine): # compare DataFrame.to_excel and Styler.to_excel when no styles applied - pytest.importorskip(engine) + td.versioned_importorskip(engine) df = DataFrame(np.random.default_rng(2).standard_normal((2, 2))) with tm.ensure_clean(".xlsx") as path: with ExcelWriter(path, engine=engine) as writer: df.to_excel(writer, sheet_name="dataframe") df.style.to_excel(writer, sheet_name="unstyled") - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + openpyxl = td.versioned_importorskip("openpyxl") # test loading only with openpyxl with contextlib.closing(openpyxl.load_workbook(path)) as wb: for col1, col2 in zip(wb["dataframe"].columns, wb["unstyled"].columns): assert len(col1) == len(col2) @@ -133,7 +133,7 @@ shared_style_params = [ ) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) def test_styler_to_excel_basic(engine, css, attrs, expected): - pytest.importorskip(engine) + td.versioned_importorskip(engine) df = DataFrame(np.random.default_rng(2).standard_normal((1, 1))) styler = df.style.map(lambda x: css) @@ -142,7 +142,7 @@ def test_styler_to_excel_basic(engine, css, attrs, expected): df.to_excel(writer, sheet_name="dataframe") styler.to_excel(writer, sheet_name="styled") - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + openpyxl = td.versioned_importorskip("openpyxl") # test loading only with openpyxl with contextlib.closing(openpyxl.load_workbook(path)) as wb: # test unstyled data cell does not have expected styles # test styled cell has expected styles @@ -164,7 +164,7 @@ def test_styler_to_excel_basic(engine, css, attrs, expected): ) @pytest.mark.parametrize("css, attrs, expected", shared_style_params) def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): - pytest.importorskip(engine) + td.versioned_importorskip(engine) df = DataFrame(np.random.default_rng(2).standard_normal((1, 1))) styler = df.style @@ -181,7 +181,7 @@ def test_styler_to_excel_basic_indexes(engine, css, attrs, expected): null_styler.to_excel(writer, sheet_name="null_styled") styler.to_excel(writer, sheet_name="styled") - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + openpyxl = td.versioned_importorskip("openpyxl") # test loading only with openpyxl with contextlib.closing(openpyxl.load_workbook(path)) as wb: # test null styled index cells does not have expected styles # test styled cell has expected styles @@ -233,7 +233,7 @@ def test_styler_to_excel_border_style(engine, border_style): attrs = ["border", "left", "style"] expected = border_style - pytest.importorskip(engine) + td.versioned_importorskip(engine) df = DataFrame(np.random.default_rng(2).standard_normal((1, 1))) styler = df.style.map(lambda x: css) @@ -242,7 +242,7 @@ def test_styler_to_excel_border_style(engine, border_style): df.to_excel(writer, sheet_name="dataframe") styler.to_excel(writer, sheet_name="styled") - openpyxl = pytest.importorskip("openpyxl") # test loading only with openpyxl + openpyxl = td.versioned_importorskip("openpyxl") # test loading only with openpyxl with contextlib.closing(openpyxl.load_workbook(path)) as wb: # test unstyled data cell does not have expected styles # test styled cell has expected styles @@ -259,7 +259,7 @@ def test_styler_to_excel_border_style(engine, border_style): def test_styler_custom_converter(): - openpyxl = pytest.importorskip("openpyxl") + openpyxl = td.versioned_importorskip("openpyxl") def custom_converter(css): return {"font": {"color": {"rgb": "111222"}}} diff --git a/pandas/tests/io/excel/test_xlrd.py b/pandas/tests/io/excel/test_xlrd.py index 066393d9..60941e27 100644 --- a/pandas/tests/io/excel/test_xlrd.py +++ b/pandas/tests/io/excel/test_xlrd.py @@ -3,6 +3,7 @@ import io import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.compat import is_platform_windows import pandas as pd @@ -11,7 +12,7 @@ import pandas._testing as tm from pandas.io.excel import ExcelFile from pandas.io.excel._base import inspect_excel_format -xlrd = pytest.importorskip("xlrd") +xlrd = td.versioned_importorskip("xlrd") if is_platform_windows(): pytestmark = pytest.mark.single_cpu diff --git a/pandas/tests/io/excel/test_xlsxwriter.py b/pandas/tests/io/excel/test_xlsxwriter.py index 52936776..8402a7c8 100644 --- a/pandas/tests/io/excel/test_xlsxwriter.py +++ b/pandas/tests/io/excel/test_xlsxwriter.py @@ -2,6 +2,7 @@ import contextlib import pytest +import pandas.util._test_decorators as td from pandas.compat import is_platform_windows from pandas import DataFrame @@ -9,7 +10,7 @@ import pandas._testing as tm from pandas.io.excel import ExcelWriter -xlsxwriter = pytest.importorskip("xlsxwriter") +xlsxwriter = td.versioned_importorskip("xlsxwriter") if is_platform_windows(): pytestmark = pytest.mark.single_cpu @@ -23,7 +24,7 @@ def ext(): def test_column_format(ext): # Test that column formats are applied to cells. Test for issue #9167. # Applicable to xlsxwriter only. - openpyxl = pytest.importorskip("openpyxl") + openpyxl = td.versioned_importorskip("openpyxl") with tm.ensure_clean(ext) as path: frame = DataFrame({"A": [123456, 123456], "B": [123456, 123456]}) diff --git a/pandas/tests/io/formats/style/test_bar.py b/pandas/tests/io/formats/style/test_bar.py index b0e4712e..9c84fde6 100644 --- a/pandas/tests/io/formats/style/test_bar.py +++ b/pandas/tests/io/formats/style/test_bar.py @@ -3,13 +3,14 @@ import io import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( NA, DataFrame, read_csv, ) -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") def bar_grad(a=None, b=None, c=None, d=None): diff --git a/pandas/tests/io/formats/style/test_exceptions.py b/pandas/tests/io/formats/style/test_exceptions.py index d52e3a37..a742f06f 100644 --- a/pandas/tests/io/formats/style/test_exceptions.py +++ b/pandas/tests/io/formats/style/test_exceptions.py @@ -1,6 +1,7 @@ import pytest -jinja2 = pytest.importorskip("jinja2") +import pandas.util._test_decorators as td +jinja2 = td.versioned_importorskip("jinja2") from pandas import ( DataFrame, diff --git a/pandas/tests/io/formats/style/test_format.py b/pandas/tests/io/formats/style/test_format.py index 1c84816e..3531a47e 100644 --- a/pandas/tests/io/formats/style/test_format.py +++ b/pandas/tests/io/formats/style/test_format.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( NA, DataFrame, @@ -11,7 +12,7 @@ from pandas import ( option_context, ) -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") from pandas.io.formats.style import Styler from pandas.io.formats.style_render import _str_escape diff --git a/pandas/tests/io/formats/style/test_highlight.py b/pandas/tests/io/formats/style/test_highlight.py index 3d597190..b659146a 100644 --- a/pandas/tests/io/formats/style/test_highlight.py +++ b/pandas/tests/io/formats/style/test_highlight.py @@ -1,13 +1,14 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( NA, DataFrame, IndexSlice, ) -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") from pandas.io.formats.style import Styler diff --git a/pandas/tests/io/formats/style/test_html.py b/pandas/tests/io/formats/style/test_html.py index 2c5220da..2f03a579 100644 --- a/pandas/tests/io/formats/style/test_html.py +++ b/pandas/tests/io/formats/style/test_html.py @@ -6,13 +6,14 @@ from textwrap import ( import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, MultiIndex, option_context, ) -jinja2 = pytest.importorskip("jinja2") +jinja2 = td.versioned_importorskip("jinja2") from pandas.io.formats.style import Styler diff --git a/pandas/tests/io/formats/style/test_matplotlib.py b/pandas/tests/io/formats/style/test_matplotlib.py index fb7a77f1..30f03065 100644 --- a/pandas/tests/io/formats/style/test_matplotlib.py +++ b/pandas/tests/io/formats/style/test_matplotlib.py @@ -3,14 +3,15 @@ import gc import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, IndexSlice, Series, ) -pytest.importorskip("matplotlib") -pytest.importorskip("jinja2") +td.versioned_importorskip("matplotlib") +td.versioned_importorskip("jinja2") import matplotlib as mpl @@ -23,9 +24,9 @@ def mpl_cleanup(): # 1) Resets units registry # 2) Resets rc_context # 3) Closes all figures - mpl = pytest.importorskip("matplotlib") - mpl_units = pytest.importorskip("matplotlib.units") - plt = pytest.importorskip("matplotlib.pyplot") + mpl = td.versioned_importorskip("matplotlib") + mpl_units = td.versioned_importorskip("matplotlib.units") + plt = td.versioned_importorskip("matplotlib.pyplot") orig_units_registry = mpl_units.registry.copy() with mpl.rc_context(): mpl.use("template") diff --git a/pandas/tests/io/formats/style/test_non_unique.py b/pandas/tests/io/formats/style/test_non_unique.py index e4d31fe2..278fbf7b 100644 --- a/pandas/tests/io/formats/style/test_non_unique.py +++ b/pandas/tests/io/formats/style/test_non_unique.py @@ -2,12 +2,13 @@ from textwrap import dedent import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, IndexSlice, ) -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") from pandas.io.formats.style import Styler diff --git a/pandas/tests/io/formats/style/test_style.py b/pandas/tests/io/formats/style/test_style.py index 3e231e37..80b4209b 100644 --- a/pandas/tests/io/formats/style/test_style.py +++ b/pandas/tests/io/formats/style/test_style.py @@ -16,7 +16,7 @@ from pandas import ( import pandas._testing as tm import pandas.util._test_decorators as td -jinja2 = pytest.importorskip("jinja2") +jinja2 = td.versioned_importorskip("jinja2") from pandas.io.formats.style import ( # isort:skip Styler, ) diff --git a/pandas/tests/io/formats/style/test_to_latex.py b/pandas/tests/io/formats/style/test_to_latex.py index 7f1443c3..e804cfb6 100644 --- a/pandas/tests/io/formats/style/test_to_latex.py +++ b/pandas/tests/io/formats/style/test_to_latex.py @@ -3,6 +3,7 @@ from textwrap import dedent import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, MultiIndex, @@ -10,7 +11,7 @@ from pandas import ( option_context, ) -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") from pandas.io.formats.style import Styler from pandas.io.formats.style_render import ( _parse_latex_cell_styles, diff --git a/pandas/tests/io/formats/style/test_to_string.py b/pandas/tests/io/formats/style/test_to_string.py index e6f84cc9..cfe92eba 100644 --- a/pandas/tests/io/formats/style/test_to_string.py +++ b/pandas/tests/io/formats/style/test_to_string.py @@ -2,12 +2,13 @@ from textwrap import dedent import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Series, ) -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") from pandas.io.formats.style import Styler diff --git a/pandas/tests/io/formats/style/test_tooltip.py b/pandas/tests/io/formats/style/test_tooltip.py index c49a0e05..9d21067c 100644 --- a/pandas/tests/io/formats/style/test_tooltip.py +++ b/pandas/tests/io/formats/style/test_tooltip.py @@ -1,9 +1,10 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import DataFrame -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") from pandas.io.formats.style import Styler diff --git a/pandas/tests/io/formats/test_format.py b/pandas/tests/io/formats/test_format.py index 0ca29c21..017e4b90 100644 --- a/pandas/tests/io/formats/test_format.py +++ b/pandas/tests/io/formats/test_format.py @@ -11,6 +11,7 @@ from shutil import get_terminal_size import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._config import using_pyarrow_string_dtype import pandas as pd @@ -2268,7 +2269,7 @@ def test_filepath_or_buffer_arg( ): df = DataFrame([data]) if method in ["to_latex"]: # uses styler implementation - pytest.importorskip("jinja2") + td.versioned_importorskip("jinja2") if filepath_or_buffer_id not in ["string", "pathlike"] and encoding is not None: with pytest.raises( @@ -2287,7 +2288,7 @@ def test_filepath_or_buffer_arg( @pytest.mark.parametrize("method", ["to_string", "to_html", "to_latex"]) def test_filepath_or_buffer_bad_arg_raises(float_frame, method): if method in ["to_latex"]: # uses styler implementation - pytest.importorskip("jinja2") + td.versioned_importorskip("jinja2") msg = "buf is not a file name and it has no write method" with pytest.raises(TypeError, match=msg): getattr(float_frame, method)(buf=object()) diff --git a/pandas/tests/io/formats/test_to_excel.py b/pandas/tests/io/formats/test_to_excel.py index 927a9f49..583d11b6 100644 --- a/pandas/tests/io/formats/test_to_excel.py +++ b/pandas/tests/io/formats/test_to_excel.py @@ -6,6 +6,7 @@ import string import pytest +import pandas.util._test_decorators as td from pandas.errors import CSSWarning import pandas._testing as tm @@ -336,7 +337,7 @@ def tests_css_named_colors_valid(): def test_css_named_colors_from_mpl_present(): - mpl_colors = pytest.importorskip("matplotlib.colors") + mpl_colors = td.versioned_importorskip("matplotlib.colors") pd_colors = CSSToExcelConverter.NAMED_COLORS for name, color in mpl_colors.CSS4_COLORS.items(): diff --git a/pandas/tests/io/formats/test_to_latex.py b/pandas/tests/io/formats/test_to_latex.py index 1fd96dff..156824b5 100644 --- a/pandas/tests/io/formats/test_to_latex.py +++ b/pandas/tests/io/formats/test_to_latex.py @@ -4,6 +4,7 @@ from textwrap import dedent import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -11,7 +12,7 @@ from pandas import ( ) import pandas._testing as tm -pytest.importorskip("jinja2") +td.versioned_importorskip("jinja2") def _dedent(string): diff --git a/pandas/tests/io/formats/test_to_markdown.py b/pandas/tests/io/formats/test_to_markdown.py index 85eca834..af919573 100644 --- a/pandas/tests/io/formats/test_to_markdown.py +++ b/pandas/tests/io/formats/test_to_markdown.py @@ -5,10 +5,11 @@ from io import ( import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm -pytest.importorskip("tabulate") +td.versioned_importorskip("tabulate") def test_simple(): diff --git a/pandas/tests/io/formats/test_to_string.py b/pandas/tests/io/formats/test_to_string.py index 2e5a5005..022a1d52 100644 --- a/pandas/tests/io/formats/test_to_string.py +++ b/pandas/tests/io/formats/test_to_string.py @@ -10,6 +10,7 @@ from textwrap import dedent import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._config import using_pyarrow_string_dtype from pandas import ( @@ -748,7 +749,7 @@ class TestDataFrameToString: def test_to_string_string_dtype(self): # GH#50099 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( {"x": ["foo", "bar", "baz"], "y": ["a", "b", "c"], "z": [1, 2, 3]} ) diff --git a/pandas/tests/io/json/test_pandas.py b/pandas/tests/io/json/test_pandas.py index 5279f3f1..5ef69fbe 100644 --- a/pandas/tests/io/json/test_pandas.py +++ b/pandas/tests/io/json/test_pandas.py @@ -2034,7 +2034,7 @@ class TestPandasContainer: self, string_storage, dtype_backend, orient, using_infer_string ): # GH#50750 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") df = DataFrame( { "a": Series([1, np.nan, 3], dtype="Int64"), @@ -2056,7 +2056,7 @@ class TestPandasContainer: string_array_na = StringArray(np.array(["a", "b", NA], dtype=np.object_)) elif dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray string_array = ArrowExtensionArray(pa.array(["a", "b", "c"])) @@ -2103,7 +2103,7 @@ class TestPandasContainer: @pytest.mark.parametrize("orient", ["split", "records", "index"]) def test_read_json_nullable_series(self, string_storage, dtype_backend, orient): # GH#50750 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") ser = Series([1, np.nan, 3], dtype="Int64") out = ser.to_json(orient=orient) @@ -2147,7 +2147,7 @@ def test_pyarrow_engine_lines_false(): def test_json_roundtrip_string_inference(orient): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( [["a", "b"], ["c", "d"]], index=["row 1", "row 2"], columns=["col 1", "col 2"] ) diff --git a/pandas/tests/io/json/test_readlines.py b/pandas/tests/io/json/test_readlines.py index d96ccb4b..5663f238 100644 --- a/pandas/tests/io/json/test_readlines.py +++ b/pandas/tests/io/json/test_readlines.py @@ -5,6 +5,7 @@ from pathlib import Path import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -28,7 +29,7 @@ def lines_json_df(): @pytest.fixture(params=["ujson", "pyarrow"]) def engine(request): if request.param == "pyarrow": - pytest.importorskip("pyarrow.json") + td.versioned_importorskip("pyarrow.json") return request.param diff --git a/pandas/tests/io/parser/conftest.py b/pandas/tests/io/parser/conftest.py index 6d5f870f..ef030ac2 100644 --- a/pandas/tests/io/parser/conftest.py +++ b/pandas/tests/io/parser/conftest.py @@ -4,6 +4,7 @@ import os import pytest +import pandas.util._test_decorators as td from pandas.compat._optional import VERSIONS from pandas import ( @@ -135,7 +136,7 @@ def all_parsers(request): """ parser = request.param() if parser.engine == "pyarrow": - pytest.importorskip("pyarrow", VERSIONS["pyarrow"]) + td.versioned_importorskip("pyarrow", VERSIONS["pyarrow"]) # Try finding a way to disable threads all together # for more stable CI runs import pyarrow diff --git a/pandas/tests/io/parser/dtypes/test_dtypes_basic.py b/pandas/tests/io/parser/dtypes/test_dtypes_basic.py index ce02e752..8b247792 100644 --- a/pandas/tests/io/parser/dtypes/test_dtypes_basic.py +++ b/pandas/tests/io/parser/dtypes/test_dtypes_basic.py @@ -8,6 +8,7 @@ from io import StringIO import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import ParserWarning import pandas as pd @@ -460,7 +461,7 @@ def test_dtype_backend_and_dtype(all_parsers): def test_dtype_backend_string(all_parsers, string_storage): # GH#36712 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") with pd.option_context("mode.string_storage", string_storage): parser = all_parsers @@ -503,7 +504,7 @@ def test_dtype_backend_ea_dtype_specified(all_parsers): def test_dtype_backend_pyarrow(all_parsers, request): # GH#36712 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") parser = all_parsers data = """a,b,c,d,e,f,g,h,i,j @@ -556,7 +557,7 @@ def test_ea_int_avoid_overflow(all_parsers): def test_string_inference(all_parsers): # GH#54430 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype = "string[pyarrow_numpy]" data = """a,b @@ -577,7 +578,7 @@ y,2 @pytest.mark.parametrize("dtype", ["O", object, "object", np.object_, str, np.str_]) def test_string_inference_object_dtype(all_parsers, dtype): # GH#56047 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") data = """a,b x,a diff --git a/pandas/tests/io/parser/test_concatenate_chunks.py b/pandas/tests/io/parser/test_concatenate_chunks.py index 1bae2317..8c828460 100644 --- a/pandas/tests/io/parser/test_concatenate_chunks.py +++ b/pandas/tests/io/parser/test_concatenate_chunks.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import DtypeWarning import pandas._testing as tm @@ -11,7 +12,7 @@ from pandas.io.parsers.c_parser_wrapper import _concatenate_chunks def test_concatenate_chunks_pyarrow(): # GH#51876 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") chunks = [ {0: ArrowExtensionArray(pa.array([1.5, 2.5]))}, {0: ArrowExtensionArray(pa.array([1, 2]))}, @@ -23,7 +24,7 @@ def test_concatenate_chunks_pyarrow(): def test_concatenate_chunks_pyarrow_strings(): # GH#51876 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") chunks = [ {0: ArrowExtensionArray(pa.array([1.5, 2.5]))}, {0: ArrowExtensionArray(pa.array(["a", "b"]))}, diff --git a/pandas/tests/io/parser/test_network.py b/pandas/tests/io/parser/test_network.py index 9351387d..d064e836 100644 --- a/pandas/tests/io/parser/test_network.py +++ b/pandas/tests/io/parser/test_network.py @@ -80,7 +80,7 @@ class TestS3: def test_parse_public_s3_bucket(self, s3_public_bucket_with_data, tips_df, s3so): # more of an integration test due to the not-public contents portion # can probably mock this though. - pytest.importorskip("s3fs") + td.versioned_importorskip("s3fs") for ext, comp in [("", None), (".gz", "gzip"), (".bz2", "bz2")]: df = read_csv( f"s3://{s3_public_bucket_with_data.name}/tips.csv" + ext, @@ -93,7 +93,7 @@ class TestS3: def test_parse_private_s3_bucket(self, s3_private_bucket_with_data, tips_df, s3so): # Read public file from bucket with not-public contents - pytest.importorskip("s3fs") + td.versioned_importorskip("s3fs") df = read_csv( f"s3://{s3_private_bucket_with_data.name}/tips.csv", storage_options=s3so ) @@ -258,7 +258,7 @@ class TestS3: def test_write_s3_parquet_fails(self, tips_df, s3so): # GH 27679 # Attempting to write to an invalid S3 path should raise - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") import botocore # GH 34087 @@ -318,7 +318,7 @@ class TestS3: self, s3_public_bucket_with_data, feather_file, s3so ): # GH 29055 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = read_feather(feather_file) res = read_feather( f"s3://{s3_public_bucket_with_data.name}/simple_dataset.feather", diff --git a/pandas/tests/io/parser/test_python_parser_only.py b/pandas/tests/io/parser/test_python_parser_only.py index dbd474c6..08387c4e 100644 --- a/pandas/tests/io/parser/test_python_parser_only.py +++ b/pandas/tests/io/parser/test_python_parser_only.py @@ -17,6 +17,7 @@ from typing import TYPE_CHECKING import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import ( ParserError, ParserWarning, @@ -167,7 +168,7 @@ def test_decompression_regex_sep(python_parser_only, csv1, compression, klass): data = data.replace(b",", b"::") expected = parser.read_csv(csv1) - module = pytest.importorskip(compression) + module = td.versioned_importorskip(compression) klass = getattr(module, klass) with tm.ensure_clean() as path: diff --git a/pandas/tests/io/parser/test_read_fwf.py b/pandas/tests/io/parser/test_read_fwf.py index bed2b5e1..3606320b 100644 --- a/pandas/tests/io/parser/test_read_fwf.py +++ b/pandas/tests/io/parser/test_read_fwf.py @@ -14,6 +14,7 @@ from pathlib import Path import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import EmptyDataError import pandas as pd @@ -972,13 +973,13 @@ def test_dtype_backend(string_storage, dtype_backend): arr = StringArray(np.array(["a", "b"], dtype=np.object_)) arr_na = StringArray(np.array([pd.NA, "a"], dtype=np.object_)) elif dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray arr = ArrowExtensionArray(pa.array(["a", "b"])) arr_na = ArrowExtensionArray(pa.array([None, "a"])) else: - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") arr = ArrowStringArray(pa.array(["a", "b"])) arr_na = ArrowStringArray(pa.array([None, "a"])) @@ -1002,7 +1003,7 @@ def test_dtype_backend(string_storage, dtype_backend): } ) if dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray expected = DataFrame( diff --git a/pandas/tests/io/parser/test_upcast.py b/pandas/tests/io/parser/test_upcast.py index bc4c4c2e..5014a254 100644 --- a/pandas/tests/io/parser/test_upcast.py +++ b/pandas/tests/io/parser/test_upcast.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs.parsers import ( _maybe_upcast, na_values, @@ -87,7 +88,7 @@ def test_maybe_upcaste_all_nan(): @pytest.mark.parametrize("val", [na_values[np.object_], "c"]) def test_maybe_upcast_object(val, string_storage): # GH#36712 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") with pd.option_context("mode.string_storage", string_storage): arr = np.array(["a", "b", val], dtype=np.object_) diff --git a/pandas/tests/io/pytables/common.py b/pandas/tests/io/pytables/common.py index 62582b21..825ab1b9 100644 --- a/pandas/tests/io/pytables/common.py +++ b/pandas/tests/io/pytables/common.py @@ -5,9 +5,10 @@ import tempfile import pytest +import pandas.util._test_decorators as td from pandas.io.pytables import HDFStore -tables = pytest.importorskip("tables") +tables = td.versioned_importorskip("tables") # set these parameters so we don't have file sharing tables.parameters.MAX_NUMEXPR_THREADS = 1 tables.parameters.MAX_BLOSC_THREADS = 1 diff --git a/pandas/tests/io/pytables/test_append.py b/pandas/tests/io/pytables/test_append.py index 3acfd8ef..1da11240 100644 --- a/pandas/tests/io/pytables/test_append.py +++ b/pandas/tests/io/pytables/test_append.py @@ -29,7 +29,7 @@ is_crashing_arch=bool((platform.uname()[4].startswith('arm') or platform.uname() pytestmark = pytest.mark.single_cpu -tables = pytest.importorskip("tables") +tables = td.versioned_importorskip("tables") @pytest.mark.filterwarnings("ignore::tables.NaturalNameWarning") diff --git a/pandas/tests/io/pytables/test_compat.py b/pandas/tests/io/pytables/test_compat.py index b07fb3dd..6bf427ea 100644 --- a/pandas/tests/io/pytables/test_compat.py +++ b/pandas/tests/io/pytables/test_compat.py @@ -1,9 +1,10 @@ import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm -tables = pytest.importorskip("tables") +tables = td.versioned_importorskip("tables") @pytest.fixture diff --git a/pandas/tests/io/pytables/test_read.py b/pandas/tests/io/pytables/test_read.py index 78f9a874..0f049482 100644 --- a/pandas/tests/io/pytables/test_read.py +++ b/pandas/tests/io/pytables/test_read.py @@ -401,7 +401,7 @@ def test_read_py2_hdf_file_in_py3(datapath): def test_read_infer_string(tmp_path, setup_path): # GH#54431 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": ["a", "b", None]}) path = tmp_path / setup_path df.to_hdf(path, key="data", format="table") diff --git a/pandas/tests/io/pytables/test_round_trip.py b/pandas/tests/io/pytables/test_round_trip.py index 4ba9787a..d1e073ec 100644 --- a/pandas/tests/io/pytables/test_round_trip.py +++ b/pandas/tests/io/pytables/test_round_trip.py @@ -565,7 +565,7 @@ def test_round_trip_equals(tmp_path, setup_path): def test_infer_string_columns(tmp_path, setup_path): # GH# - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") path = tmp_path / setup_path with pd.option_context("future.infer_string", True): df = DataFrame(1, columns=list("ABCD"), index=list(range(10))).set_index( diff --git a/pandas/tests/io/pytables/test_store.py b/pandas/tests/io/pytables/test_store.py index 4172e12a..d3921d80 100644 --- a/pandas/tests/io/pytables/test_store.py +++ b/pandas/tests/io/pytables/test_store.py @@ -7,6 +7,7 @@ import time import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -37,7 +38,7 @@ is_crashing_arch=bool((platform.uname()[4].startswith('arm') or platform.uname() pytestmark = pytest.mark.single_cpu -tables = pytest.importorskip("tables") +tables = td.versioned_importorskip("tables") def test_context(setup_path): diff --git a/pandas/tests/io/pytables/test_subclass.py b/pandas/tests/io/pytables/test_subclass.py index 03622faa..d9ed6f24 100644 --- a/pandas/tests/io/pytables/test_subclass.py +++ b/pandas/tests/io/pytables/test_subclass.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Series, @@ -12,7 +13,7 @@ from pandas.io.pytables import ( read_hdf, ) -pytest.importorskip("tables") +td.versioned_importorskip("tables") class TestHDFStoreSubclass: diff --git a/pandas/tests/io/test_clipboard.py b/pandas/tests/io/test_clipboard.py index 3c0208fc..acfd96f9 100644 --- a/pandas/tests/io/test_clipboard.py +++ b/pandas/tests/io/test_clipboard.py @@ -3,6 +3,7 @@ from textwrap import dedent import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.errors import ( PyperclipException, PyperclipWindowsException, @@ -353,14 +354,14 @@ class TestClipboard: ): # GH#50502 if string_storage == "pyarrow" or dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") if string_storage == "python": string_array = StringArray(np.array(["x", "y"], dtype=np.object_)) string_array_na = StringArray(np.array(["x", NA], dtype=np.object_)) elif dtype_backend == "pyarrow" and engine != "c": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray string_array = ArrowExtensionArray(pa.array(["x", "y"])) diff --git a/pandas/tests/io/test_common.py b/pandas/tests/io/test_common.py index 4b79ff7b..a1b1bff0 100644 --- a/pandas/tests/io/test_common.py +++ b/pandas/tests/io/test_common.py @@ -100,7 +100,7 @@ bar2,12,13,14,15 def test_stringify_file_and_path_like(self): # GH 38125: do not stringify file objects that are also path-like - fsspec = pytest.importorskip("fsspec") + fsspec = td.versioned_importorskip("fsspec") with tm.ensure_clean() as path: with fsspec.open(f"file://{path}", mode="wb") as fsspec_obj: assert fsspec_obj == icom.stringify_path(fsspec_obj) @@ -153,7 +153,7 @@ Look,a snake,🐍""" # Test that pyarrow can handle a file opened with get_handle def test_get_handle_pyarrow_compat(self): - pa_csv = pytest.importorskip("pyarrow.csv") + pa_csv = td.versioned_importorskip("pyarrow.csv") # Test latin1, ucs-2, and ucs-4 chars data = """a,b,c @@ -196,7 +196,7 @@ Look,a snake,🐍""" ], ) def test_read_non_existent(self, reader, module, error_class, fn_ext): - pytest.importorskip(module) + td.versioned_importorskip(module) path = os.path.join(HERE, "data", "does_not_exist." + fn_ext) msg1 = rf"File (b')?.+does_not_exist\.{fn_ext}'? does not exist" @@ -234,7 +234,7 @@ Look,a snake,🐍""" ) # NOTE: Missing parent directory for pd.DataFrame.to_hdf is handled by PyTables def test_write_missing_parent_directory(self, method, module, error_class, fn_ext): - pytest.importorskip(module) + td.versioned_importorskip(module) dummy_frame = pd.DataFrame({"a": [1, 2, 3], "b": [2, 3, 4], "c": [3, 4, 5]}) @@ -264,7 +264,7 @@ Look,a snake,🐍""" def test_read_expands_user_home_dir( self, reader, module, error_class, fn_ext, monkeypatch ): - pytest.importorskip(module) + td.versioned_importorskip(module) path = os.path.join("~", "does_not_exist." + fn_ext) monkeypatch.setattr(icom, "_expand_user", lambda x: os.path.join("foo", x)) @@ -321,7 +321,7 @@ Look,a snake,🐍""" ], ) def test_read_fspath_all(self, reader, module, path, datapath): - pytest.importorskip(module) + td.versioned_importorskip(module) path = datapath(*path) mypath = CustomFSPath(path) @@ -349,13 +349,13 @@ Look,a snake,🐍""" ) def test_write_fspath_all(self, writer_name, writer_kwargs, module): if writer_name in ["to_latex"]: # uses Styler implementation - pytest.importorskip("jinja2") + td.versioned_importorskip("jinja2") p1 = tm.ensure_clean("string") p2 = tm.ensure_clean("fspath") df = pd.DataFrame({"A": [1, 2]}) with p1 as string, p2 as fspath: - pytest.importorskip(module) + td.versioned_importorskip(module) mypath = CustomFSPath(fspath) writer = getattr(df, writer_name) @@ -377,7 +377,7 @@ Look,a snake,🐍""" # Same test as write_fspath_all, except HDF5 files aren't # necessarily byte-for-byte identical for a given dataframe, so we'll # have to read and compare equality - pytest.importorskip("tables") + td.versioned_importorskip("tables") df = pd.DataFrame({"A": [1, 2]}) p1 = tm.ensure_clean("string") diff --git a/pandas/tests/io/test_feather.py b/pandas/tests/io/test_feather.py index 22a7d3b8..d4e86756 100644 --- a/pandas/tests/io/test_feather.py +++ b/pandas/tests/io/test_feather.py @@ -2,6 +2,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm from pandas.core.arrays import ( @@ -15,7 +16,7 @@ pytestmark = pytest.mark.filterwarnings( "ignore:Passing a BlockManager to DataFrame:DeprecationWarning" ) -pa = pytest.importorskip("pyarrow") +pa = td.versioned_importorskip("pyarrow") @pytest.mark.single_cpu diff --git a/pandas/tests/io/test_fsspec.py b/pandas/tests/io/test_fsspec.py index a1dec8a2..fce08511 100644 --- a/pandas/tests/io/test_fsspec.py +++ b/pandas/tests/io/test_fsspec.py @@ -25,7 +25,7 @@ pytestmark = pytest.mark.filterwarnings( @pytest.fixture def fsspectest(): - pytest.importorskip("fsspec") + td.versioned_importorskip("fsspec") from fsspec import register_implementation from fsspec.implementations.memory import MemoryFileSystem from fsspec.registry import _registry as registry @@ -59,7 +59,7 @@ def df1(): @pytest.fixture def cleared_fs(): - fsspec = pytest.importorskip("fsspec") + fsspec = td.versioned_importorskip("fsspec") memfs = fsspec.filesystem("memory") yield memfs @@ -99,7 +99,7 @@ def test_to_csv(cleared_fs, df1): def test_to_excel(cleared_fs, df1): - pytest.importorskip("openpyxl") + td.versioned_importorskip("openpyxl") ext = "xlsx" path = f"memory://test/test.{ext}" df1.to_excel(path, index=True) @@ -111,7 +111,7 @@ def test_to_excel(cleared_fs, df1): @pytest.mark.parametrize("binary_mode", [False, True]) def test_to_csv_fsspec_object(cleared_fs, binary_mode, df1): - fsspec = pytest.importorskip("fsspec") + fsspec = td.versioned_importorskip("fsspec") path = "memory://test/test.csv" mode = "wb" if binary_mode else "w" @@ -153,7 +153,7 @@ def test_read_table_options(fsspectest): def test_excel_options(fsspectest): - pytest.importorskip("openpyxl") + td.versioned_importorskip("openpyxl") extension = "xlsx" df = DataFrame({"a": [0]}) @@ -168,7 +168,7 @@ def test_excel_options(fsspectest): def test_to_parquet_new_file(cleared_fs, df1): """Regression test for writing to a not-yet-existent GCS Parquet file.""" - pytest.importorskip("fastparquet") + td.versioned_importorskip("fastparquet") df1.to_parquet( "memory://test/test.csv", index=True, engine="fastparquet", compression=None @@ -177,7 +177,7 @@ def test_to_parquet_new_file(cleared_fs, df1): def test_arrowparquet_options(fsspectest): """Regression test for writing to a not-yet-existent GCS Parquet file.""" - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [0]}) df.to_parquet( "testmem://test/test.csv", @@ -197,7 +197,7 @@ def test_arrowparquet_options(fsspectest): @td.skip_array_manager_not_yet_implemented # TODO(ArrayManager) fastparquet def test_fastparquet_options(fsspectest): """Regression test for writing to a not-yet-existent GCS Parquet file.""" - pytest.importorskip("fastparquet") + td.versioned_importorskip("fastparquet") df = DataFrame({"a": [0]}) df.to_parquet( @@ -217,7 +217,7 @@ def test_fastparquet_options(fsspectest): @pytest.mark.single_cpu def test_from_s3_csv(s3_public_bucket_with_data, tips_file, s3so): - pytest.importorskip("s3fs") + td.versioned_importorskip("s3fs") tm.assert_equal( read_csv( f"s3://{s3_public_bucket_with_data.name}/tips.csv", storage_options=s3so @@ -242,7 +242,7 @@ def test_from_s3_csv(s3_public_bucket_with_data, tips_file, s3so): @pytest.mark.single_cpu @pytest.mark.parametrize("protocol", ["s3", "s3a", "s3n"]) def test_s3_protocols(s3_public_bucket_with_data, tips_file, protocol, s3so): - pytest.importorskip("s3fs") + td.versioned_importorskip("s3fs") tm.assert_equal( read_csv( f"{protocol}://{s3_public_bucket_with_data.name}/tips.csv", @@ -255,8 +255,8 @@ def test_s3_protocols(s3_public_bucket_with_data, tips_file, protocol, s3so): @pytest.mark.single_cpu @td.skip_array_manager_not_yet_implemented # TODO(ArrayManager) fastparquet def test_s3_parquet(s3_public_bucket, s3so, df1): - pytest.importorskip("fastparquet") - pytest.importorskip("s3fs") + td.versioned_importorskip("fastparquet") + td.versioned_importorskip("s3fs") fn = f"s3://{s3_public_bucket.name}/test.parquet" df1.to_parquet( @@ -274,7 +274,7 @@ def test_not_present_exception(): def test_feather_options(fsspectest): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [0]}) df.to_feather("testmem://mockfile", storage_options={"test": "feather_write"}) assert fsspectest.test[0] == "feather_write" @@ -321,7 +321,7 @@ def test_stata_options(fsspectest): def test_markdown_options(fsspectest): - pytest.importorskip("tabulate") + td.versioned_importorskip("tabulate") df = DataFrame({"a": [0]}) df.to_markdown("testmem://mockfile", storage_options={"test": "md_write"}) assert fsspectest.test[0] == "md_write" @@ -329,7 +329,7 @@ def test_markdown_options(fsspectest): def test_non_fsspec_options(): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") with pytest.raises(ValueError, match="storage_options"): read_csv("localfile", storage_options={"a": True}) with pytest.raises(ValueError, match="storage_options"): diff --git a/pandas/tests/io/test_gcs.py b/pandas/tests/io/test_gcs.py index 4b337b5b..33e2b49d 100644 --- a/pandas/tests/io/test_gcs.py +++ b/pandas/tests/io/test_gcs.py @@ -29,8 +29,8 @@ pytestmark = pytest.mark.filterwarnings( @pytest.fixture def gcs_buffer(): """Emulate GCS using a binary buffer.""" - pytest.importorskip("gcsfs") - fsspec = pytest.importorskip("fsspec") + td.versioned_importorskip("gcsfs") + fsspec = td.versioned_importorskip("fsspec") gcs_buffer = BytesIO() gcs_buffer.close = lambda: True @@ -83,8 +83,8 @@ def test_to_read_gcs(gcs_buffer, format, monkeypatch, capsys, request): df1.to_json(path) df2 = read_json(path, convert_dates=["dt"]) elif format == "parquet": - pytest.importorskip("pyarrow") - pa_fs = pytest.importorskip("pyarrow.fs") + td.versioned_importorskip("pyarrow") + pa_fs = td.versioned_importorskip("pyarrow.fs") class MockFileSystem(pa_fs.FileSystem): @staticmethod @@ -107,7 +107,7 @@ def test_to_read_gcs(gcs_buffer, format, monkeypatch, capsys, request): captured = capsys.readouterr() assert captured.out == "Using pyarrow filesystem\nUsing pyarrow filesystem\n" elif format == "markdown": - pytest.importorskip("tabulate") + td.versioned_importorskip("tabulate") df1.to_markdown(path) df2 = df1 @@ -196,8 +196,8 @@ def test_to_csv_compression_encoding_gcs( def test_to_parquet_gcs_new_file(monkeypatch, tmpdir): """Regression test for writing to a not-yet-existent GCS Parquet file.""" - pytest.importorskip("fastparquet") - pytest.importorskip("gcsfs") + td.versioned_importorskip("fastparquet") + td.versioned_importorskip("gcsfs") from fsspec import AbstractFileSystem diff --git a/pandas/tests/io/test_html.py b/pandas/tests/io/test_html.py index 607357e7..3f8a982b 100644 --- a/pandas/tests/io/test_html.py +++ b/pandas/tests/io/test_html.py @@ -71,8 +71,8 @@ def assert_framelist_equal(list1, list2, *args, **kwargs): def test_bs4_version_fails(monkeypatch, datapath): - bs4 = pytest.importorskip("bs4") - pytest.importorskip("html5lib") + bs4 = td.versioned_importorskip("bs4") + td.versioned_importorskip("html5lib") monkeypatch.setattr(bs4, "__version__", "4.2") with pytest.raises(ImportError, match="Pandas requires version"): @@ -89,9 +89,9 @@ def test_invalid_flavor(): def test_same_ordering(datapath): - pytest.importorskip("bs4") - pytest.importorskip("lxml") - pytest.importorskip("html5lib") + td.versioned_importorskip("bs4") + td.versioned_importorskip("lxml") + td.versioned_importorskip("html5lib") filename = datapath("io", "data", "html", "valid_markup.html") dfs_lxml = read_html(filename, index_col=0, flavor=["lxml"]) @@ -184,13 +184,13 @@ class TestReadHtml: string_array = StringArray(np.array(["a", "b", "c"], dtype=np.object_)) string_array_na = StringArray(np.array(["a", "b", NA], dtype=np.object_)) elif dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray string_array = ArrowExtensionArray(pa.array(["a", "b", "c"])) string_array_na = ArrowExtensionArray(pa.array(["a", "b", None])) else: - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") string_array = ArrowStringArray(pa.array(["a", "b", "c"])) string_array_na = ArrowStringArray(pa.array(["a", "b", None])) diff --git a/pandas/tests/io/test_http_headers.py b/pandas/tests/io/test_http_headers.py index 2ca11ad1..fe4dd24d 100644 --- a/pandas/tests/io/test_http_headers.py +++ b/pandas/tests/io/test_http_headers.py @@ -161,7 +161,7 @@ def test_to_parquet_to_disk_with_storage_options(engine): "Auth": "other_custom", } - pytest.importorskip(engine) + td.versioned_importorskip(engine) true_df = pd.DataFrame({"column_name": ["column_value"]}) msg = ( diff --git a/pandas/tests/io/test_orc.py b/pandas/tests/io/test_orc.py index a4021311..df550376 100644 --- a/pandas/tests/io/test_orc.py +++ b/pandas/tests/io/test_orc.py @@ -8,12 +8,13 @@ import pathlib import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import read_orc import pandas._testing as tm from pandas.core.arrays import StringArray -pytest.importorskip("pyarrow.orc") +td.versioned_importorskip("pyarrow.orc") import pyarrow as pa @@ -248,7 +249,7 @@ def test_orc_reader_snappy_compressed(dirpath): def test_orc_roundtrip_file(dirpath): # GH44554 # PyArrow gained ORC write support with the current argument order - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") data = { "boolean1": np.array([False, True], dtype="bool"), @@ -273,7 +274,7 @@ def test_orc_roundtrip_file(dirpath): def test_orc_roundtrip_bytesio(): # GH44554 # PyArrow gained ORC write support with the current argument order - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") data = { "boolean1": np.array([False, True], dtype="bool"), @@ -297,7 +298,7 @@ def test_orc_roundtrip_bytesio(): def test_orc_writer_dtypes_not_supported(orc_writer_dtypes_not_supported): # GH44554 # PyArrow gained ORC write support with the current argument order - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") msg = "The dtype of one or more columns is not supported yet." with pytest.raises(NotImplementedError, match=msg): @@ -305,7 +306,7 @@ def test_orc_writer_dtypes_not_supported(orc_writer_dtypes_not_supported): def test_orc_dtype_backend_pyarrow(): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame( { "string": list("abc"), @@ -341,7 +342,7 @@ def test_orc_dtype_backend_pyarrow(): def test_orc_dtype_backend_numpy_nullable(): # GH#50503 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame( { "string": list("abc"), diff --git a/pandas/tests/io/test_parquet.py b/pandas/tests/io/test_parquet.py index 760a64c8..3fbd55a7 100644 --- a/pandas/tests/io/test_parquet.py +++ b/pandas/tests/io/test_parquet.py @@ -8,6 +8,7 @@ import pathlib import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._config import using_copy_on_write from pandas._config.config import _get_option @@ -389,7 +390,7 @@ class Base: @pytest.mark.single_cpu def test_parquet_read_from_url(self, httpserver, datapath, df_compat, engine): if engine != "auto": - pytest.importorskip(engine) + td.versioned_importorskip(engine) with open(datapath("io", "data", "parquet", "simple.parquet"), mode="rb") as f: httpserver.serve_content(content=f.read()) df = read_parquet(httpserver.url) @@ -611,7 +612,7 @@ class TestBasic(Base): check_round_trip(df, engine) def test_dtype_backend(self, engine, request): - pq = pytest.importorskip("pyarrow.parquet") + pq = td.versioned_importorskip("pyarrow.parquet") if engine == "fastparquet": # We are manually disabling fastparquet's @@ -799,7 +800,7 @@ class TestParquetPyArrow(Base): @pytest.mark.single_cpu def test_s3_roundtrip_explicit_fs(self, df_compat, s3_public_bucket, pa, s3so): - s3fs = pytest.importorskip("s3fs") + s3fs = td.versioned_importorskip("s3fs") s3 = s3fs.S3FileSystem(**s3so) kw = {"filesystem": s3} check_round_trip( @@ -833,7 +834,7 @@ class TestParquetPyArrow(Base): def test_s3_roundtrip_for_dir( self, df_compat, s3_public_bucket, pa, partition_col, s3so ): - pytest.importorskip("s3fs") + td.versioned_importorskip("s3fs") # GH #26388 expected_df = df_compat.copy() @@ -862,14 +863,14 @@ class TestParquetPyArrow(Base): ) def test_read_file_like_obj_support(self, df_compat): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") buffer = BytesIO() df_compat.to_parquet(buffer) df_from_buf = read_parquet(buffer) tm.assert_frame_equal(df_compat, df_from_buf) def test_expand_user(self, df_compat, monkeypatch): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") monkeypatch.setenv("HOME", "TestingUser") monkeypatch.setenv("USERPROFILE", "TestingUser") with pytest.raises(OSError, match=r".*TestingUser.*"): @@ -924,7 +925,7 @@ class TestParquetPyArrow(Base): def test_additional_extension_arrays(self, pa): # test additional ExtensionArrays that are supported through the # __arrow_array__ protocol - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame( { "a": pd.Series([1, 2, 3], dtype="Int64"), @@ -939,7 +940,7 @@ class TestParquetPyArrow(Base): def test_pyarrow_backed_string_array(self, pa, string_storage): # test ArrowStringArray supported through the __arrow_array__ protocol - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame({"a": pd.Series(["a", None, "c"], dtype="string[pyarrow]")}) with pd.option_context("string_storage", string_storage): check_round_trip(df, pa, expected=df.astype(f"string[{string_storage}]")) @@ -947,7 +948,7 @@ class TestParquetPyArrow(Base): def test_additional_extension_types(self, pa): # test additional ExtensionArrays that are supported through the # __arrow_array__ protocol + by defining a custom ExtensionType - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame( { "c": pd.IntervalIndex.from_tuples([(0, 1), (1, 2), (3, 4)]), @@ -992,7 +993,7 @@ class TestParquetPyArrow(Base): def test_filter_row_groups(self, pa): # https://github.com/pandas-dev/pandas/issues/26551 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame({"a": list(range(3))}) with tm.ensure_clean() as path: df.to_parquet(path, engine=pa) @@ -1349,7 +1350,7 @@ class TestParquetFastParquet(Base): tm.assert_frame_equal(result, df) def test_filesystem_notimplemented(self): - pytest.importorskip("fastparquet") + td.versioned_importorskip("fastparquet") df = pd.DataFrame(data={"A": [0, 1], "B": [1, 0]}) with tm.ensure_clean() as path: with pytest.raises( @@ -1365,7 +1366,7 @@ class TestParquetFastParquet(Base): read_parquet(path, engine="fastparquet", filesystem="foo") def test_invalid_filesystem(self): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = pd.DataFrame(data={"A": [0, 1], "B": [1, 0]}) with tm.ensure_clean() as path: with pytest.raises( @@ -1381,7 +1382,7 @@ class TestParquetFastParquet(Base): read_parquet(path, engine="pyarrow", filesystem="foo") def test_unsupported_pa_filesystem_storage_options(self): - pa_fs = pytest.importorskip("pyarrow.fs") + pa_fs = td.versioned_importorskip("pyarrow.fs") df = pd.DataFrame(data={"A": [0, 1], "B": [1, 0]}) with tm.ensure_clean() as path: with pytest.raises( diff --git a/pandas/tests/io/test_pickle.py b/pandas/tests/io/test_pickle.py index 2347fad8..e4b28cdc 100644 --- a/pandas/tests/io/test_pickle.py +++ b/pandas/tests/io/test_pickle.py @@ -499,7 +499,7 @@ def test_pickle_generalurl_read(monkeypatch, mockurl): def test_pickle_fsspec_roundtrip(): - pytest.importorskip("fsspec") + td.versioned_importorskip("fsspec") with tm.ensure_clean(): mockurl = "memory://mockfile" df = DataFrame( diff --git a/pandas/tests/io/test_s3.py b/pandas/tests/io/test_s3.py index 79473895..4e8113f1 100644 --- a/pandas/tests/io/test_s3.py +++ b/pandas/tests/io/test_s3.py @@ -2,13 +2,14 @@ from io import BytesIO import pytest +import pandas.util._test_decorators as td from pandas import read_csv def test_streaming_s3_objects(): # GH17135 # botocore gained iteration support in 1.10.47, can now be used in read_* - pytest.importorskip("botocore", minversion="1.10.47") + td.versioned_importorskip("botocore", min_version="1.10.47") from botocore.response import StreamingBody data = [b"foo,bar,baz\n1,2,3\n4,5,6\n", b"just,the,header\n"] @@ -20,7 +21,7 @@ def test_streaming_s3_objects(): @pytest.mark.single_cpu def test_read_without_creds_from_pub_bucket(s3_public_bucket_with_data, s3so): # GH 34626 - pytest.importorskip("s3fs") + td.versioned_importorskip("s3fs") result = read_csv( f"s3://{s3_public_bucket_with_data.name}/tips.csv", nrows=3, @@ -33,7 +34,7 @@ def test_read_without_creds_from_pub_bucket(s3_public_bucket_with_data, s3so): def test_read_with_creds_from_pub_bucket(s3_public_bucket_with_data, s3so): # Ensure we can read from a public bucket with credentials # GH 34626 - pytest.importorskip("s3fs") + td.versioned_importorskip("s3fs") df = read_csv( f"s3://{s3_public_bucket_with_data.name}/tips.csv", nrows=5, diff --git a/pandas/tests/io/test_spss.py b/pandas/tests/io/test_spss.py index e118c90d..d4012819 100644 --- a/pandas/tests/io/test_spss.py +++ b/pandas/tests/io/test_spss.py @@ -4,11 +4,12 @@ from pathlib import Path import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm from pandas.util.version import Version -pyreadstat = pytest.importorskip("pyreadstat") +pyreadstat = td.versioned_importorskip("pyreadstat") # TODO(CoW) - detection of chained assignment in cython @@ -101,7 +102,7 @@ def test_spss_umlauts_dtype_backend(datapath, dtype_backend): expected = pd.DataFrame({"var1": [1.0, 2.0, 1.0, 3.0]}, dtype="Int64") if dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray diff --git a/pandas/tests/io/test_sql.py b/pandas/tests/io/test_sql.py index 7068247b..9619aafc 100644 --- a/pandas/tests/io/test_sql.py +++ b/pandas/tests/io/test_sql.py @@ -601,8 +601,8 @@ def drop_view( @pytest.fixture def mysql_pymysql_engine(): - sqlalchemy = pytest.importorskip("sqlalchemy") - pymysql = pytest.importorskip("pymysql") + sqlalchemy = td.versioned_importorskip("sqlalchemy") + pymysql = td.versioned_importorskip("pymysql") engine = sqlalchemy.create_engine( "mysql+pymysql://root@localhost:3306/pandas", connect_args={"client_flag": pymysql.constants.CLIENT.MULTI_STATEMENTS}, @@ -649,8 +649,8 @@ def mysql_pymysql_conn_types(mysql_pymysql_engine_types): @pytest.fixture def postgresql_psycopg2_engine(): - sqlalchemy = pytest.importorskip("sqlalchemy") - pytest.importorskip("psycopg2") + sqlalchemy = td.versioned_importorskip("sqlalchemy") + td.versioned_importorskip("psycopg2") engine = sqlalchemy.create_engine( "postgresql+psycopg2://postgres:postgres@localhost:5432/pandas", poolclass=sqlalchemy.pool.NullPool, @@ -684,7 +684,7 @@ def postgresql_psycopg2_conn(postgresql_psycopg2_engine): @pytest.fixture def postgresql_adbc_conn(): - pytest.importorskip("adbc_driver_postgresql") + td.versioned_importorskip("adbc_driver_postgresql") from adbc_driver_postgresql import dbapi uri = "postgresql://postgres:postgres@localhost:5432/pandas" @@ -747,14 +747,14 @@ def postgresql_psycopg2_conn_types(postgresql_psycopg2_engine_types): @pytest.fixture def sqlite_str(): - pytest.importorskip("sqlalchemy") + td.versioned_importorskip("sqlalchemy") with tm.ensure_clean() as name: yield f"sqlite:///{name}" @pytest.fixture def sqlite_engine(sqlite_str): - sqlalchemy = pytest.importorskip("sqlalchemy") + sqlalchemy = td.versioned_importorskip("sqlalchemy") engine = sqlalchemy.create_engine(sqlite_str, poolclass=sqlalchemy.pool.NullPool) yield engine for view in get_all_views(engine): @@ -772,7 +772,7 @@ def sqlite_conn(sqlite_engine): @pytest.fixture def sqlite_str_iris(sqlite_str, iris_path): - sqlalchemy = pytest.importorskip("sqlalchemy") + sqlalchemy = td.versioned_importorskip("sqlalchemy") engine = sqlalchemy.create_engine(sqlite_str) create_and_load_iris(engine, iris_path) create_and_load_iris_view(engine) @@ -795,7 +795,7 @@ def sqlite_conn_iris(sqlite_engine_iris): @pytest.fixture def sqlite_str_types(sqlite_str, types_data): - sqlalchemy = pytest.importorskip("sqlalchemy") + sqlalchemy = td.versioned_importorskip("sqlalchemy") engine = sqlalchemy.create_engine(sqlite_str) create_and_load_types(engine, types_data, "sqlite") engine.dispose() @@ -816,7 +816,7 @@ def sqlite_conn_types(sqlite_engine_types): @pytest.fixture def sqlite_adbc_conn(): - pytest.importorskip("adbc_driver_sqlite") + td.versioned_importorskip("adbc_driver_sqlite") from adbc_driver_sqlite import dbapi with tm.ensure_clean() as name: @@ -1001,7 +1001,7 @@ def test_dataframe_to_sql_empty(conn, test_frame1, request): @pytest.mark.parametrize("conn", all_connectable) def test_dataframe_to_sql_arrow_dtypes(conn, request): # GH 52046 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( { "int": pd.array([1], dtype="int8[pyarrow]"), @@ -1035,7 +1035,7 @@ def test_dataframe_to_sql_arrow_dtypes(conn, request): @pytest.mark.parametrize("conn", all_connectable) def test_dataframe_to_sql_arrow_dtypes_missing(conn, request, nulls_fixture): # GH 52046 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( { "datetime": pd.array( @@ -2515,7 +2515,7 @@ def test_sqlalchemy_integer_overload_mapping(conn, request, integer): @pytest.mark.parametrize("conn", all_connectable) def test_database_uri_string(conn, request, test_frame1): - pytest.importorskip("sqlalchemy") + td.versioned_importorskip("sqlalchemy") conn = request.getfixturevalue(conn) # Test read_sql and .to_sql method with a database URI (GH10654) # db_uri = 'sqlite:///:memory:' # raises @@ -2537,7 +2537,7 @@ def test_database_uri_string(conn, request, test_frame1): @td.skip_if_installed("pg8000") @pytest.mark.parametrize("conn", all_connectable) def test_pg8000_sqlalchemy_passthrough_error(conn, request): - pytest.importorskip("sqlalchemy") + td.versioned_importorskip("sqlalchemy") conn = request.getfixturevalue(conn) # using driver that will not be installed on CI to trigger error # in sqlalchemy.create_engine -> test passing of this error to user @@ -3414,7 +3414,7 @@ def test_to_sql_with_negative_npinf(conn, request, input): # The input {"foo": [-np.inf], "infe0": ["bar"]} does not raise any error # for pymysql version >= 0.10 # TODO(GH#36465): remove this version check after GH 36465 is fixed - pymysql = pytest.importorskip("pymysql") + pymysql = td.versioned_importorskip("pymysql") if Version(pymysql.__version__) < Version("1.0.3") and "infe0" in df.columns: mark = pytest.mark.xfail(reason="GH 36465") @@ -3529,7 +3529,7 @@ def test_options_auto(conn, request, test_frame1): def test_options_get_engine(): - pytest.importorskip("sqlalchemy") + td.versioned_importorskip("sqlalchemy") assert isinstance(get_engine("sqlalchemy"), SQLAlchemyEngine) with pd.option_context("io.sql.engine", "sqlalchemy"): @@ -3681,14 +3681,14 @@ def dtype_backend_expected(): string_array_na = StringArray(np.array(["a", "b", pd.NA], dtype=np.object_)) elif dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray string_array = ArrowExtensionArray(pa.array(["a", "b", "c"])) # type: ignore[assignment] string_array_na = ArrowExtensionArray(pa.array(["a", "b", None])) # type: ignore[assignment] else: - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") string_array = ArrowStringArray(pa.array(["a", "b", "c"])) string_array_na = ArrowStringArray(pa.array(["a", "b", None])) @@ -3705,7 +3705,7 @@ def dtype_backend_expected(): } ) if dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray @@ -3850,7 +3850,7 @@ def test_row_object_is_named_tuple(sqlite_engine): def test_read_sql_string_inference(sqlite_engine): conn = sqlite_engine # GH#54430 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") table = "test" df = DataFrame({"a": ["x", "y"]}) df.to_sql(table, con=conn, index=False, if_exists="replace") diff --git a/pandas/tests/io/test_stata.py b/pandas/tests/io/test_stata.py index 43febd41..bef0df62 100644 --- a/pandas/tests/io/test_stata.py +++ b/pandas/tests/io/test_stata.py @@ -2045,11 +2045,11 @@ def test_compression(compression, version, use_dict, infer, compression_to_exten with bz2.open(path, "rb") as comp: fp = io.BytesIO(comp.read()) elif compression == "zstd": - zstd = pytest.importorskip("zstandard") + zstd = td.versioned_importorskip("zstandard") with zstd.open(path, "rb") as comp: fp = io.BytesIO(comp.read()) elif compression == "xz": - lzma = pytest.importorskip("lzma") + lzma = td.versioned_importorskip("lzma") with lzma.open(path, "rb") as comp: fp = io.BytesIO(comp.read()) elif compression is None: diff --git a/pandas/tests/io/xml/test_to_xml.py b/pandas/tests/io/xml/test_to_xml.py index 37251a58..69a7d85e 100644 --- a/pandas/tests/io/xml/test_to_xml.py +++ b/pandas/tests/io/xml/test_to_xml.py @@ -867,7 +867,7 @@ def test_encoding_option_str(xml_baby_names, parser): def test_correct_encoding_file(xml_baby_names): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") df_file = read_xml(xml_baby_names, encoding="ISO-8859-1", parser="lxml") with tm.ensure_clean("test.xml") as path: @@ -876,7 +876,7 @@ def test_correct_encoding_file(xml_baby_names): @pytest.mark.parametrize("encoding", ["UTF-8", "UTF-16", "ISO-8859-1"]) def test_wrong_encoding_option_lxml(xml_baby_names, parser, encoding): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") df_file = read_xml(xml_baby_names, encoding="ISO-8859-1", parser="lxml") with tm.ensure_clean("test.xml") as path: @@ -892,7 +892,7 @@ def test_misspelled_encoding(parser, geom_df): def test_xml_declaration_pretty_print(geom_df): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") expected = """\ @@ -1005,7 +1005,7 @@ xsl_expected = """\ def test_stylesheet_file_like(xsl_row_field_output, mode, geom_df): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with open( xsl_row_field_output, mode, encoding="utf-8" if mode == "r" else None ) as f: @@ -1015,7 +1015,7 @@ def test_stylesheet_file_like(xsl_row_field_output, mode, geom_df): def test_stylesheet_io(xsl_row_field_output, mode, geom_df): # note: By default the bodies of untyped functions are not checked, # consider using --check-untyped-defs - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xsl_obj: BytesIO | StringIO # type: ignore[annotation-unchecked] with open( @@ -1032,7 +1032,7 @@ def test_stylesheet_io(xsl_row_field_output, mode, geom_df): def test_stylesheet_buffered_reader(xsl_row_field_output, mode, geom_df): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with open( xsl_row_field_output, mode, encoding="utf-8" if mode == "r" else None ) as f: @@ -1044,7 +1044,7 @@ def test_stylesheet_buffered_reader(xsl_row_field_output, mode, geom_df): def test_stylesheet_wrong_path(geom_df): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") xsl = os.path.join("data", "xml", "row_field_output.xslt") @@ -1057,7 +1057,7 @@ def test_stylesheet_wrong_path(geom_df): @pytest.mark.parametrize("val", ["", b""]) def test_empty_string_stylesheet(val, geom_df): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") msg = "|".join( [ @@ -1073,7 +1073,7 @@ def test_empty_string_stylesheet(val, geom_df): def test_incorrect_xsl_syntax(geom_df): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") xsl = """\ @@ -1103,7 +1103,7 @@ def test_incorrect_xsl_syntax(geom_df): def test_incorrect_xsl_eval(geom_df): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") xsl = """\ @@ -1131,7 +1131,7 @@ def test_incorrect_xsl_eval(geom_df): def test_incorrect_xsl_apply(geom_df): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") xsl = """\ @@ -1169,7 +1169,7 @@ def test_stylesheet_with_etree(geom_df): def test_style_to_csv(geom_df): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xsl = """\ @@ -1198,7 +1198,7 @@ def test_style_to_csv(geom_df): def test_style_to_string(geom_df): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xsl = """\ @@ -1232,7 +1232,7 @@ def test_style_to_string(geom_df): def test_style_to_json(geom_df): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xsl = """\ @@ -1363,8 +1363,8 @@ def test_unsuported_compression(parser, geom_df): @pytest.mark.single_cpu def test_s3_permission_output(parser, s3_public_bucket, geom_df): - s3fs = pytest.importorskip("s3fs") - pytest.importorskip("lxml") + s3fs = td.versioned_importorskip("s3fs") + td.versioned_importorskip("lxml") with tm.external_error_raised((PermissionError, FileNotFoundError)): fs = s3fs.S3FileSystem(anon=True) diff --git a/pandas/tests/io/xml/test_xml.py b/pandas/tests/io/xml/test_xml.py index e40b7a51..dbd05e46 100644 --- a/pandas/tests/io/xml/test_xml.py +++ b/pandas/tests/io/xml/test_xml.py @@ -249,7 +249,7 @@ df_kml = DataFrame( def test_literal_xml_deprecation(): # GH 53809 - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") msg = ( "Passing literal xml to 'read_xml' is deprecated and " "will be removed in a future version. To read from a " @@ -289,7 +289,7 @@ def read_xml_iterparse_comp(comp_path, compression_only, **kwargs): def test_parser_consistency_file(xml_books): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") df_file_lxml = read_xml(xml_books, parser="lxml") df_file_etree = read_xml(xml_books, parser="etree") @@ -462,7 +462,7 @@ def test_file_handle_close(xml_books, parser): @pytest.mark.parametrize("val", ["", b""]) def test_empty_string_lxml(val): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") msg = "|".join( [ @@ -505,7 +505,7 @@ def test_wrong_file_path(parser, datapath): @pytest.mark.network @pytest.mark.single_cpu def test_url(httpserver, xml_file): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with open(xml_file, encoding="utf-8") as f: httpserver.serve_content(content=f.read()) df_url = read_xml(httpserver.url, xpath=".//book[count(*)=4]") @@ -587,7 +587,7 @@ def test_whitespace(parser): def test_empty_xpath_lxml(xml_books): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with pytest.raises(ValueError, match=("xpath does not return any nodes")): read_xml(xml_books, xpath=".//python", parser="lxml") @@ -600,7 +600,7 @@ def test_bad_xpath_etree(xml_books): def test_bad_xpath_lxml(xml_books): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") with pytest.raises(lxml_etree.XPathEvalError, match=("Invalid expression")): read_xml(xml_books, xpath=".//[book]", parser="lxml") @@ -659,7 +659,7 @@ def test_prefix_namespace(parser): def test_consistency_default_namespace(): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") df_lxml = read_xml( StringIO(xml_default_nmsp), xpath=".//ns:row", @@ -678,7 +678,7 @@ def test_consistency_default_namespace(): def test_consistency_prefix_namespace(): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") df_lxml = read_xml( StringIO(xml_prefix_nmsp), xpath=".//doc:row", @@ -710,7 +710,7 @@ def test_missing_prefix_definition_etree(kml_cta_rail_lines): def test_missing_prefix_definition_lxml(kml_cta_rail_lines): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") with pytest.raises(lxml_etree.XPathEvalError, match=("Undefined namespace prefix")): read_xml(kml_cta_rail_lines, xpath=".//kml:Placemark", parser="lxml") @@ -718,7 +718,7 @@ def test_missing_prefix_definition_lxml(kml_cta_rail_lines): @pytest.mark.parametrize("key", ["", None]) def test_none_namespace_prefix(key): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with pytest.raises( TypeError, match=("empty namespace prefix is not supported in XPath") ): @@ -831,7 +831,7 @@ def test_empty_elems_only(parser): def test_attribute_centric_xml(): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xml = """\ @@ -1061,7 +1061,7 @@ def test_ascii_encoding(xml_baby_names, parser): def test_parser_consistency_with_encoding(xml_baby_names): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") df_xpath_lxml = read_xml(xml_baby_names, parser="lxml", encoding="ISO-8859-1") df_xpath_etree = read_xml(xml_baby_names, parser="etree", encoding="iso-8859-1") @@ -1084,7 +1084,7 @@ def test_parser_consistency_with_encoding(xml_baby_names): def test_wrong_encoding_for_lxml(): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") # GH#45133 data = """ @@ -1131,7 +1131,7 @@ def test_wrong_parser(xml_books): def test_stylesheet_file(kml_cta_rail_lines, xsl_flatten_doc): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") df_style = read_xml( kml_cta_rail_lines, xpath=".//k:Placemark", @@ -1158,7 +1158,7 @@ def test_stylesheet_file(kml_cta_rail_lines, xsl_flatten_doc): def test_stylesheet_file_like(kml_cta_rail_lines, xsl_flatten_doc, mode): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with open(xsl_flatten_doc, mode, encoding="utf-8" if mode == "r" else None) as f: df_style = read_xml( kml_cta_rail_lines, @@ -1173,7 +1173,7 @@ def test_stylesheet_file_like(kml_cta_rail_lines, xsl_flatten_doc, mode): def test_stylesheet_io(kml_cta_rail_lines, xsl_flatten_doc, mode): # note: By default the bodies of untyped functions are not checked, # consider using --check-untyped-defs - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xsl_obj: BytesIO | StringIO # type: ignore[annotation-unchecked] with open(xsl_flatten_doc, mode, encoding="utf-8" if mode == "r" else None) as f: @@ -1193,7 +1193,7 @@ def test_stylesheet_io(kml_cta_rail_lines, xsl_flatten_doc, mode): def test_stylesheet_buffered_reader(kml_cta_rail_lines, xsl_flatten_doc, mode): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with open(xsl_flatten_doc, mode, encoding="utf-8" if mode == "r" else None) as f: xsl_obj = f.read() @@ -1208,7 +1208,7 @@ def test_stylesheet_buffered_reader(kml_cta_rail_lines, xsl_flatten_doc, mode): def test_style_charset(): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xml = "<中文標籤>12" xsl = """\ @@ -1237,7 +1237,7 @@ def test_style_charset(): def test_not_stylesheet(kml_cta_rail_lines, xml_books): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") with pytest.raises( lxml_etree.XSLTParseError, match=("document is not a stylesheet") @@ -1246,7 +1246,7 @@ def test_not_stylesheet(kml_cta_rail_lines, xml_books): def test_incorrect_xsl_syntax(kml_cta_rail_lines): - lxml_etree = pytest.importorskip("lxml.etree") + lxml_etree = td.versioned_importorskip("lxml.etree") xsl = """\ @@ -1321,7 +1321,7 @@ def test_incorrect_xsl_apply(kml_cta_rail_lines): def test_wrong_stylesheet(kml_cta_rail_lines, xml_data_path): - xml_etree = pytest.importorskip("lxml.etree") + xml_etree = td.versioned_importorskip("lxml.etree") xsl = xml_data_path / "flatten.xsl" @@ -1335,7 +1335,7 @@ def test_wrong_stylesheet(kml_cta_rail_lines, xml_data_path): def test_stylesheet_file_close(kml_cta_rail_lines, xsl_flatten_doc, mode): # note: By default the bodies of untyped functions are not checked, # consider using --check-untyped-defs - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xsl_obj: BytesIO | StringIO # type: ignore[annotation-unchecked] with open(xsl_flatten_doc, mode, encoding="utf-8" if mode == "r" else None) as f: @@ -1350,7 +1350,7 @@ def test_stylesheet_file_close(kml_cta_rail_lines, xsl_flatten_doc, mode): def test_stylesheet_with_etree(kml_cta_rail_lines, xsl_flatten_doc): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") with pytest.raises( ValueError, match=("To use stylesheet, you need lxml installed") ): @@ -1359,7 +1359,7 @@ def test_stylesheet_with_etree(kml_cta_rail_lines, xsl_flatten_doc): @pytest.mark.parametrize("val", ["", b""]) def test_empty_stylesheet(val, datapath): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") msg = ( "Passing literal xml to 'read_xml' is deprecated and " "will be removed in a future version. To read from a " @@ -1662,7 +1662,7 @@ def test_empty_data(xml_books, parser): def test_online_stylesheet(): - pytest.importorskip("lxml") + td.versioned_importorskip("lxml") xml = """\ @@ -1993,8 +1993,8 @@ def test_unsuported_compression(parser): @pytest.mark.network @pytest.mark.single_cpu def test_s3_parser_consistency(s3_public_bucket_with_data, s3so): - pytest.importorskip("s3fs") - pytest.importorskip("lxml") + td.versioned_importorskip("s3fs") + td.versioned_importorskip("lxml") s3 = f"s3://{s3_public_bucket_with_data.name}/books.xml" df_lxml = read_xml(s3, parser="lxml", storage_options=s3so) @@ -2035,7 +2035,7 @@ def test_read_xml_nullable_dtypes( """ if using_infer_string: - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") string_array = ArrowStringArrayNumpySemantics(pa.array(["x", "y"])) string_array_na = ArrowStringArrayNumpySemantics(pa.array(["x", None])) @@ -2044,14 +2044,14 @@ def test_read_xml_nullable_dtypes( string_array_na = StringArray(np.array(["x", NA], dtype=np.object_)) elif dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray string_array = ArrowExtensionArray(pa.array(["x", "y"])) string_array_na = ArrowExtensionArray(pa.array(["x", None])) else: - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") string_array = ArrowStringArray(pa.array(["x", "y"])) string_array_na = ArrowStringArray(pa.array(["x", None])) @@ -2073,7 +2073,7 @@ def test_read_xml_nullable_dtypes( ) if dtype_backend == "pyarrow": - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") from pandas.arrays import ArrowExtensionArray expected = DataFrame( diff --git a/pandas/tests/plotting/conftest.py b/pandas/tests/plotting/conftest.py index d688bbd4..174c5d1e 100644 --- a/pandas/tests/plotting/conftest.py +++ b/pandas/tests/plotting/conftest.py @@ -3,6 +3,7 @@ import gc import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, to_datetime, @@ -15,9 +16,9 @@ def mpl_cleanup(): # 1) Resets units registry # 2) Resets rc_context # 3) Closes all figures - mpl = pytest.importorskip("matplotlib") - mpl_units = pytest.importorskip("matplotlib.units") - plt = pytest.importorskip("matplotlib.pyplot") + mpl = td.versioned_importorskip("matplotlib") + mpl_units = td.versioned_importorskip("matplotlib.units") + plt = td.versioned_importorskip("matplotlib.pyplot") orig_units_registry = mpl_units.registry.copy() with mpl.rc_context(): mpl.use("template") diff --git a/pandas/tests/plotting/frame/test_frame.py b/pandas/tests/plotting/frame/test_frame.py index 4ca40672..158c9f63 100644 --- a/pandas/tests/plotting/frame/test_frame.py +++ b/pandas/tests/plotting/frame/test_frame.py @@ -48,8 +48,8 @@ from pandas.util.version import Version from pandas.io.formats.printing import pprint_thing -mpl = pytest.importorskip("matplotlib") -plt = pytest.importorskip("matplotlib.pyplot") +mpl = td.versioned_importorskip("matplotlib") +plt = td.versioned_importorskip("matplotlib.pyplot") class TestDataFramePlots: @@ -1119,7 +1119,7 @@ class TestDataFramePlots: _check_box_return_type(result, return_type) def test_kde_df(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((100, 4))) ax = _check_plot_works(df.plot, kind="kde") expected = [pprint_thing(c) for c in df.columns] @@ -1127,13 +1127,13 @@ class TestDataFramePlots: _check_ticks_props(ax, xrot=0) def test_kde_df_rot(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((10, 4))) ax = df.plot(kind="kde", rot=20, fontsize=5) _check_ticks_props(ax, xrot=20, xlabelsize=5, ylabelsize=5) def test_kde_df_subplots(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((10, 4))) axes = _check_plot_works( df.plot, @@ -1144,13 +1144,13 @@ class TestDataFramePlots: _check_axes_shape(axes, axes_num=4, layout=(4, 1)) def test_kde_df_logy(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((10, 4))) axes = df.plot(kind="kde", logy=True, subplots=True) _check_ax_scales(axes, yaxis="log") def test_kde_missing_vals(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).uniform(size=(100, 4))) df.loc[0, 0] = np.nan _check_plot_works(df.plot, kind="kde") @@ -1447,14 +1447,14 @@ class TestDataFramePlots: @pytest.mark.parametrize("kind", plotting.PlotAccessor._common_kinds) def test_kind_both_ways(self, kind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame({"x": [1, 2, 3]}) df.plot(kind=kind) getattr(df.plot, kind)() @pytest.mark.parametrize("kind", ["scatter", "hexbin"]) def test_kind_both_ways_x_y(self, kind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame({"x": [1, 2, 3]}) df.plot("x", "x", kind=kind) getattr(df.plot, kind)("x", "x") @@ -2100,7 +2100,7 @@ class TestDataFramePlots: @pytest.mark.parametrize("kind", plotting.PlotAccessor._all_kinds) def test_memory_leak(self, kind): """Check that every plot type gets properly collected.""" - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") args = {} if kind in ["hexbin", "scatter", "pie"]: df = DataFrame( @@ -2427,7 +2427,7 @@ class TestDataFramePlots: "kind", ("line", "bar", "barh", "hist", "kde", "density", "area", "pie") ) def test_group_subplot(self, kind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") d = { "a": np.arange(10), "b": np.arange(10) + 1, diff --git a/pandas/tests/plotting/frame/test_frame_color.py b/pandas/tests/plotting/frame/test_frame_color.py index ff1edd32..5c94c217 100644 --- a/pandas/tests/plotting/frame/test_frame_color.py +++ b/pandas/tests/plotting/frame/test_frame_color.py @@ -4,6 +4,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import DataFrame import pandas._testing as tm @@ -14,9 +15,9 @@ from pandas.tests.plotting.common import ( ) from pandas.util.version import Version -mpl = pytest.importorskip("matplotlib") -plt = pytest.importorskip("matplotlib.pyplot") -cm = pytest.importorskip("matplotlib.cm") +mpl = td.versioned_importorskip("matplotlib") +plt = td.versioned_importorskip("matplotlib.pyplot") +cm = td.versioned_importorskip("matplotlib.cm") def _check_colors_box(bp, box_c, whiskers_c, medians_c, caps_c="k", fliers_c=None): @@ -446,7 +447,7 @@ class TestDataFrameColor: _check_colors(ax.patches[::10], facecolors=["green"] * 5) def test_kde_colors(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") custom_colors = "rgcby" df = DataFrame(np.random.default_rng(2).random((5, 5))) @@ -455,14 +456,14 @@ class TestDataFrameColor: @pytest.mark.parametrize("colormap", ["jet", cm.jet]) def test_kde_colors_cmap(self, colormap): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) ax = df.plot.kde(colormap=colormap) rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] _check_colors(ax.get_lines(), linecolors=rgba_colors) def test_kde_colors_and_styles_subplots(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") default_colors = _unpack_cycler(mpl.pyplot.rcParams) df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) @@ -473,14 +474,14 @@ class TestDataFrameColor: @pytest.mark.parametrize("colormap", ["k", "red"]) def test_kde_colors_and_styles_subplots_single_col_str(self, colormap): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) axes = df.plot(kind="kde", color=colormap, subplots=True) for ax in axes: _check_colors(ax.get_lines(), linecolors=[colormap]) def test_kde_colors_and_styles_subplots_custom_color(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) custom_colors = "rgcby" axes = df.plot(kind="kde", color=custom_colors, subplots=True) @@ -489,7 +490,7 @@ class TestDataFrameColor: @pytest.mark.parametrize("colormap", ["jet", cm.jet]) def test_kde_colors_and_styles_subplots_cmap(self, colormap): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) rgba_colors = [cm.jet(n) for n in np.linspace(0, 1, len(df))] axes = df.plot(kind="kde", colormap=colormap, subplots=True) @@ -497,7 +498,7 @@ class TestDataFrameColor: _check_colors(ax.get_lines(), linecolors=[c]) def test_kde_colors_and_styles_subplots_single_col(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) # make color a list if plotting one column frame # handles cases like df.plot(color='DodgerBlue') @@ -505,7 +506,7 @@ class TestDataFrameColor: _check_colors(axes[0].lines, linecolors=["DodgerBlue"]) def test_kde_colors_and_styles_subplots_single_char(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) # list of styles # single character style @@ -514,7 +515,7 @@ class TestDataFrameColor: _check_colors(ax.get_lines(), linecolors=["r"]) def test_kde_colors_and_styles_subplots_list(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).standard_normal((5, 5))) # list of styles styles = list("rgcby") diff --git a/pandas/tests/plotting/frame/test_frame_groupby.py b/pandas/tests/plotting/frame/test_frame_groupby.py index f1924185..644ce2bb 100644 --- a/pandas/tests/plotting/frame/test_frame_groupby.py +++ b/pandas/tests/plotting/frame/test_frame_groupby.py @@ -2,10 +2,11 @@ import pytest +import pandas.util._test_decorators as td from pandas import DataFrame from pandas.tests.plotting.common import _check_visible -pytest.importorskip("matplotlib") +td.versioned_importorskip("matplotlib") class TestDataFramePlotsGroupby: diff --git a/pandas/tests/plotting/frame/test_frame_legend.py b/pandas/tests/plotting/frame/test_frame_legend.py index 402a4b95..bb464624 100644 --- a/pandas/tests/plotting/frame/test_frame_legend.py +++ b/pandas/tests/plotting/frame/test_frame_legend.py @@ -14,7 +14,7 @@ from pandas.tests.plotting.common import ( ) from pandas.util.version import Version -mpl = pytest.importorskip("matplotlib") +mpl = td.versioned_importorskip("matplotlib") class TestFrameLegend: @@ -61,7 +61,7 @@ class TestFrameLegend: @pytest.mark.parametrize("kind", ["line", "bar", "barh", "kde", "area", "hist"]) def test_df_legend_labels(self, kind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).random((3, 3)), columns=["a", "b", "c"]) df2 = DataFrame( np.random.default_rng(2).random((3, 3)), columns=["d", "e", "f"] @@ -87,7 +87,7 @@ class TestFrameLegend: _check_legend_labels(ax, labels=expected) def test_df_legend_labels_secondary_y(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame(np.random.default_rng(2).random((3, 3)), columns=["a", "b", "c"]) df2 = DataFrame( np.random.default_rng(2).random((3, 3)), columns=["d", "e", "f"] @@ -105,7 +105,7 @@ class TestFrameLegend: def test_df_legend_labels_time_series(self): # Time Series - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ind = date_range("1/1/2014", periods=3) df = DataFrame( np.random.default_rng(2).standard_normal((3, 3)), @@ -131,7 +131,7 @@ class TestFrameLegend: def test_df_legend_labels_time_series_scatter(self): # Time Series - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ind = date_range("1/1/2014", periods=3) df = DataFrame( np.random.default_rng(2).standard_normal((3, 3)), @@ -157,7 +157,7 @@ class TestFrameLegend: _check_legend_labels(ax, labels=["data1", "data3"]) def test_df_legend_labels_time_series_no_mutate(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ind = date_range("1/1/2014", periods=3) df = DataFrame( np.random.default_rng(2).standard_normal((3, 3)), diff --git a/pandas/tests/plotting/frame/test_frame_subplots.py b/pandas/tests/plotting/frame/test_frame_subplots.py index 46b9cea2..a7de569d 100644 --- a/pandas/tests/plotting/frame/test_frame_subplots.py +++ b/pandas/tests/plotting/frame/test_frame_subplots.py @@ -6,6 +6,7 @@ import numpy as np from numpy.testing import assert_array_almost_equal_nulp import pytest +import pandas.util._test_decorators as td from pandas.compat import is_platform_linux from pandas.compat.numpy import np_version_gte1p24 @@ -27,8 +28,8 @@ from pandas.tests.plotting.common import ( from pandas.io.formats.printing import pprint_thing -mpl = pytest.importorskip("matplotlib") -plt = pytest.importorskip("matplotlib.pyplot") +mpl = td.versioned_importorskip("matplotlib") +plt = td.versioned_importorskip("matplotlib.pyplot") class TestDataFramePlotsSubplots: diff --git a/pandas/tests/plotting/frame/test_hist_box_by.py b/pandas/tests/plotting/frame/test_hist_box_by.py index a9250fa8..e8afa0e2 100644 --- a/pandas/tests/plotting/frame/test_hist_box_by.py +++ b/pandas/tests/plotting/frame/test_hist_box_by.py @@ -3,6 +3,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import DataFrame import pandas._testing as tm from pandas.tests.plotting.common import ( @@ -12,7 +13,7 @@ from pandas.tests.plotting.common import ( get_y_axis, ) -pytest.importorskip("matplotlib") +td.versioned_importorskip("matplotlib") @pytest.fixture diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 76f7fa1f..580da287 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -6,6 +6,7 @@ import string import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, MultiIndex, @@ -25,8 +26,8 @@ from pandas.tests.plotting.common import ( from pandas.io.formats.printing import pprint_thing -mpl = pytest.importorskip("matplotlib") -plt = pytest.importorskip("matplotlib.pyplot") +mpl = td.versioned_importorskip("matplotlib") +plt = td.versioned_importorskip("matplotlib.pyplot") def _check_ax_limits(col, ax): diff --git a/pandas/tests/plotting/test_common.py b/pandas/tests/plotting/test_common.py index 20daf593..8d58408a 100644 --- a/pandas/tests/plotting/test_common.py +++ b/pandas/tests/plotting/test_common.py @@ -1,5 +1,6 @@ import pytest +import pandas.util._test_decorators as td from pandas import DataFrame from pandas.tests.plotting.common import ( _check_plot_works, @@ -7,7 +8,7 @@ from pandas.tests.plotting.common import ( _gen_two_subplots, ) -plt = pytest.importorskip("matplotlib.pyplot") +plt = td.versioned_importorskip("matplotlib.pyplot") class TestCommon: diff --git a/pandas/tests/plotting/test_converter.py b/pandas/tests/plotting/test_converter.py index f748d7c5..69784259 100644 --- a/pandas/tests/plotting/test_converter.py +++ b/pandas/tests/plotting/test_converter.py @@ -8,6 +8,7 @@ import sys import numpy as np import pytest +import pandas.util._test_decorators as td import pandas._config.config as cf from pandas._libs.tslibs import to_offset @@ -41,8 +42,8 @@ except ImportError: # causing an improper skip pass -pytest.importorskip("matplotlib.pyplot") -dates = pytest.importorskip("matplotlib.dates") +td.versioned_importorskip("matplotlib.pyplot") +dates = td.versioned_importorskip("matplotlib.dates") @pytest.mark.single_cpu @@ -79,7 +80,7 @@ class TestRegistration: assert subprocess.check_call(call) == 0 def test_registering_no_warning(self): - plt = pytest.importorskip("matplotlib.pyplot") + plt = td.versioned_importorskip("matplotlib.pyplot") s = Series(range(12), index=date_range("2017", periods=12)) _, ax = plt.subplots() @@ -89,7 +90,7 @@ class TestRegistration: plt.close() def test_pandas_plots_register(self): - plt = pytest.importorskip("matplotlib.pyplot") + plt = td.versioned_importorskip("matplotlib.pyplot") s = Series(range(12), index=date_range("2017", periods=12)) # Set to the "warn" state, in case this isn't the first test run with tm.assert_produces_warning(None) as w: @@ -101,7 +102,7 @@ class TestRegistration: plt.close() def test_matplotlib_formatters(self): - units = pytest.importorskip("matplotlib.units") + units = td.versioned_importorskip("matplotlib.units") # Can't make any assertion about the start state. # We we check that toggling converters off removes it, and toggling it @@ -113,9 +114,9 @@ class TestRegistration: assert Timestamp in units.registry def test_option_no_warning(self): - pytest.importorskip("matplotlib.pyplot") + td.versioned_importorskip("matplotlib.pyplot") ctx = cf.option_context("plotting.matplotlib.register_converters", False) - plt = pytest.importorskip("matplotlib.pyplot") + plt = td.versioned_importorskip("matplotlib.pyplot") s = Series(range(12), index=date_range("2017", periods=12)) _, ax = plt.subplots() @@ -130,8 +131,8 @@ class TestRegistration: plt.close() def test_registry_resets(self): - units = pytest.importorskip("matplotlib.units") - dates = pytest.importorskip("matplotlib.dates") + units = td.versioned_importorskip("matplotlib.units") + dates = td.versioned_importorskip("matplotlib.dates") # make a copy, to reset to original = dict(units.registry) diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index 6c318402..65bb6354 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -10,6 +10,7 @@ import pickle import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs.tslibs import ( BaseOffset, to_offset, @@ -41,7 +42,7 @@ from pandas.tests.plotting.common import _check_ticks_props from pandas.tseries.offsets import WeekOfMonth -mpl = pytest.importorskip("matplotlib") +mpl = td.versioned_importorskip("matplotlib") class TestTSPlot: @@ -737,7 +738,7 @@ class TestTSPlot: assert ax.get_yaxis().get_visible() def test_secondary_kde(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ser = Series(np.random.default_rng(2).standard_normal(10)) fig, ax = mpl.pyplot.subplots() ax = ser.plot(secondary_y=True, kind="density", ax=ax) diff --git a/pandas/tests/plotting/test_groupby.py b/pandas/tests/plotting/test_groupby.py index 5ebf9351..ad901abb 100644 --- a/pandas/tests/plotting/test_groupby.py +++ b/pandas/tests/plotting/test_groupby.py @@ -4,6 +4,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Index, @@ -14,7 +15,7 @@ from pandas.tests.plotting.common import ( _check_legend_labels, ) -pytest.importorskip("matplotlib") +td.versioned_importorskip("matplotlib") class TestDataFrameGroupByPlots: diff --git a/pandas/tests/plotting/test_hist_method.py b/pandas/tests/plotting/test_hist_method.py index 4d17f87f..773bc762 100644 --- a/pandas/tests/plotting/test_hist_method.py +++ b/pandas/tests/plotting/test_hist_method.py @@ -4,6 +4,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Index, @@ -25,7 +26,7 @@ from pandas.tests.plotting.common import ( get_y_axis, ) -mpl = pytest.importorskip("matplotlib") +mpl = td.versioned_importorskip("matplotlib") @pytest.fixture @@ -206,7 +207,7 @@ class TestSeriesPlots: @pytest.mark.xfail(reason="Api changed in 3.6.0") def test_hist_kde(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _, ax = mpl.pyplot.subplots() ax = ts.plot.hist(logy=True, ax=ax) _check_ax_scales(ax, yaxis="log") @@ -217,16 +218,16 @@ class TestSeriesPlots: _check_text_labels(ylabels, [""] * len(ylabels)) def test_hist_kde_plot_works(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _check_plot_works(ts.plot.kde) def test_hist_kde_density_works(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _check_plot_works(ts.plot.density) @pytest.mark.xfail(reason="Api changed in 3.6.0") def test_hist_kde_logy(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _, ax = mpl.pyplot.subplots() ax = ts.plot.kde(logy=True, ax=ax) _check_ax_scales(ax, yaxis="log") @@ -236,7 +237,7 @@ class TestSeriesPlots: _check_text_labels(ylabels, [""] * len(ylabels)) def test_hist_kde_color_bins(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _, ax = mpl.pyplot.subplots() ax = ts.plot.hist(logy=True, bins=10, color="b", ax=ax) _check_ax_scales(ax, yaxis="log") @@ -244,7 +245,7 @@ class TestSeriesPlots: _check_colors(ax.patches, facecolors=["b"] * 10) def test_hist_kde_color(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _, ax = mpl.pyplot.subplots() ax = ts.plot.kde(logy=True, color="r", ax=ax) _check_ax_scales(ax, yaxis="log") @@ -631,7 +632,7 @@ class TestDataFramePlots: def test_hist_with_nans_and_weights(self): # GH 48884 - mpl_patches = pytest.importorskip("matplotlib.patches") + mpl_patches = td.versioned_importorskip("matplotlib.patches") df = DataFrame( [[np.nan, 0.2, 0.3], [0.4, np.nan, np.nan], [0.7, 0.8, 0.9]], columns=list("abc"), diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py index cfb657c2..b98663c6 100644 --- a/pandas/tests/plotting/test_misc.py +++ b/pandas/tests/plotting/test_misc.py @@ -26,9 +26,9 @@ from pandas.tests.plotting.common import ( _check_ticks_props, ) -mpl = pytest.importorskip("matplotlib") -plt = pytest.importorskip("matplotlib.pyplot") -cm = pytest.importorskip("matplotlib.cm") +mpl = td.versioned_importorskip("matplotlib") +plt = td.versioned_importorskip("matplotlib.pyplot") +cm = td.versioned_importorskip("matplotlib.cm") @pytest.fixture @@ -148,7 +148,7 @@ class TestSeriesPlots: class TestDataFramePlots: @pytest.mark.parametrize("pass_axis", [False, True]) def test_scatter_matrix_axis(self, pass_axis): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") scatter_matrix = plotting.scatter_matrix ax = None @@ -173,7 +173,7 @@ class TestDataFramePlots: @pytest.mark.parametrize("pass_axis", [False, True]) def test_scatter_matrix_axis_smaller(self, pass_axis): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") scatter_matrix = plotting.scatter_matrix ax = None diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 2b2f2f3b..4aac755a 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -32,8 +32,8 @@ from pandas.tests.plotting.common import ( get_y_axis, ) -mpl = pytest.importorskip("matplotlib") -plt = pytest.importorskip("matplotlib.pyplot") +mpl = td.versioned_importorskip("matplotlib") +plt = td.versioned_importorskip("matplotlib.pyplot") @pytest.fixture @@ -569,16 +569,16 @@ class TestSeriesPlots: ], ) def test_kde_kwargs(self, ts, bw_method, ind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _check_plot_works(ts.plot.kde, bw_method=bw_method, ind=ind) def test_density_kwargs(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") sample_points = np.linspace(-100, 100, 20) _check_plot_works(ts.plot.density, bw_method=0.5, ind=sample_points) def test_kde_kwargs_check_axes(self, ts): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _, ax = mpl.pyplot.subplots() sample_points = np.linspace(-100, 100, 20) ax = ts.plot.kde(logy=True, bw_method=0.5, ind=sample_points, ax=ax) @@ -586,7 +586,7 @@ class TestSeriesPlots: _check_text_labels(ax.yaxis.get_label(), "Density") def test_kde_missing_vals(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series(np.random.default_rng(2).uniform(size=50)) s[0] = np.nan axes = _check_plot_works(s.plot.kde) @@ -609,7 +609,7 @@ class TestSeriesPlots: plotting.PlotAccessor._common_kinds + plotting.PlotAccessor._series_kinds, ) def test_kind_kwarg(self, kind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series(range(3)) _, ax = mpl.pyplot.subplots() s.plot(kind=kind, ax=ax) @@ -620,7 +620,7 @@ class TestSeriesPlots: plotting.PlotAccessor._common_kinds + plotting.PlotAccessor._series_kinds, ) def test_kind_attr(self, kind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series(range(3)) _, ax = mpl.pyplot.subplots() getattr(s.plot, kind)() @@ -636,7 +636,7 @@ class TestSeriesPlots: @pytest.mark.parametrize("kind", plotting.PlotAccessor._common_kinds) def test_valid_object_plot(self, kind): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series(range(10), dtype=object) _check_plot_works(s.plot, kind=kind) @@ -750,7 +750,7 @@ class TestSeriesPlots: @pytest.mark.slow def test_series_grid_settings(self): # Make sure plot defaults to rcParams['axes.grid'] setting, GH 9792 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") _check_grid_settings( Series([1, 2, 3]), plotting.PlotAccessor._series_kinds + plotting.PlotAccessor._common_kinds, diff --git a/pandas/tests/plotting/test_style.py b/pandas/tests/plotting/test_style.py index 665bda15..6c64e46d 100644 --- a/pandas/tests/plotting/test_style.py +++ b/pandas/tests/plotting/test_style.py @@ -1,8 +1,9 @@ import pytest +import pandas.util._test_decorators as td from pandas import Series -pytest.importorskip("matplotlib") +td.versioned_importorskip("matplotlib") from pandas.plotting._matplotlib.style import get_standard_colors diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py index 30ec0d0a..5547f25e 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -7,6 +7,7 @@ from decimal import Decimal import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( Categorical, @@ -1091,7 +1092,7 @@ class TestSeriesReductions: def test_any_all_pyarrow_string(self): # GH#54591 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series(["", "a"], dtype="string[pyarrow_numpy]") assert ser.any() assert not ser.all() diff --git a/pandas/tests/reductions/test_stat_reductions.py b/pandas/tests/reductions/test_stat_reductions.py index 8fbb7873..44a01205 100644 --- a/pandas/tests/reductions/test_stat_reductions.py +++ b/pandas/tests/reductions/test_stat_reductions.py @@ -6,6 +6,7 @@ import inspect import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -231,7 +232,7 @@ class TestSeriesStatReductions: assert pd.isna(result) def test_skew(self): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") string_series = Series(range(20), dtype=np.float64, name="series") @@ -253,7 +254,7 @@ class TestSeriesStatReductions: assert (df.skew() == 0).all() def test_kurt(self): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") string_series = Series(range(20), dtype=np.float64, name="series") diff --git a/pandas/tests/resample/test_datetime_index.py b/pandas/tests/resample/test_datetime_index.py index ddd81ab1..efcfb916 100644 --- a/pandas/tests/resample/test_datetime_index.py +++ b/pandas/tests/resample/test_datetime_index.py @@ -1110,7 +1110,7 @@ def test_resample_dtype_preservation(unit): def test_resample_dtype_coercion(unit): - pytest.importorskip("scipy.interpolate") + td.versioned_importorskip("scipy.interpolate") # GH 16361 df = {"a": [1, 3, 1, 4]} diff --git a/pandas/tests/reshape/merge/test_merge.py b/pandas/tests/reshape/merge/test_merge.py index ed49f3b7..71ba6d80 100644 --- a/pandas/tests/reshape/merge/test_merge.py +++ b/pandas/tests/reshape/merge/test_merge.py @@ -8,6 +8,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.core.dtypes.common import ( is_object_dtype, is_string_dtype, @@ -2817,7 +2818,7 @@ def test_merge_ea_and_non_ea(any_numeric_ea_dtype, join_type): @pytest.mark.parametrize("dtype", ["int64", "int64[pyarrow]"]) def test_merge_arrow_and_numpy_dtypes(dtype): # GH#52406 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame({"a": [1, 2]}, dtype=dtype) df2 = DataFrame({"a": [1, 2]}, dtype="int64[pyarrow]") result = df.merge(df2) @@ -2967,7 +2968,7 @@ def test_merge_ea_int_and_float_numpy(): def test_merge_arrow_string_index(any_string_dtype): # GH#54894 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") left = DataFrame({"a": ["a", "b"]}, dtype=any_string_dtype) right = DataFrame({"b": 1}, index=Index(["a", "c"], dtype=any_string_dtype)) result = left.merge(right, left_on="a", right_index=True, how="left") diff --git a/pandas/tests/reshape/test_melt.py b/pandas/tests/reshape/test_melt.py index 272c5b34..5320ffc7 100644 --- a/pandas/tests/reshape/test_melt.py +++ b/pandas/tests/reshape/test_melt.py @@ -3,6 +3,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -1224,7 +1225,7 @@ class TestWideToLong: def test_wide_to_long_pyarrow_string_columns(): # GH 57066 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") df = DataFrame( { "ID": {0: 1}, diff --git a/pandas/tests/series/accessors/test_list_accessor.py b/pandas/tests/series/accessors/test_list_accessor.py index 1c60567c..77435d5d 100644 --- a/pandas/tests/series/accessors/test_list_accessor.py +++ b/pandas/tests/series/accessors/test_list_accessor.py @@ -2,13 +2,14 @@ import re import pytest +import pandas.util._test_decorators as td from pandas import ( ArrowDtype, Series, ) import pandas._testing as tm -pa = pytest.importorskip("pyarrow") +pa = td.versioned_importorskip("pyarrow") from pandas.compat import pa_version_under11p0 diff --git a/pandas/tests/series/accessors/test_struct_accessor.py b/pandas/tests/series/accessors/test_struct_accessor.py index 80aea75f..5d4fcf45 100644 --- a/pandas/tests/series/accessors/test_struct_accessor.py +++ b/pandas/tests/series/accessors/test_struct_accessor.py @@ -2,6 +2,7 @@ import re import pytest +import pandas.util._test_decorators as td from pandas.compat.pyarrow import ( pa_version_under11p0, pa_version_under13p0, @@ -15,8 +16,8 @@ from pandas import ( ) import pandas._testing as tm -pa = pytest.importorskip("pyarrow") -pc = pytest.importorskip("pyarrow.compute") +pa = td.versioned_importorskip("pyarrow") +pc = td.versioned_importorskip("pyarrow.compute") def test_struct_accessor_dtypes(): diff --git a/pandas/tests/series/methods/test_convert_dtypes.py b/pandas/tests/series/methods/test_convert_dtypes.py index b0a920ba..23bedf8e 100644 --- a/pandas/tests/series/methods/test_convert_dtypes.py +++ b/pandas/tests/series/methods/test_convert_dtypes.py @@ -3,6 +3,7 @@ from itertools import product import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs import lib import pandas as pd @@ -291,7 +292,7 @@ class TestSeriesConvertDtypes: def test_convert_dtypes_pyarrow_to_np_nullable(self): # GH 53648 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = pd.Series(range(2), dtype="int32[pyarrow]") result = ser.convert_dtypes(dtype_backend="numpy_nullable") expected = pd.Series(range(2), dtype="Int32") @@ -299,7 +300,7 @@ class TestSeriesConvertDtypes: def test_convert_dtypes_pyarrow_null(self): # GH#55346 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") ser = pd.Series([None, None]) result = ser.convert_dtypes(dtype_backend="pyarrow") expected = pd.Series([None, None], dtype=pd.ArrowDtype(pa.null())) diff --git a/pandas/tests/series/methods/test_cov_corr.py b/pandas/tests/series/methods/test_cov_corr.py index a369145b..2d769a4c 100644 --- a/pandas/tests/series/methods/test_cov_corr.py +++ b/pandas/tests/series/methods/test_cov_corr.py @@ -3,6 +3,7 @@ import math import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( Series, @@ -58,7 +59,7 @@ class TestSeriesCov: class TestSeriesCorr: @pytest.mark.parametrize("dtype", ["float64", "Float64"]) def test_corr(self, datetime_series, dtype): - stats = pytest.importorskip("scipy.stats") + stats = td.versioned_importorskip("scipy.stats") datetime_series = datetime_series.astype(dtype) @@ -93,7 +94,7 @@ class TestSeriesCorr: tm.assert_almost_equal(result, expected) def test_corr_rank(self): - stats = pytest.importorskip("scipy.stats") + stats = td.versioned_importorskip("scipy.stats") # kendall and spearman A = Series( diff --git a/pandas/tests/series/methods/test_drop_duplicates.py b/pandas/tests/series/methods/test_drop_duplicates.py index 10b2e985..91b6e6bf 100644 --- a/pandas/tests/series/methods/test_drop_duplicates.py +++ b/pandas/tests/series/methods/test_drop_duplicates.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( Categorical, @@ -252,7 +253,7 @@ class TestSeriesDropDuplicates: tm.assert_series_equal(result, expected) def test_duplicated_arrow_dtype(self): - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series([True, False, None, False], dtype="bool[pyarrow]") result = ser.drop_duplicates() expected = Series([True, False, None], dtype="bool[pyarrow]") @@ -260,7 +261,7 @@ class TestSeriesDropDuplicates: def test_drop_duplicates_arrow_strings(self): # GH#54904 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") ser = Series(["a", "a"], dtype=pd.ArrowDtype(pa.string())) result = ser.drop_duplicates() expecetd = Series(["a"], dtype=pd.ArrowDtype(pa.string())) diff --git a/pandas/tests/series/methods/test_explode.py b/pandas/tests/series/methods/test_explode.py index 5a018858..da5bbb04 100644 --- a/pandas/tests/series/methods/test_explode.py +++ b/pandas/tests/series/methods/test_explode.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd import pandas._testing as tm @@ -146,7 +147,7 @@ def test_explode_scalars_can_ignore_index(): @pytest.mark.parametrize("ignore_index", [True, False]) def test_explode_pyarrow_list_type(ignore_index): # GH 53602 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") data = [ [None, None], @@ -167,7 +168,7 @@ def test_explode_pyarrow_list_type(ignore_index): @pytest.mark.parametrize("ignore_index", [True, False]) def test_explode_pyarrow_non_list_type(ignore_index): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") data = [1, 2, 3] ser = pd.Series(data, dtype=pd.ArrowDtype(pa.int64())) result = ser.explode(ignore_index=ignore_index) diff --git a/pandas/tests/series/methods/test_interpolate.py b/pandas/tests/series/methods/test_interpolate.py index d854f0b7..1886b973 100644 --- a/pandas/tests/series/methods/test_interpolate.py +++ b/pandas/tests/series/methods/test_interpolate.py @@ -118,7 +118,7 @@ class TestSeriesInterpolateData: non_ts.interpolate(method="time") def test_interpolate_cubicspline(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ser = Series([10, 11, 12, 13]) expected = Series( @@ -133,7 +133,7 @@ class TestSeriesInterpolateData: tm.assert_series_equal(result, expected) def test_interpolate_pchip(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ser = Series(np.sort(np.random.default_rng(2).uniform(size=100))) # interpolate at new_index @@ -145,7 +145,7 @@ class TestSeriesInterpolateData: interp_s.loc[49:51] def test_interpolate_akima(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ser = Series([10, 11, 12, 13]) # interpolate at new_index where `der` is zero @@ -171,7 +171,7 @@ class TestSeriesInterpolateData: tm.assert_series_equal(interp_s.loc[1:3], expected) def test_interpolate_piecewise_polynomial(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ser = Series([10, 11, 12, 13]) expected = Series( @@ -186,7 +186,7 @@ class TestSeriesInterpolateData: tm.assert_series_equal(interp_s.loc[1:3], expected) def test_interpolate_from_derivatives(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ser = Series([10, 11, 12, 13]) expected = Series( @@ -276,14 +276,14 @@ class TestSeriesInterpolateData: tm.assert_series_equal(result, expected) def test_interp_quad(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") sq = Series([1, 4, np.nan, 16], index=[1, 2, 3, 4]) result = sq.interpolate(method="quadratic") expected = Series([1.0, 4.0, 9.0, 16.0], index=[1, 2, 3, 4]) tm.assert_series_equal(result, expected) def test_interp_scipy_basic(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([1, 3, np.nan, 12, np.nan, 25]) # slinear expected = Series([1.0, 3.0, 7.5, 12.0, 18.5, 25.0]) @@ -618,7 +618,7 @@ class TestSeriesInterpolateData: tm.assert_series_equal(result, expected) def test_interp_all_good(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([1, 2, 3]) result = s.interpolate(method="polynomial", order=1) tm.assert_series_equal(result, s) @@ -645,7 +645,7 @@ class TestSeriesInterpolateData: s.interpolate(method="polynomial", order=1) def test_interp_nonmono_raise(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([1, np.nan, 3], index=[0, 2, 1]) msg = "krogh interpolation requires that the index be monotonic" with pytest.raises(ValueError, match=msg): @@ -653,7 +653,7 @@ class TestSeriesInterpolateData: @pytest.mark.parametrize("method", ["nearest", "pad"]) def test_interp_datetime64(self, method, tz_naive_fixture): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = Series( [1, np.nan, 3], index=date_range("1/1/2000", periods=3, tz=tz_naive_fixture) ) @@ -699,7 +699,7 @@ class TestSeriesInterpolateData: @pytest.mark.parametrize("method", ["polynomial", "spline"]) def test_no_order(self, method): # see GH-10633, GH-24014 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([0, 1, np.nan, 3]) msg = "You must specify the order of the spline or polynomial" with pytest.raises(ValueError, match=msg): @@ -707,21 +707,21 @@ class TestSeriesInterpolateData: @pytest.mark.parametrize("order", [-1, -1.0, 0, 0.0, np.nan]) def test_interpolate_spline_invalid_order(self, order): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([0, 1, np.nan, 3]) msg = "order needs to be specified and greater than 0" with pytest.raises(ValueError, match=msg): s.interpolate(method="spline", order=order) def test_spline(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([1, 2, np.nan, 4, 5, np.nan, 7]) result = s.interpolate(method="spline", order=1) expected = Series([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]) tm.assert_series_equal(result, expected) def test_spline_extrapolate(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([1, 2, 3, 4, np.nan, 6, np.nan]) result3 = s.interpolate(method="spline", order=1, ext=3) expected3 = Series([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 6.0]) @@ -732,7 +732,7 @@ class TestSeriesInterpolateData: tm.assert_series_equal(result1, expected1) def test_spline_smooth(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series([1, 2, np.nan, 4, 5.1, np.nan, 7]) assert ( s.interpolate(method="spline", order=3, s=0)[5] @@ -741,7 +741,7 @@ class TestSeriesInterpolateData: def test_spline_interpolation(self): # Explicit cast to float to avoid implicit cast when setting np.nan - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series(np.arange(10) ** 2, dtype="float") s[np.random.default_rng(2).integers(0, 9, 3)] = np.nan result1 = s.interpolate(method="spline", order=1) @@ -801,7 +801,7 @@ class TestSeriesInterpolateData: method, kwargs = interp_methods_ind if method == "pchip": - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") if method == "linear": result = df[0].interpolate(**kwargs) @@ -824,7 +824,7 @@ class TestSeriesInterpolateData: are tested here. """ # gh 21662 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ind = pd.timedelta_range(start=1, periods=4) df = pd.DataFrame([0, 1, np.nan, 3], index=ind) @@ -861,7 +861,7 @@ class TestSeriesInterpolateData: def test_interpolate_fill_value(self): # GH#54920 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") ser = Series([np.nan, 0, 1, np.nan, 3, np.nan]) result = ser.interpolate(method="nearest", fill_value=0) expected = Series([np.nan, 0, 1, 1, 3, 0]) diff --git a/pandas/tests/series/methods/test_rank.py b/pandas/tests/series/methods/test_rank.py index 24cf97c0..a3ca64d9 100644 --- a/pandas/tests/series/methods/test_rank.py +++ b/pandas/tests/series/methods/test_rank.py @@ -56,7 +56,7 @@ def dtype(request): class TestSeriesRank: def test_rank(self, datetime_series): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") datetime_series[::2] = np.nan datetime_series[:10:3] = 4.0 @@ -269,7 +269,7 @@ class TestSeriesRank: def test_rank_tie_methods_on_infs_nans( self, method, na_option, ascending, dtype, na_value, pos_inf, neg_inf ): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") if dtype == "float64[pyarrow]": if method == "average": exp_dtype = "float64[pyarrow]" @@ -318,7 +318,7 @@ class TestSeriesRank: ], ) def test_rank_methods_series(self, method, op, value): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") xs = np.random.default_rng(2).standard_normal(9) xs = np.concatenate([xs[i:] for i in range(0, 9, 2)]) # add duplicates diff --git a/pandas/tests/series/methods/test_reset_index.py b/pandas/tests/series/methods/test_reset_index.py index 48e2608a..b43260c0 100644 --- a/pandas/tests/series/methods/test_reset_index.py +++ b/pandas/tests/series/methods/test_reset_index.py @@ -3,6 +3,7 @@ from datetime import datetime import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -170,7 +171,7 @@ class TestResetIndex: def test_reset_index_drop_infer_string(self): # GH#56160 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series(["a", "b", "c"], dtype=object) with option_context("future.infer_string", True): result = ser.reset_index(drop=True) diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index 29d6e203..6d262b6f 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -4,6 +4,7 @@ import pydoc import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import ( DataFrame, @@ -169,7 +170,7 @@ class TestSeriesMisc: def test_inspect_getmembers(self): # GH38782 - pytest.importorskip("jinja2") + td.versioned_importorskip("jinja2") ser = Series(dtype=object) msg = "Series._data is deprecated" with tm.assert_produces_warning( diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index 387be839..4201731c 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -2094,7 +2094,7 @@ class TestSeriesConstructors: def test_series_string_inference(self): # GH#54430 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype = "string[pyarrow_numpy]" expected = Series(["a", "b"], dtype=dtype) with pd.option_context("future.infer_string", True): @@ -2109,7 +2109,7 @@ class TestSeriesConstructors: @pytest.mark.parametrize("na_value", [None, np.nan, pd.NA]) def test_series_string_with_na_inference(self, na_value): # GH#54430 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype = "string[pyarrow_numpy]" expected = Series(["a", na_value], dtype=dtype) with pd.option_context("future.infer_string", True): @@ -2118,7 +2118,7 @@ class TestSeriesConstructors: def test_series_string_inference_scalar(self): # GH#54430 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = Series("a", index=[1], dtype="string[pyarrow_numpy]") with pd.option_context("future.infer_string", True): ser = Series("a", index=[1]) @@ -2126,7 +2126,7 @@ class TestSeriesConstructors: def test_series_string_inference_array_string_dtype(self): # GH#54496 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = Series(["a", "b"], dtype="string[pyarrow_numpy]") with pd.option_context("future.infer_string", True): ser = Series(np.array(["a", "b"])) @@ -2134,7 +2134,7 @@ class TestSeriesConstructors: def test_series_string_inference_storage_definition(self): # GH#54793 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = Series(["a", "b"], dtype="string[pyarrow_numpy]") with pd.option_context("future.infer_string", True): result = Series(["a", "b"], dtype="string") @@ -2150,7 +2150,7 @@ class TestSeriesConstructors: def test_series_string_inference_na_first(self): # GH#55655 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = Series([pd.NA, "b"], dtype="string[pyarrow_numpy]") with pd.option_context("future.infer_string", True): result = Series([pd.NA, "b"]) diff --git a/pandas/tests/series/test_formats.py b/pandas/tests/series/test_formats.py index a1c5018e..99a9347c 100644 --- a/pandas/tests/series/test_formats.py +++ b/pandas/tests/series/test_formats.py @@ -6,6 +6,7 @@ from datetime import ( import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._config import using_pyarrow_string_dtype import pandas as pd @@ -227,7 +228,7 @@ class TestSeriesRepr: repr(ts2).splitlines()[-1] def test_latex_repr(self): - pytest.importorskip("jinja2") # uses Styler implementation + td.versioned_importorskip("jinja2") # uses Styler implementation result = r"""\begin{tabular}{ll} \toprule & 0 \\ diff --git a/pandas/tests/series/test_logical_ops.py b/pandas/tests/series/test_logical_ops.py index d9c94e87..4d5c9cee 100644 --- a/pandas/tests/series/test_logical_ops.py +++ b/pandas/tests/series/test_logical_ops.py @@ -4,6 +4,7 @@ import operator import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Index, @@ -533,7 +534,7 @@ class TestSeriesLogicalOps: def test_pyarrow_numpy_string_invalid(self): # GH#56008 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series([False, True]) ser2 = Series(["a", "b"], dtype="string[pyarrow_numpy]") result = ser == ser2 diff --git a/pandas/tests/series/test_reductions.py b/pandas/tests/series/test_reductions.py index 76353ab2..73efdbb3 100644 --- a/pandas/tests/series/test_reductions.py +++ b/pandas/tests/series/test_reductions.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td import pandas as pd from pandas import Series import pandas._testing as tm @@ -53,7 +54,7 @@ def test_mode_nullable_dtype(any_numeric_ea_dtype): def test_mode_infer_string(): # GH#56183 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series(["a", "b"], dtype=object) with pd.option_context("future.infer_string", True): result = ser.mode() diff --git a/pandas/tests/strings/test_extract.py b/pandas/tests/strings/test_extract.py index 77d008c6..c01c1f68 100644 --- a/pandas/tests/strings/test_extract.py +++ b/pandas/tests/strings/test_extract.py @@ -4,6 +4,7 @@ import re import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.core.dtypes.dtypes import ArrowDtype from pandas import ( @@ -718,7 +719,7 @@ def test_extractall_same_as_extract_subject_index(any_string_dtype): def test_extractall_preserves_dtype(): # Ensure that when extractall is called on a series with specific dtypes set, that # the dtype is preserved in the resulting DataFrame's column. - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") result = Series(["abc", "ab"], dtype=ArrowDtype(pa.string())).str.extractall("(ab)") assert result.dtypes[0] == "string[pyarrow]" diff --git a/pandas/tests/test_algos.py b/pandas/tests/test_algos.py index 718d1b3e..9f0a197c 100644 --- a/pandas/tests/test_algos.py +++ b/pandas/tests/test_algos.py @@ -4,6 +4,7 @@ import struct import numpy as np import pytest +import pandas.util._test_decorators as td from pandas._libs import ( algos as libalgos, hashtable as ht, @@ -1789,7 +1790,7 @@ class TestRank: ], ) def test_scipy_compat(self, arr): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") arr = np.array(arr) diff --git a/pandas/tests/test_downstream.py b/pandas/tests/test_downstream.py index e04fc4b7..774317c4 100644 --- a/pandas/tests/test_downstream.py +++ b/pandas/tests/test_downstream.py @@ -44,8 +44,8 @@ def test_dask(df): olduse = pd.get_option("compute.use_numexpr") try: - pytest.importorskip("toolz") - dd = pytest.importorskip("dask.dataframe") + td.versioned_importorskip("toolz") + dd = td.versioned_importorskip("dask.dataframe") ddf = dd.from_pandas(df, npartitions=3) assert ddf.A is not None @@ -61,8 +61,8 @@ def test_dask_ufunc(): olduse = pd.get_option("compute.use_numexpr") try: - da = pytest.importorskip("dask.array") - dd = pytest.importorskip("dask.dataframe") + da = td.versioned_importorskip("dask.array") + dd = td.versioned_importorskip("dask.dataframe") s = Series([1.5, 2.3, 3.7, 4.0]) ds = dd.from_pandas(s, npartitions=2) @@ -78,7 +78,7 @@ def test_dask_ufunc(): def test_construct_dask_float_array_int_dtype_match_ndarray(): # GH#40110 make sure we treat a float-dtype dask array with the same # rules we would for an ndarray - dd = pytest.importorskip("dask.dataframe") + dd = td.versioned_importorskip("dask.dataframe") arr = np.array([1, 2.5, 3]) darr = dd.from_array(arr) @@ -102,15 +102,15 @@ def test_construct_dask_float_array_int_dtype_match_ndarray(): def test_xarray(df): - pytest.importorskip("xarray") + td.versioned_importorskip("xarray") assert df.to_xarray() is not None def test_xarray_cftimeindex_nearest(): # https://github.com/pydata/xarray/issues/3751 - cftime = pytest.importorskip("cftime") - xarray = pytest.importorskip("xarray") + cftime = td.versioned_importorskip("cftime") + xarray = td.versioned_importorskip("xarray") times = xarray.cftime_range("0001", periods=2) key = cftime.DatetimeGregorian(2000, 1, 1) @@ -142,7 +142,7 @@ def test_oo_optimized_datetime_index_unpickle(): def test_statsmodels(): - smf = pytest.importorskip("statsmodels.formula.api") + smf = td.versioned_importorskip("statsmodels.formula.api") df = DataFrame( {"Lottery": range(5), "Literacy": range(5), "Pop1831": range(100, 105)} @@ -151,7 +151,7 @@ def test_statsmodels(): def test_scikit_learn(): - pytest.importorskip("sklearn") + td.versioned_importorskip("sklearn") from sklearn import ( datasets, svm, @@ -164,7 +164,7 @@ def test_scikit_learn(): def test_seaborn(): - seaborn = pytest.importorskip("seaborn") + seaborn = td.versioned_importorskip("seaborn") tips = DataFrame( {"day": pd.date_range("2023", freq="D", periods=5), "total_bill": range(5)} ) @@ -172,12 +172,12 @@ def test_seaborn(): def test_pandas_datareader(): - pytest.importorskip("pandas_datareader") + td.versioned_importorskip("pandas_datareader") @pytest.mark.filterwarnings("ignore:Passing a BlockManager:DeprecationWarning") def test_pyarrow(df): - pyarrow = pytest.importorskip("pyarrow") + pyarrow = td.versioned_importorskip("pyarrow") table = pyarrow.Table.from_pandas(df) result = table.to_pandas() tm.assert_frame_equal(result, df) @@ -185,7 +185,7 @@ def test_pyarrow(df): def test_yaml_dump(df): # GH#42748 - yaml = pytest.importorskip("yaml") + yaml = td.versioned_importorskip("yaml") dumped = yaml.dump(df) @@ -247,7 +247,7 @@ def test_frame_setitem_dask_array_into_new_col(): olduse = pd.get_option("compute.use_numexpr") try: - da = pytest.importorskip("dask.array") + da = td.versioned_importorskip("dask.array") dda = da.array([1, 2]) df = DataFrame({"a": ["a", "b"]}) @@ -348,7 +348,7 @@ def test_dataframe_consortium() -> None: Full testing is done at https://github.com/data-apis/dataframe-api-compat, this is just to check that the entry point works as expected. """ - pytest.importorskip("dataframe_api_compat") + td.versioned_importorskip("dataframe_api_compat") df_pd = DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]}) df = df_pd.__dataframe_consortium_standard__() result_1 = df.get_column_names() @@ -362,7 +362,7 @@ def test_dataframe_consortium() -> None: def test_xarray_coerce_unit(): # GH44053 - xr = pytest.importorskip("xarray") + xr = td.versioned_importorskip("xarray") arr = xr.DataArray([1, 2, 3]) result = pd.to_datetime(arr, unit="ns") diff --git a/pandas/tests/test_nanops.py b/pandas/tests/test_nanops.py index a50054f3..d7342c65 100644 --- a/pandas/tests/test_nanops.py +++ b/pandas/tests/test_nanops.py @@ -500,7 +500,7 @@ class TestnanopsDataFrame: @pytest.mark.parametrize("ddof", range(3)) def test_nansem(self, ddof, skipna): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") with np.errstate(invalid="ignore"): self.check_funs( @@ -559,7 +559,7 @@ class TestnanopsDataFrame: return result def test_nanskew(self, skipna): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") func = partial(self._skew_kurt_wrap, func=sp_stats.skew) with np.errstate(invalid="ignore"): @@ -573,7 +573,7 @@ class TestnanopsDataFrame: ) def test_nankurt(self, skipna): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") func1 = partial(sp_stats.kurtosis, fisher=True) func = partial(self._skew_kurt_wrap, func=func1) @@ -704,7 +704,7 @@ class TestnanopsDataFrame: self.check_nancorr_nancov_1d(nanops.nancorr, targ0, targ1, method="pearson") def test_nancorr_kendall(self): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") targ0 = sp_stats.kendalltau(self.arr_float_2d, self.arr_float1_2d)[0] targ1 = sp_stats.kendalltau(self.arr_float_2d.flat, self.arr_float1_2d.flat)[0] @@ -714,7 +714,7 @@ class TestnanopsDataFrame: self.check_nancorr_nancov_1d(nanops.nancorr, targ0, targ1, method="kendall") def test_nancorr_spearman(self): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") targ0 = sp_stats.spearmanr(self.arr_float_2d, self.arr_float1_2d)[0] targ1 = sp_stats.spearmanr(self.arr_float_2d.flat, self.arr_float1_2d.flat)[0] @@ -724,7 +724,7 @@ class TestnanopsDataFrame: self.check_nancorr_nancov_1d(nanops.nancorr, targ0, targ1, method="spearman") def test_invalid_method(self): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") targ0 = np.corrcoef(self.arr_float_2d, self.arr_float1_2d)[0, 1] targ1 = np.corrcoef(self.arr_float_2d.flat, self.arr_float1_2d.flat)[0, 1] msg = "Unknown method 'foo', expected one of 'kendall', 'spearman'" diff --git a/pandas/tests/test_optional_dependency.py b/pandas/tests/test_optional_dependency.py index 52b5f636..3d50300a 100644 --- a/pandas/tests/test_optional_dependency.py +++ b/pandas/tests/test_optional_dependency.py @@ -3,6 +3,7 @@ import types import pytest +import pandas.util._test_decorators as td from pandas.compat._optional import ( VERSIONS, import_optional_dependency, @@ -23,7 +24,7 @@ def test_import_optional(): def test_xlrd_version_fallback(): - pytest.importorskip("xlrd") + td.versioned_importorskip("xlrd") import_optional_dependency("xlrd") diff --git a/pandas/tests/tools/test_to_datetime.py b/pandas/tests/tools/test_to_datetime.py index ede38ce9..c74bf614 100644 --- a/pandas/tests/tools/test_to_datetime.py +++ b/pandas/tests/tools/test_to_datetime.py @@ -1002,7 +1002,7 @@ class TestToDatetime: @pytest.mark.parametrize("utc", [True, False]) @pytest.mark.parametrize("tz", [None, "US/Central"]) def test_to_datetime_arrow(self, tz, utc, arg_class): - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") dti = date_range("1965-04-03", periods=19, freq="2W", tz=tz) dti = arg_class(dti) @@ -1357,7 +1357,7 @@ class TestToDatetime: def test_to_datetime_tz_psycopg2(self, request, cache): # xref 8260 - psycopg2_tz = pytest.importorskip("psycopg2.tz") + psycopg2_tz = td.versioned_importorskip("psycopg2.tz") # misc cases tz1 = psycopg2_tz.FixedOffsetTimezone(offset=-300, name=None) @@ -3742,7 +3742,7 @@ def test_ignoring_unknown_tz_deprecated(): def test_from_numeric_arrow_dtype(any_numeric_ea_dtype): # GH 52425 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series([1, 2], dtype=f"{any_numeric_ea_dtype.lower()}[pyarrow]") result = to_datetime(ser) expected = Series([1, 2], dtype="datetime64[ns]") diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index c452382e..7cd9889e 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -867,7 +867,7 @@ def test_to_numeric_dtype_backend(val, dtype): def test_to_numeric_dtype_backend_na(val, dtype): # GH#50505 if "pyarrow" in dtype: - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype_backend = "pyarrow" else: dtype_backend = "numpy_nullable" @@ -891,7 +891,7 @@ def test_to_numeric_dtype_backend_na(val, dtype): def test_to_numeric_dtype_backend_downcasting(val, dtype, downcast): # GH#50505 if "pyarrow" in dtype: - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") dtype_backend = "pyarrow" else: dtype_backend = "numpy_nullable" @@ -908,7 +908,7 @@ def test_to_numeric_dtype_backend_downcasting(val, dtype, downcast): def test_to_numeric_dtype_backend_downcasting_uint(smaller, dtype_backend): # GH#50505 if dtype_backend == "pyarrow": - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series([1, pd.NA], dtype="UInt64") result = to_numeric(ser, dtype_backend=dtype_backend, downcast="unsigned") expected = Series([1, pd.NA], dtype=smaller) @@ -931,7 +931,7 @@ def test_to_numeric_dtype_backend_downcasting_uint(smaller, dtype_backend): def test_to_numeric_dtype_backend_already_nullable(dtype): # GH#50505 if "pyarrow" in dtype: - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series([1, pd.NA], dtype=dtype) result = to_numeric(ser, dtype_backend="numpy_nullable") expected = Series([1, pd.NA], dtype=dtype) @@ -971,7 +971,7 @@ def test_invalid_dtype_backend(): def test_coerce_pyarrow_backend(): # GH 52588 - pa = pytest.importorskip("pyarrow") + pa = td.versioned_importorskip("pyarrow") ser = Series(list("12x"), dtype=ArrowDtype(pa.string())) result = to_numeric(ser, errors="coerce", dtype_backend="pyarrow") expected = Series([1, 2, None], dtype=ArrowDtype(pa.int64())) diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py index 5a75988e..3852c7a9 100644 --- a/pandas/tests/tools/test_to_timedelta.py +++ b/pandas/tests/tools/test_to_timedelta.py @@ -6,6 +6,7 @@ from datetime import ( import numpy as np import pytest +import pandas.util._test_decorators as td from pandas.compat import IS64 from pandas.errors import OutOfBoundsTimedelta @@ -324,7 +325,7 @@ class TestTimedeltas: def test_from_numeric_arrow_dtype(any_numeric_ea_dtype): # GH 52425 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") ser = Series([1, 2], dtype=f"{any_numeric_ea_dtype.lower()}[pyarrow]") result = to_timedelta(ser) expected = Series([1, 2], dtype="timedelta64[ns]") @@ -334,7 +335,7 @@ def test_from_numeric_arrow_dtype(any_numeric_ea_dtype): @pytest.mark.parametrize("unit", ["ns", "ms"]) def test_from_timedelta_arrow_dtype(unit): # GH 54298 - pytest.importorskip("pyarrow") + td.versioned_importorskip("pyarrow") expected = Series([timedelta(1)], dtype=f"duration[{unit}][pyarrow]") result = to_timedelta(expected) tm.assert_series_equal(result, expected) diff --git a/pandas/tests/window/test_online.py b/pandas/tests/window/test_online.py index 14d3a391..def048b2 100644 --- a/pandas/tests/window/test_online.py +++ b/pandas/tests/window/test_online.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Series, @@ -9,7 +10,7 @@ import pandas._testing as tm pytestmark = pytest.mark.single_cpu -pytest.importorskip("numba") +td.versioned_importorskip("numba") @pytest.mark.filterwarnings("ignore") diff --git a/pandas/tests/window/test_rolling_skew_kurt.py b/pandas/tests/window/test_rolling_skew_kurt.py index 79c14f24..c30d5003 100644 --- a/pandas/tests/window/test_rolling_skew_kurt.py +++ b/pandas/tests/window/test_rolling_skew_kurt.py @@ -3,6 +3,7 @@ from functools import partial import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Series, @@ -17,7 +18,7 @@ from pandas.tseries import offsets @pytest.mark.parametrize("sp_func, roll_func", [["kurtosis", "kurt"], ["skew", "skew"]]) def test_series(series, sp_func, roll_func): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") compare_func = partial(getattr(sp_stats, sp_func), bias=False) result = getattr(series.rolling(50), roll_func)() @@ -27,7 +28,7 @@ def test_series(series, sp_func, roll_func): @pytest.mark.parametrize("sp_func, roll_func", [["kurtosis", "kurt"], ["skew", "skew"]]) def test_frame(raw, frame, sp_func, roll_func): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") compare_func = partial(getattr(sp_stats, sp_func), bias=False) result = getattr(frame.rolling(50), roll_func)() @@ -41,7 +42,7 @@ def test_frame(raw, frame, sp_func, roll_func): @pytest.mark.parametrize("sp_func, roll_func", [["kurtosis", "kurt"], ["skew", "skew"]]) def test_time_rule_series(series, sp_func, roll_func): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") compare_func = partial(getattr(sp_stats, sp_func), bias=False) win = 25 @@ -56,7 +57,7 @@ def test_time_rule_series(series, sp_func, roll_func): @pytest.mark.parametrize("sp_func, roll_func", [["kurtosis", "kurt"], ["skew", "skew"]]) def test_time_rule_frame(raw, frame, sp_func, roll_func): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") compare_func = partial(getattr(sp_stats, sp_func), bias=False) win = 25 @@ -75,7 +76,7 @@ def test_time_rule_frame(raw, frame, sp_func, roll_func): @pytest.mark.parametrize("sp_func, roll_func", [["kurtosis", "kurt"], ["skew", "skew"]]) def test_nans(sp_func, roll_func): - sp_stats = pytest.importorskip("scipy.stats") + sp_stats = td.versioned_importorskip("scipy.stats") compare_func = partial(getattr(sp_stats, sp_func), bias=False) obj = Series(np.random.default_rng(2).standard_normal(50)) diff --git a/pandas/tests/window/test_win_type.py b/pandas/tests/window/test_win_type.py index 5052019d..f69d23dd 100644 --- a/pandas/tests/window/test_win_type.py +++ b/pandas/tests/window/test_win_type.py @@ -1,6 +1,7 @@ import numpy as np import pytest +import pandas.util._test_decorators as td from pandas import ( DataFrame, Series, @@ -35,7 +36,7 @@ def win_types_special(request): def test_constructor(frame_or_series): # GH 12669 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") c = frame_or_series(range(5)).rolling # valid @@ -47,7 +48,7 @@ def test_constructor(frame_or_series): @pytest.mark.parametrize("w", [2.0, "foo", np.array([2])]) def test_invalid_constructor(frame_or_series, w): # not valid - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") c = frame_or_series(range(5)).rolling with pytest.raises(ValueError, match="min_periods must be an integer"): c(win_type="boxcar", window=2, min_periods=w) @@ -57,7 +58,7 @@ def test_invalid_constructor(frame_or_series, w): @pytest.mark.parametrize("wt", ["foobar", 1]) def test_invalid_constructor_wintype(frame_or_series, wt): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") c = frame_or_series(range(5)).rolling with pytest.raises(ValueError, match="Invalid win_type"): c(win_type=wt, window=2) @@ -65,14 +66,14 @@ def test_invalid_constructor_wintype(frame_or_series, wt): def test_constructor_with_win_type(frame_or_series, win_types): # GH 12669 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") c = frame_or_series(range(5)).rolling c(win_type=win_types, window=2) @pytest.mark.parametrize("arg", ["median", "kurt", "skew"]) def test_agg_function_support(arg): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame({"A": np.arange(5)}) roll = df.rolling(2, win_type="triang") @@ -89,7 +90,7 @@ def test_agg_function_support(arg): def test_invalid_scipy_arg(): # This error is raised by scipy - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") msg = r"boxcar\(\) got an unexpected" with pytest.raises(TypeError, match=msg): Series(range(3)).rolling(1, win_type="boxcar").mean(foo="bar") @@ -97,7 +98,7 @@ def test_invalid_scipy_arg(): def test_constructor_with_win_type_invalid(frame_or_series): # GH 13383 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") c = frame_or_series(range(5)).rolling msg = "window must be an integer 0 or greater" @@ -108,7 +109,7 @@ def test_constructor_with_win_type_invalid(frame_or_series): def test_window_with_args(step): # make sure that we are aggregating window functions correctly with arg - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") r = Series(np.random.default_rng(2).standard_normal(100)).rolling( window=10, min_periods=1, win_type="gaussian", step=step ) @@ -130,7 +131,7 @@ def test_window_with_args(step): def test_win_type_with_method_invalid(): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") with pytest.raises( NotImplementedError, match="'single' is the only supported method type." ): @@ -140,7 +141,7 @@ def test_win_type_with_method_invalid(): @pytest.mark.parametrize("arg", [2000000000, "2s", Timedelta("2s")]) def test_consistent_win_type_freq(arg): # GH 15969 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") s = Series(range(1)) with pytest.raises(ValueError, match="Invalid win_type freq"): s.rolling(arg, win_type="freq") @@ -153,7 +154,7 @@ def test_win_type_freq_return_none(): def test_win_type_not_implemented(): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") class CustomIndexer(BaseIndexer): def get_window_bounds(self, num_values, min_periods, center, closed, step): @@ -167,7 +168,7 @@ def test_win_type_not_implemented(): def test_cmov_mean(step): # GH 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") vals = np.array([6.95, 15.21, 4.72, 9.12, 13.81, 13.49, 16.68, 9.48, 10.63, 14.48]) result = Series(vals).rolling(5, center=True, step=step).mean() expected_values = [ @@ -188,7 +189,7 @@ def test_cmov_mean(step): def test_cmov_window(step): # GH 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") vals = np.array([6.95, 15.21, 4.72, 9.12, 13.81, 13.49, 16.68, 9.48, 10.63, 14.48]) result = Series(vals).rolling(5, win_type="boxcar", center=True, step=step).mean() expected_values = [ @@ -210,7 +211,7 @@ def test_cmov_window(step): def test_cmov_window_corner(step): # GH 8238 # all nan - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") vals = Series([np.nan] * 10) result = vals.rolling(5, center=True, win_type="boxcar", step=step).mean() assert np.isnan(result).all() @@ -294,7 +295,7 @@ def test_cmov_window_corner(step): ) def test_cmov_window_frame(f, xp, step): # Gh 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame( np.array( [ @@ -321,7 +322,7 @@ def test_cmov_window_frame(f, xp, step): @pytest.mark.parametrize("min_periods", [0, 1, 2, 3, 4, 5]) def test_cmov_window_na_min_periods(step, min_periods): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") vals = Series(np.random.default_rng(2).standard_normal(10)) vals[4] = np.nan vals[8] = np.nan @@ -335,7 +336,7 @@ def test_cmov_window_na_min_periods(step, min_periods): def test_cmov_window_regular(win_types, step): # GH 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") vals = np.array([6.95, 15.21, 4.72, 9.12, 13.81, 13.49, 16.68, 9.48, 10.63, 14.48]) xps = { "hamming": [ @@ -443,7 +444,7 @@ def test_cmov_window_regular(win_types, step): def test_cmov_window_regular_linear_range(win_types, step): # GH 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") vals = np.array(range(10), dtype=float) xp = vals.copy() xp[:2] = np.nan @@ -456,7 +457,7 @@ def test_cmov_window_regular_linear_range(win_types, step): def test_cmov_window_regular_missing_data(win_types, step): # GH 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") vals = np.array( [6.95, 15.21, 4.72, 9.12, 13.81, 13.49, 16.68, np.nan, 10.63, 14.48] ) @@ -566,7 +567,7 @@ def test_cmov_window_regular_missing_data(win_types, step): def test_cmov_window_special(win_types_special, step): # GH 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") kwds = { "kaiser": {"beta": 1.0}, "gaussian": {"std": 1.0}, @@ -638,7 +639,7 @@ def test_cmov_window_special(win_types_special, step): def test_cmov_window_special_linear_range(win_types_special, step): # GH 8238 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") kwds = { "kaiser": {"beta": 1.0}, "gaussian": {"std": 1.0}, @@ -663,7 +664,7 @@ def test_cmov_window_special_linear_range(win_types_special, step): def test_weighted_var_big_window_no_segfault(win_types, center): # GitHub Issue #46772 - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") x = Series(0) result = x.rolling(window=16, center=center, win_type=win_types).var() expected = Series(np.nan) @@ -672,7 +673,7 @@ def test_weighted_var_big_window_no_segfault(win_types, center): def test_rolling_center_axis_1(): - pytest.importorskip("scipy") + td.versioned_importorskip("scipy") df = DataFrame( {"a": [1, 1, 0, 0, 0, 1], "b": [1, 0, 0, 1, 0, 0], "c": [1, 0, 0, 1, 0, 1]} ) diff --git a/pandas/util/_test_decorators.py b/pandas/util/_test_decorators.py index 2c1912bc..3315b55c 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -79,8 +79,8 @@ def skip_if_no(package: str, min_version: str | None = None) -> pytest.MarkDecor The mark can be used as either a decorator for a test class or to be applied to parameters in pytest.mark.parametrize calls or parametrized - fixtures. Use pytest.importorskip if an imported moduled is later needed - or for test functions. + fixtures. Use td.versioned_importorskip if an imported module is later + needed or for test functions. If the import and version check are unsuccessful, then the test function (or test case when used in conjunction with parametrization) will be @@ -171,3 +171,22 @@ skip_copy_on_write_invalid_test = pytest.mark.skipif( get_option("mode.copy_on_write") is True, reason="Test not valid for Copy-on-Write mode", ) + +def versioned_importorskip(*args, **kwargs): + """ + (warning - this is currently Debian-specific, the name may change if upstream request this) + + Return the requested module, or skip the test if it is + not available in a new enough version. + + Intended as a replacement for pytest.importorskip that + defaults to requiring at least pandas' minimum version for that + optional dependency, rather than any version. + + See import_optional_dependency for full parameter documentation. + """ + try: + module = import_optional_dependency(*args, **kwargs) + except ImportError as exc: + pytest.skip(str(exc), allow_module_level=True) + return module -- 2.30.2