diff --git a/doc/source/whatsnew/v1.0.0.rst b/doc/source/whatsnew/v1.0.0.rst index f231c2b31abb1..89b85c376f5b4 100644 --- a/doc/source/whatsnew/v1.0.0.rst +++ b/doc/source/whatsnew/v1.0.0.rst @@ -377,6 +377,7 @@ or ``matplotlib.Axes.plot``. See :ref:`plotting.formatters` for more. **Other removals** - Removed the previously deprecated :meth:`Index.summary` (:issue:`18217`) +- Removed the previously deprecated "fastpath" keyword from the :class:`Index` constructor (:issue:`23110`) - Removed the previously deprecated :meth:`Series.get_value`, :meth:`Series.set_value`, :meth:`DataFrame.get_value`, :meth:`DataFrame.set_value` (:issue:`17739`) - Changed the the default value of `inplace` in :meth:`DataFrame.set_index` and :meth:`Series.set_axis`. It now defaults to False (:issue:`27600`) - Removed support for nested renaming in :meth:`DataFrame.aggregate`, :meth:`Series.aggregate`, :meth:`DataFrameGroupBy.aggregate`, :meth:`SeriesGroupBy.aggregate`, :meth:`Rolling.aggregate` (:issue:`18529`) diff --git a/pandas/conftest.py b/pandas/conftest.py index b032e14d8f7e1..122d6e94d9c1a 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -854,3 +854,16 @@ def float_frame(): [30 rows x 4 columns] """ return DataFrame(tm.getSeriesData()) + + +@pytest.fixture(params=[pd.Index, pd.Series], ids=["index", "series"]) +def index_or_series(request): + """ + Fixture to parametrize over Index and Series, made necessary by a mypy + bug, giving an error: + + List item 0 has incompatible type "Type[Series]"; expected "Type[PandasObject]" + + See GH#????? + """ + return request.param diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index dd38bd0ee5f70..d082d42ae7977 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -259,14 +259,7 @@ def _outer_indexer(self, left, right): # Constructors def __new__( - cls, - data=None, - dtype=None, - copy=False, - name=None, - fastpath=None, - tupleize_cols=True, - **kwargs, + cls, data=None, dtype=None, copy=False, name=None, tupleize_cols=True, **kwargs, ) -> "Index": from .range import RangeIndex @@ -278,16 +271,6 @@ def __new__( if name is None and hasattr(data, "name"): name = data.name - if fastpath is not None: - warnings.warn( - "The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", - FutureWarning, - stacklevel=2, - ) - if fastpath: - return cls._simple_new(data, name) - if isinstance(data, ABCPandasArray): # ensure users don't accidentally put a PandasArray in an index. data = data.to_numpy() diff --git a/pandas/core/indexes/category.py b/pandas/core/indexes/category.py index e0ffc726bc3a1..d061f61effff3 100644 --- a/pandas/core/indexes/category.py +++ b/pandas/core/indexes/category.py @@ -1,6 +1,5 @@ import operator from typing import Any -import warnings import numpy as np @@ -172,19 +171,8 @@ def __new__( dtype=None, copy=False, name=None, - fastpath=None, ): - if fastpath is not None: - warnings.warn( - "The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", - FutureWarning, - stacklevel=2, - ) - if fastpath: - return cls._simple_new(data, name=name, dtype=dtype) - dtype = CategoricalDtype._from_values_or_dtype(data, categories, ordered, dtype) if name is None and hasattr(data, "name"): diff --git a/pandas/core/indexes/numeric.py b/pandas/core/indexes/numeric.py index 29f56259dac79..b30d8c732fbef 100644 --- a/pandas/core/indexes/numeric.py +++ b/pandas/core/indexes/numeric.py @@ -1,5 +1,3 @@ -import warnings - import numpy as np from pandas._libs import index as libindex @@ -47,17 +45,8 @@ class NumericIndex(Index): _is_numeric_dtype = True - def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=None): + def __new__(cls, data=None, dtype=None, copy=False, name=None): cls._validate_dtype(dtype) - if fastpath is not None: - warnings.warn( - "The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", - FutureWarning, - stacklevel=2, - ) - if fastpath: - return cls._simple_new(data, name=name) # Coerce to ndarray if not already ndarray or Index if not isinstance(data, (np.ndarray, Index)): diff --git a/pandas/core/indexes/range.py b/pandas/core/indexes/range.py index e68b340130b9b..f7bbbee461e8d 100644 --- a/pandas/core/indexes/range.py +++ b/pandas/core/indexes/range.py @@ -81,26 +81,9 @@ class RangeIndex(Int64Index): # Constructors def __new__( - cls, - start=None, - stop=None, - step=None, - dtype=None, - copy=False, - name=None, - fastpath=None, + cls, start=None, stop=None, step=None, dtype=None, copy=False, name=None, ): - if fastpath is not None: - warnings.warn( - "The 'fastpath' keyword is deprecated, and will be " - "removed in a future version.", - FutureWarning, - stacklevel=2, - ) - if fastpath: - return cls._simple_new(range(start, stop, step), name=name) - cls._validate_dtype(dtype) # RangeIndex diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py index 584e22f8488f5..77713deada44a 100644 --- a/pandas/tests/arithmetic/test_numeric.py +++ b/pandas/tests/arithmetic/test_numeric.py @@ -5,6 +5,7 @@ from decimal import Decimal from itertools import combinations import operator +from typing import Any, List import numpy as np import pytest @@ -30,6 +31,19 @@ def adjust_negative_zero(zero, expected): return expected +# TODO: remove this kludge once mypy stops giving false positives here +# List comprehension has incompatible type List[PandasObject]; expected List[RangeIndex] +# See GH#????? +ser_or_index: List[Any] = [pd.Series, pd.Index] +lefts: List[Any] = [pd.RangeIndex(10, 40, 10)] +lefts.extend( + [ + cls([10, 20, 30], dtype=dtype) + for dtype in ["i1", "i2", "i4", "i8", "u1", "u2", "u4", "u8", "f2", "f4", "f8"] + for cls in ser_or_index + ] +) + # ------------------------------------------------------------------ # Comparisons @@ -81,26 +95,7 @@ class TestNumericArraylikeArithmeticWithDatetimeLike: # TODO: also check name retentention @pytest.mark.parametrize("box_cls", [np.array, pd.Index, pd.Series]) @pytest.mark.parametrize( - "left", - [pd.RangeIndex(10, 40, 10)] - + [ - cls([10, 20, 30], dtype=dtype) - for dtype in [ - "i1", - "i2", - "i4", - "i8", - "u1", - "u2", - "u4", - "u8", - "f2", - "f4", - "f8", - ] - for cls in [pd.Series, pd.Index] - ], - ids=lambda x: type(x).__name__ + str(x.dtype), + "left", lefts, ids=lambda x: type(x).__name__ + str(x.dtype), ) def test_mul_td64arr(self, left, box_cls): # GH#22390 @@ -120,26 +115,7 @@ def test_mul_td64arr(self, left, box_cls): # TODO: also check name retentention @pytest.mark.parametrize("box_cls", [np.array, pd.Index, pd.Series]) @pytest.mark.parametrize( - "left", - [pd.RangeIndex(10, 40, 10)] - + [ - cls([10, 20, 30], dtype=dtype) - for dtype in [ - "i1", - "i2", - "i4", - "i8", - "u1", - "u2", - "u4", - "u8", - "f2", - "f4", - "f8", - ] - for cls in [pd.Series, pd.Index] - ], - ids=lambda x: type(x).__name__ + str(x.dtype), + "left", lefts, ids=lambda x: type(x).__name__ + str(x.dtype), ) def test_div_td64arr(self, left, box_cls): # GH#22390 diff --git a/pandas/tests/arrays/test_array.py b/pandas/tests/arrays/test_array.py index e8d9ecfac61e4..6f443f1841dcc 100644 --- a/pandas/tests/arrays/test_array.py +++ b/pandas/tests/arrays/test_array.py @@ -272,8 +272,9 @@ def _from_sequence(cls, scalars, dtype=None, copy=False): return super()._from_sequence(scalars, dtype=dtype, copy=copy) -@pytest.mark.parametrize("box", [pd.Series, pd.Index]) -def test_array_unboxes(box): +def test_array_unboxes(index_or_series): + box = index_or_series + data = box([decimal.Decimal("1"), decimal.Decimal("2")]) # make sure it works with pytest.raises(TypeError): diff --git a/pandas/tests/dtypes/test_concat.py b/pandas/tests/dtypes/test_concat.py index 0ca2f7c976535..02daa185b1cdb 100644 --- a/pandas/tests/dtypes/test_concat.py +++ b/pandas/tests/dtypes/test_concat.py @@ -2,7 +2,7 @@ import pandas.core.dtypes.concat as _concat -from pandas import DatetimeIndex, Index, Period, PeriodIndex, Series, TimedeltaIndex +from pandas import DatetimeIndex, Period, PeriodIndex, Series, TimedeltaIndex @pytest.mark.parametrize( @@ -40,9 +40,8 @@ ), ], ) -@pytest.mark.parametrize("klass", [Index, Series]) -def test_get_dtype_kinds(klass, to_concat, expected): - to_concat_klass = [klass(c) for c in to_concat] +def test_get_dtype_kinds(index_or_series, to_concat, expected): + to_concat_klass = [index_or_series(c) for c in to_concat] result = _concat.get_dtype_kinds(to_concat_klass) assert result == set(expected) diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 15844df5d7b04..21c828328e5b8 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -2762,32 +2762,18 @@ def test_index_subclass_constructor_wrong_kwargs(index_maker): def test_deprecated_fastpath(): + msg = "[Uu]nexpected keyword argument" + with pytest.raises(TypeError, match=msg): + pd.Index(np.array(["a", "b"], dtype=object), name="test", fastpath=True) - with tm.assert_produces_warning(FutureWarning): - idx = pd.Index(np.array(["a", "b"], dtype=object), name="test", fastpath=True) + with pytest.raises(TypeError, match=msg): + pd.Int64Index(np.array([1, 2, 3], dtype="int64"), name="test", fastpath=True) - expected = pd.Index(["a", "b"], name="test") - tm.assert_index_equal(idx, expected) + with pytest.raises(TypeError, match=msg): + pd.RangeIndex(0, 5, 2, name="test", fastpath=True) - with tm.assert_produces_warning(FutureWarning): - idx = pd.Int64Index( - np.array([1, 2, 3], dtype="int64"), name="test", fastpath=True - ) - - expected = pd.Index([1, 2, 3], name="test", dtype="int64") - tm.assert_index_equal(idx, expected) - - with tm.assert_produces_warning(FutureWarning): - idx = pd.RangeIndex(0, 5, 2, name="test", fastpath=True) - - expected = pd.RangeIndex(0, 5, 2, name="test") - tm.assert_index_equal(idx, expected) - - with tm.assert_produces_warning(FutureWarning): - idx = pd.CategoricalIndex(["a", "b", "c"], name="test", fastpath=True) - - expected = pd.CategoricalIndex(["a", "b", "c"], name="test") - tm.assert_index_equal(idx, expected) + with pytest.raises(TypeError, match=msg): + pd.CategoricalIndex(["a", "b", "c"], name="test", fastpath=True) def test_shape_of_invalid_index(): diff --git a/pandas/tests/indexing/test_coercion.py b/pandas/tests/indexing/test_coercion.py index 8b29cf3813d13..e3ad3f733a302 100644 --- a/pandas/tests/indexing/test_coercion.py +++ b/pandas/tests/indexing/test_coercion.py @@ -513,12 +513,12 @@ def _assert_where_conversion( res = target.where(cond, values) self._assert(res, expected, expected_dtype) - @pytest.mark.parametrize("klass", [pd.Series, pd.Index], ids=["series", "index"]) @pytest.mark.parametrize( "fill_val,exp_dtype", [(1, np.object), (1.1, np.object), (1 + 1j, np.object), (True, np.object)], ) - def test_where_object(self, klass, fill_val, exp_dtype): + def test_where_object(self, index_or_series, fill_val, exp_dtype): + klass = index_or_series obj = klass(list("abcd")) assert obj.dtype == np.object cond = klass([True, False, True, False]) @@ -539,12 +539,12 @@ def test_where_object(self, klass, fill_val, exp_dtype): exp = klass(["a", values[1], "c", values[3]]) self._assert_where_conversion(obj, cond, values, exp, exp_dtype) - @pytest.mark.parametrize("klass", [pd.Series, pd.Index], ids=["series", "index"]) @pytest.mark.parametrize( "fill_val,exp_dtype", [(1, np.int64), (1.1, np.float64), (1 + 1j, np.complex128), (True, np.object)], ) - def test_where_int64(self, klass, fill_val, exp_dtype): + def test_where_int64(self, index_or_series, fill_val, exp_dtype): + klass = index_or_series if klass is pd.Index and exp_dtype is np.complex128: pytest.skip("Complex Index not supported") obj = klass([1, 2, 3, 4]) @@ -561,7 +561,6 @@ def test_where_int64(self, klass, fill_val, exp_dtype): exp = klass([1, values[1], 3, values[3]]) self._assert_where_conversion(obj, cond, values, exp, exp_dtype) - @pytest.mark.parametrize("klass", [pd.Series, pd.Index], ids=["series", "index"]) @pytest.mark.parametrize( "fill_val, exp_dtype", [ @@ -571,7 +570,8 @@ def test_where_int64(self, klass, fill_val, exp_dtype): (True, np.object), ], ) - def test_where_float64(self, klass, fill_val, exp_dtype): + def test_where_float64(self, index_or_series, fill_val, exp_dtype): + klass = index_or_series if klass is pd.Index and exp_dtype is np.complex128: pytest.skip("Complex Index not supported") obj = klass([1.1, 2.2, 3.3, 4.4]) @@ -781,19 +781,18 @@ def _assert_fillna_conversion(self, original, value, expected, expected_dtype): res = target.fillna(value) self._assert(res, expected, expected_dtype) - @pytest.mark.parametrize("klass", [pd.Series, pd.Index], ids=["series", "index"]) @pytest.mark.parametrize( "fill_val, fill_dtype", [(1, np.object), (1.1, np.object), (1 + 1j, np.object), (True, np.object)], ) - def test_fillna_object(self, klass, fill_val, fill_dtype): + def test_fillna_object(self, index_or_series, fill_val, fill_dtype): + klass = index_or_series obj = klass(["a", np.nan, "c", "d"]) assert obj.dtype == np.object exp = klass(["a", fill_val, "c", "d"]) self._assert_fillna_conversion(obj, fill_val, exp, fill_dtype) - @pytest.mark.parametrize("klass", [pd.Series, pd.Index], ids=["series", "index"]) @pytest.mark.parametrize( "fill_val,fill_dtype", [ @@ -803,7 +802,8 @@ def test_fillna_object(self, klass, fill_val, fill_dtype): (True, np.object), ], ) - def test_fillna_float64(self, klass, fill_val, fill_dtype): + def test_fillna_float64(self, index_or_series, fill_val, fill_dtype): + klass = index_or_series obj = klass([1.1, np.nan, 3.3, 4.4]) assert obj.dtype == np.float64 @@ -831,7 +831,6 @@ def test_fillna_series_complex128(self, fill_val, fill_dtype): exp = pd.Series([1 + 1j, fill_val, 3 + 3j, 4 + 4j]) self._assert_fillna_conversion(obj, fill_val, exp, fill_dtype) - @pytest.mark.parametrize("klass", [pd.Series, pd.Index], ids=["series", "index"]) @pytest.mark.parametrize( "fill_val,fill_dtype", [ @@ -842,7 +841,8 @@ def test_fillna_series_complex128(self, fill_val, fill_dtype): ], ids=["datetime64", "datetime64tz", "object", "object"], ) - def test_fillna_datetime(self, klass, fill_val, fill_dtype): + def test_fillna_datetime(self, index_or_series, fill_val, fill_dtype): + klass = index_or_series obj = klass( [ pd.Timestamp("2011-01-01"), @@ -863,7 +863,6 @@ def test_fillna_datetime(self, klass, fill_val, fill_dtype): ) self._assert_fillna_conversion(obj, fill_val, exp, fill_dtype) - @pytest.mark.parametrize("klass", [pd.Series, pd.Index]) @pytest.mark.parametrize( "fill_val,fill_dtype", [ @@ -874,7 +873,8 @@ def test_fillna_datetime(self, klass, fill_val, fill_dtype): ("x", np.object), ], ) - def test_fillna_datetime64tz(self, klass, fill_val, fill_dtype): + def test_fillna_datetime64tz(self, index_or_series, fill_val, fill_dtype): + klass = index_or_series tz = "US/Eastern" obj = klass( diff --git a/pandas/tests/io/json/test_json_table_schema.py b/pandas/tests/io/json/test_json_table_schema.py index ef9b0bdf053e9..49f666344dfa2 100644 --- a/pandas/tests/io/json/test_json_table_schema.py +++ b/pandas/tests/io/json/test_json_table_schema.py @@ -421,15 +421,15 @@ def test_date_format_raises(self): self.df.to_json(orient="table", date_format="iso") self.df.to_json(orient="table") - @pytest.mark.parametrize("kind", [pd.Series, pd.Index]) - def test_convert_pandas_type_to_json_field_int(self, kind): + def test_convert_pandas_type_to_json_field_int(self, index_or_series): + kind = index_or_series data = [1, 2, 3] result = convert_pandas_type_to_json_field(kind(data, name="name")) expected = {"name": "name", "type": "integer"} assert result == expected - @pytest.mark.parametrize("kind", [pd.Series, pd.Index]) - def test_convert_pandas_type_to_json_field_float(self, kind): + def test_convert_pandas_type_to_json_field_float(self, index_or_series): + kind = index_or_series data = [1.0, 2.0, 3.0] result = convert_pandas_type_to_json_field(kind(data, name="name")) expected = {"name": "name", "type": "number"} diff --git a/pandas/tests/test_base.py b/pandas/tests/test_base.py index 58093ba4d90a5..f24bb9e72aef5 100644 --- a/pandas/tests/test_base.py +++ b/pandas/tests/test_base.py @@ -516,8 +516,8 @@ def test_value_counts_unique_nunique_null(self, null_obj): assert o.nunique() == 8 assert o.nunique(dropna=False) == 9 - @pytest.mark.parametrize("klass", [Index, Series]) - def test_value_counts_inferred(self, klass): + def test_value_counts_inferred(self, index_or_series): + klass = index_or_series s_values = ["a", "b", "b", "b", "b", "c", "d", "d", "a", "a"] s = klass(s_values) expected = Series([4, 3, 2, 1], index=["b", "a", "d", "c"]) @@ -547,8 +547,8 @@ def test_value_counts_inferred(self, klass): expected = Series([0.4, 0.3, 0.2, 0.1], index=["b", "a", "d", "c"]) tm.assert_series_equal(hist, expected) - @pytest.mark.parametrize("klass", [Index, Series]) - def test_value_counts_bins(self, klass): + def test_value_counts_bins(self, index_or_series): + klass = index_or_series s_values = ["a", "b", "b", "b", "b", "c", "d", "d", "a", "a"] s = klass(s_values) @@ -612,8 +612,8 @@ def test_value_counts_bins(self, klass): assert s.nunique() == 0 - @pytest.mark.parametrize("klass", [Index, Series]) - def test_value_counts_datetime64(self, klass): + def test_value_counts_datetime64(self, index_or_series): + klass = index_or_series # GH 3002, datetime64[ns] # don't test names though @@ -1090,13 +1090,13 @@ class TestToIterable: ], ids=["tolist", "to_list", "list", "iter"], ) - @pytest.mark.parametrize("typ", [Series, Index]) @pytest.mark.filterwarnings("ignore:\\n Passing:FutureWarning") # TODO(GH-24559): Remove the filterwarnings - def test_iterable(self, typ, method, dtype, rdtype): + def test_iterable(self, index_or_series, method, dtype, rdtype): # gh-10904 # gh-13258 # coerce iteration to underlying python / pandas types + typ = index_or_series s = typ([1], dtype=dtype) result = method(s)[0] assert isinstance(result, rdtype) @@ -1120,11 +1120,13 @@ def test_iterable(self, typ, method, dtype, rdtype): ], ids=["tolist", "to_list", "list", "iter"], ) - @pytest.mark.parametrize("typ", [Series, Index]) - def test_iterable_object_and_category(self, typ, method, dtype, rdtype, obj): + def test_iterable_object_and_category( + self, index_or_series, method, dtype, rdtype, obj + ): # gh-10904 # gh-13258 # coerce iteration to underlying python / pandas types + typ = index_or_series s = typ([obj], dtype=dtype) result = method(s)[0] assert isinstance(result, rdtype) @@ -1144,12 +1146,12 @@ def test_iterable_items(self, dtype, rdtype): @pytest.mark.parametrize( "dtype, rdtype", dtypes + [("object", int), ("category", int)] ) - @pytest.mark.parametrize("typ", [Series, Index]) @pytest.mark.filterwarnings("ignore:\\n Passing:FutureWarning") # TODO(GH-24559): Remove the filterwarnings - def test_iterable_map(self, typ, dtype, rdtype): + def test_iterable_map(self, index_or_series, dtype, rdtype): # gh-13236 # coerce iteration to underlying python / pandas types + typ = index_or_series s = typ([1], dtype=dtype) result = s.map(type)[0] if not isinstance(rdtype, tuple): @@ -1332,8 +1334,8 @@ def test_numpy_array_all_dtypes(any_numpy_dtype): ), ], ) -@pytest.mark.parametrize("box", [pd.Series, pd.Index]) -def test_array(array, attr, box): +def test_array(array, attr, index_or_series): + box = index_or_series if array.dtype.name in ("Int64", "Sparse[int64, 0]") and box is pd.Index: pytest.skip("No index type for {}".format(array.dtype)) result = box(array, copy=False).array @@ -1396,8 +1398,8 @@ def test_array_multiindex_raises(): ), ], ) -@pytest.mark.parametrize("box", [pd.Series, pd.Index]) -def test_to_numpy(array, expected, box): +def test_to_numpy(array, expected, index_or_series): + box = index_or_series thing = box(array) if array.dtype.name in ("Int64", "Sparse[int64, 0]") and box is pd.Index: diff --git a/pandas/tests/test_strings.py b/pandas/tests/test_strings.py index 1261c3bbc86db..c00e792fb210f 100644 --- a/pandas/tests/test_strings.py +++ b/pandas/tests/test_strings.py @@ -202,9 +202,9 @@ def test_api_mi_raises(self): assert not hasattr(mi, "str") @pytest.mark.parametrize("dtype", [object, "category"]) - @pytest.mark.parametrize("box", [Series, Index]) - def test_api_per_dtype(self, box, dtype, any_skipna_inferred_dtype): + def test_api_per_dtype(self, index_or_series, dtype, any_skipna_inferred_dtype): # one instance of parametrized fixture + box = index_or_series inferred_dtype, values = any_skipna_inferred_dtype t = box(values, dtype=dtype) # explicit dtype to avoid casting @@ -236,13 +236,17 @@ def test_api_per_dtype(self, box, dtype, any_skipna_inferred_dtype): assert not hasattr(t, "str") @pytest.mark.parametrize("dtype", [object, "category"]) - @pytest.mark.parametrize("box", [Series, Index]) def test_api_per_method( - self, box, dtype, any_allowed_skipna_inferred_dtype, any_string_method + self, + index_or_series, + dtype, + any_allowed_skipna_inferred_dtype, + any_string_method, ): # this test does not check correctness of the different methods, # just that the methods work on the specified (inferred) dtypes, # and raise on all others + box = index_or_series # one instance of each parametrized fixture inferred_dtype, values = any_allowed_skipna_inferred_dtype @@ -375,10 +379,10 @@ def test_iter_object_try_string(self): assert i == 100 assert s == "h" - @pytest.mark.parametrize("box", [Series, Index]) @pytest.mark.parametrize("other", [None, Series, Index]) - def test_str_cat_name(self, box, other): + def test_str_cat_name(self, index_or_series, other): # GH 21053 + box = index_or_series values = ["a", "b"] if other: other = other(values) @@ -387,8 +391,8 @@ def test_str_cat_name(self, box, other): result = box(values, name="name").str.cat(other, sep=",") assert result.name == "name" - @pytest.mark.parametrize("box", [Series, Index]) - def test_str_cat(self, box): + def test_str_cat(self, index_or_series): + box = index_or_series # test_cat above tests "str_cat" from ndarray; # here testing "str.cat" from Series/Indext to ndarray/list s = box(["a", "a", "b", "b", "c", np.nan]) @@ -427,9 +431,9 @@ def test_str_cat(self, box): with pytest.raises(ValueError, match=rgx): s.str.cat(list(z)) - @pytest.mark.parametrize("box", [Series, Index]) - def test_str_cat_raises_intuitive_error(self, box): + def test_str_cat_raises_intuitive_error(self, index_or_series): # GH 11334 + box = index_or_series s = box(["a", "b", "c", "d"]) message = "Did you mean to supply a `sep` keyword?" with pytest.raises(ValueError, match=message): @@ -440,8 +444,11 @@ def test_str_cat_raises_intuitive_error(self, box): @pytest.mark.parametrize("sep", ["", None]) @pytest.mark.parametrize("dtype_target", ["object", "category"]) @pytest.mark.parametrize("dtype_caller", ["object", "category"]) - @pytest.mark.parametrize("box", [Series, Index]) - def test_str_cat_categorical(self, box, dtype_caller, dtype_target, sep): + def test_str_cat_categorical( + self, index_or_series, dtype_caller, dtype_target, sep + ): + box = index_or_series + s = Index(["a", "a", "b", "a"], dtype=dtype_caller) s = s if box == Index else Series(s, index=s) t = Index(["b", "a", "b", "c"], dtype=dtype_target) @@ -494,8 +501,8 @@ def test_str_cat_wrong_dtype_raises(self, box, data): # need to use outer and na_rep, as otherwise Index would not raise s.str.cat(t, join="outer", na_rep="-") - @pytest.mark.parametrize("box", [Series, Index]) - def test_str_cat_mixed_inputs(self, box): + def test_str_cat_mixed_inputs(self, index_or_series): + box = index_or_series s = Index(["a", "b", "c", "d"]) s = s if box == Index else Series(s, index=s) @@ -596,9 +603,10 @@ def test_str_cat_mixed_inputs(self, box): s.str.cat(iter([t.values, list(s)])) @pytest.mark.parametrize("join", ["left", "outer", "inner", "right"]) - @pytest.mark.parametrize("box", [Series, Index]) - def test_str_cat_align_indexed(self, box, join): + def test_str_cat_align_indexed(self, index_or_series, join): # https://github.com/pandas-dev/pandas/issues/18657 + box = index_or_series + s = Series(["a", "b", "c", "d"], index=["a", "b", "c", "d"]) t = Series(["D", "A", "E", "B"], index=["d", "a", "e", "b"]) sa, ta = s.align(t, join=join) @@ -656,10 +664,14 @@ def test_str_cat_align_mixed_inputs(self, join): with pytest.raises(ValueError, match=rgx): s.str.cat([t, z], join=join) - @pytest.mark.parametrize("box", [Series, Index]) - @pytest.mark.parametrize("other", [Series, Index]) - def test_str_cat_all_na(self, box, other): + index_or_series2 = [Series, Index] # type: ignore + # List item 0 has incompatible type "Type[Series]"; expected "Type[PandasObject]" + # See GH#>???? + + @pytest.mark.parametrize("other", index_or_series2) + def test_str_cat_all_na(self, index_or_series, other): # GH 24044 + box = index_or_series # check that all NaNs in caller / target work s = Index(["a", "b", "c", "d"])