Skip to content

Commit 081254c

Browse files
authored
Merge branch 'pandas-dev:main' into pytz-link
2 parents 186e31c + b876c67 commit 081254c

File tree

13 files changed

+204
-80
lines changed

13 files changed

+204
-80
lines changed

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,7 @@ Indexing
758758
- Bug in :meth:`DataFrame.from_records` throwing a ``ValueError`` when passed an empty list in ``index`` (:issue:`58594`)
759759
- Bug in :meth:`DataFrame.loc` and :meth:`DataFrame.iloc` returning incorrect dtype when selecting from a :class:`DataFrame` with mixed data types. (:issue:`60600`)
760760
- Bug in :meth:`DataFrame.loc` with inconsistent behavior of loc-set with 2 given indexes to Series (:issue:`59933`)
761+
- Bug in :meth:`Index.equals` when comparing between :class:`Series` with string dtype :class:`Index` (:issue:`61099`)
761762
- Bug in :meth:`Index.get_indexer` and similar methods when ``NaN`` is located at or after position 128 (:issue:`58924`)
762763
- Bug in :meth:`MultiIndex.insert` when a new value inserted to a datetime-like level gets cast to ``NaT`` and fails indexing (:issue:`60388`)
763764
- Bug in :meth:`Series.__setitem__` when assigning boolean series with boolean indexer will raise ``LossySetitemError`` (:issue:`57338`)

pandas/core/indexes/base.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5481,11 +5481,7 @@ def equals(self, other: Any) -> bool:
54815481
# quickly return if the lengths are different
54825482
return False
54835483

5484-
if (
5485-
isinstance(self.dtype, StringDtype)
5486-
and self.dtype.na_value is np.nan
5487-
and other.dtype != self.dtype
5488-
):
5484+
if isinstance(self.dtype, StringDtype) and other.dtype != self.dtype:
54895485
# TODO(infer_string) can we avoid this special case?
54905486
# special case for object behavior
54915487
return other.equals(self.astype(object))

pandas/tests/arrays/categorical/test_constructors.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
import numpy as np
77
import pytest
88

9-
from pandas._config import using_string_dtype
10-
11-
from pandas.compat import HAS_PYARROW
12-
139
from pandas.core.dtypes.common import (
1410
is_float_dtype,
1511
is_integer_dtype,
@@ -444,13 +440,12 @@ def test_constructor_str_unknown(self):
444440
with pytest.raises(ValueError, match="Unknown dtype"):
445441
Categorical([1, 2], dtype="foo")
446442

447-
@pytest.mark.xfail(
448-
using_string_dtype() and HAS_PYARROW, reason="Can't be NumPy strings"
449-
)
450443
def test_constructor_np_strs(self):
451444
# GH#31499 Hashtable.map_locations needs to work on np.str_ objects
452-
cat = Categorical(["1", "0", "1"], [np.str_("0"), np.str_("1")])
453-
assert all(isinstance(x, np.str_) for x in cat.categories)
445+
# We can't pass all-strings because the constructor would cast
446+
# those to StringDtype post-PDEP14
447+
cat = Categorical(["1", "0", "1", 2], [np.str_("0"), np.str_("1"), 2])
448+
assert all(isinstance(x, (np.str_, int)) for x in cat.categories)
454449

455450
def test_constructor_from_categorical_with_dtype(self):
456451
dtype = CategoricalDtype(["a", "b", "c"], ordered=True)

pandas/tests/arrays/categorical/test_repr.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import numpy as np
2-
import pytest
3-
4-
from pandas._config import using_string_dtype
52

63
from pandas import (
74
Categorical,
@@ -77,17 +74,19 @@ def test_print_none_width(self):
7774
with option_context("display.width", None):
7875
assert exp == repr(a)
7976

80-
@pytest.mark.skipif(
81-
using_string_dtype(),
82-
reason="Change once infer_string is set to True by default",
83-
)
84-
def test_unicode_print(self):
77+
def test_unicode_print(self, using_infer_string):
8578
c = Categorical(["aaaaa", "bb", "cccc"] * 20)
8679
expected = """\
8780
['aaaaa', 'bb', 'cccc', 'aaaaa', 'bb', ..., 'bb', 'cccc', 'aaaaa', 'bb', 'cccc']
8881
Length: 60
8982
Categories (3, object): ['aaaaa', 'bb', 'cccc']"""
9083

84+
if using_infer_string:
85+
expected = expected.replace(
86+
"(3, object): ['aaaaa', 'bb', 'cccc']",
87+
"(3, str): [aaaaa, bb, cccc]",
88+
)
89+
9190
assert repr(c) == expected
9291

9392
c = Categorical(["ああああ", "いいいいい", "ううううううう"] * 20)
@@ -96,6 +95,12 @@ def test_unicode_print(self):
9695
Length: 60
9796
Categories (3, object): ['ああああ', 'いいいいい', 'ううううううう']""" # noqa: E501
9897

98+
if using_infer_string:
99+
expected = expected.replace(
100+
"(3, object): ['ああああ', 'いいいいい', 'ううううううう']",
101+
"(3, str): [ああああ, いいいいい, ううううううう]",
102+
)
103+
99104
assert repr(c) == expected
100105

101106
# unicode option should not affect to Categorical, as it doesn't care
@@ -106,6 +111,12 @@ def test_unicode_print(self):
106111
Length: 60
107112
Categories (3, object): ['ああああ', 'いいいいい', 'ううううううう']""" # noqa: E501
108113

114+
if using_infer_string:
115+
expected = expected.replace(
116+
"(3, object): ['ああああ', 'いいいいい', 'ううううううう']",
117+
"(3, str): [ああああ, いいいいい, ううううううう]",
118+
)
119+
109120
assert repr(c) == expected
110121

111122
def test_categorical_repr(self):

pandas/tests/frame/methods/test_astype.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import numpy as np
44
import pytest
55

6-
from pandas._config import using_string_dtype
7-
86
import pandas.util._test_decorators as td
97

108
import pandas as pd
@@ -745,10 +743,7 @@ def test_astype_tz_object_conversion(self, tz):
745743
result = result.astype({"tz": "datetime64[ns, Europe/London]"})
746744
tm.assert_frame_equal(result, expected)
747745

748-
@pytest.mark.xfail(using_string_dtype(), reason="TODO(infer_string) GH#60639")
749-
def test_astype_dt64_to_string(
750-
self, frame_or_series, tz_naive_fixture, using_infer_string
751-
):
746+
def test_astype_dt64_to_string(self, frame_or_series, tz_naive_fixture):
752747
# GH#41409
753748
tz = tz_naive_fixture
754749

@@ -766,10 +761,7 @@ def test_astype_dt64_to_string(
766761
item = result.iloc[0]
767762
if frame_or_series is DataFrame:
768763
item = item.iloc[0]
769-
if using_infer_string:
770-
assert item is np.nan
771-
else:
772-
assert item is pd.NA
764+
assert item is pd.NA
773765

774766
# For non-NA values, we should match what we get for non-EA str
775767
alt = obj.astype(str)

pandas/tests/frame/test_arithmetic.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import numpy as np
1212
import pytest
1313

14-
from pandas.compat import HAS_PYARROW
15-
1614
import pandas as pd
1715
from pandas import (
1816
DataFrame,
@@ -2183,19 +2181,14 @@ def test_enum_column_equality():
21832181
tm.assert_series_equal(result, expected)
21842182

21852183

2186-
def test_mixed_col_index_dtype(using_infer_string):
2184+
def test_mixed_col_index_dtype(string_dtype_no_object):
21872185
# GH 47382
21882186
df1 = DataFrame(columns=list("abc"), data=1.0, index=[0])
21892187
df2 = DataFrame(columns=list("abc"), data=0.0, index=[0])
2190-
df1.columns = df2.columns.astype("string")
2188+
df1.columns = df2.columns.astype(string_dtype_no_object)
21912189
result = df1 + df2
21922190
expected = DataFrame(columns=list("abc"), data=1.0, index=[0])
2193-
if using_infer_string:
2194-
# df2.columns.dtype will be "str" instead of object,
2195-
# so the aligned result will be "string", not object
2196-
if HAS_PYARROW:
2197-
dtype = "string[pyarrow]"
2198-
else:
2199-
dtype = "string"
2200-
expected.columns = expected.columns.astype(dtype)
2191+
2192+
expected.columns = expected.columns.astype(string_dtype_no_object)
2193+
22012194
tm.assert_frame_equal(result, expected)

pandas/tests/groupby/test_timegrouper.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
import numpy as np
1212
import pytest
1313

14-
from pandas._config import using_string_dtype
15-
1614
import pandas as pd
1715
from pandas import (
1816
DataFrame,
@@ -76,10 +74,7 @@ def groupby_with_truncated_bingrouper(frame_for_truncated_bingrouper):
7674

7775

7876
class TestGroupBy:
79-
# TODO(infer_string) resample sum introduces 0's
80-
# https://github.com/pandas-dev/pandas/issues/60229
81-
@pytest.mark.xfail(using_string_dtype(), reason="TODO(infer_string)")
82-
def test_groupby_with_timegrouper(self):
77+
def test_groupby_with_timegrouper(self, using_infer_string):
8378
# GH 4161
8479
# TimeGrouper requires a sorted index
8580
# also verifies that the resultant index has the correct name
@@ -116,8 +111,11 @@ def test_groupby_with_timegrouper(self):
116111
{"Buyer": 0, "Quantity": 0},
117112
index=exp_dti,
118113
)
119-
# Cast to object to avoid implicit cast when setting entry to "CarlCarlCarl"
114+
# Cast to object/str to avoid implicit cast when setting
115+
# entry to "CarlCarlCarl"
120116
expected = expected.astype({"Buyer": object})
117+
if using_infer_string:
118+
expected = expected.astype({"Buyer": "str"})
121119
expected.iloc[0, 0] = "CarlCarlCarl"
122120
expected.iloc[6, 0] = "CarlCarl"
123121
expected.iloc[18, 0] = "Joe"

pandas/tests/indexes/base_class/test_formats.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import numpy as np
22
import pytest
33

4-
from pandas._config import using_string_dtype
54
import pandas._config.config as cf
65

76
from pandas import Index
@@ -16,7 +15,6 @@ def test_repr_is_valid_construction_code(self):
1615
res = eval(repr(idx))
1716
tm.assert_index_equal(res, idx)
1817

19-
@pytest.mark.xfail(using_string_dtype(), reason="repr different")
2018
@pytest.mark.parametrize(
2119
"index,expected",
2220
[
@@ -77,11 +75,13 @@ def test_repr_is_valid_construction_code(self):
7775
),
7876
],
7977
)
80-
def test_string_index_repr(self, index, expected):
78+
def test_string_index_repr(self, index, expected, using_infer_string):
8179
result = repr(index)
80+
if using_infer_string:
81+
expected = expected.replace("dtype='object'", "dtype='str'")
82+
8283
assert result == expected
8384

84-
@pytest.mark.xfail(using_string_dtype(), reason="repr different")
8585
@pytest.mark.parametrize(
8686
"index,expected",
8787
[
@@ -121,11 +121,16 @@ def test_string_index_repr(self, index, expected):
121121
),
122122
],
123123
)
124-
def test_string_index_repr_with_unicode_option(self, index, expected):
124+
def test_string_index_repr_with_unicode_option(
125+
self, index, expected, using_infer_string
126+
):
125127
# Enable Unicode option -----------------------------------------
126128
with cf.option_context("display.unicode.east_asian_width", True):
127129
result = repr(index)
128-
assert result == expected
130+
131+
if using_infer_string:
132+
expected = expected.replace("dtype='object'", "dtype='str'")
133+
assert result == expected
129134

130135
def test_repr_summary(self):
131136
with cf.option_context("display.max_seq_items", 10):

pandas/tests/indexes/categorical/test_category.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ def test_unique(self, data, categories, expected_data, ordered):
199199
expected = CategoricalIndex(expected_data, dtype=dtype)
200200
tm.assert_index_equal(idx.unique(), expected)
201201

202+
# TODO(3.0): remove this test once using_string_dtype() is always True
202203
@pytest.mark.xfail(using_string_dtype(), reason="repr doesn't roundtrip")
203204
def test_repr_roundtrip(self):
204205
ci = CategoricalIndex(["a", "b"], categories=["a", "b"], ordered=True)

0 commit comments

Comments
 (0)