Skip to content

Commit 06cdcc0

Browse files
authored
BUG: is_string_dtype(pd.Index([], dtype='O')) returns False (#54997)
* correct def is_all_strings * add a test, correct whatsnew/v2.2.0.rst * move the test and add parametrization, correct v2.2.0.rst * remove the line from v2.2.0.rst * add the note to v2.1.1.rst * correct the whatsnew note and move it to 2.2.0
1 parent da01e38 commit 06cdcc0

File tree

3 files changed

+24
-11
lines changed

3 files changed

+24
-11
lines changed

doc/source/whatsnew/v2.2.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ Bug fixes
279279
~~~~~~~~~
280280
- Bug in :class:`AbstractHolidayCalendar` where timezone data was not propagated when computing holiday observances (:issue:`54580`)
281281
- Bug in :class:`pandas.core.window.Rolling` where duplicate datetimelike indexes are treated as consecutive rather than equal with ``closed='left'`` and ``closed='neither'`` (:issue:`20712`)
282+
- Bug in :func:`pandas.api.types.is_string_dtype` while checking object array with no elements is of the string dtype (:issue:`54661`)
282283
- Bug in :meth:`DataFrame.apply` where passing ``raw=True`` ignored ``args`` passed to the applied function (:issue:`55009`)
283284
- Bug in :meth:`pandas.DataFrame.melt` where it would not preserve the datetime (:issue:`55254`)
284285
- Bug in :meth:`pandas.read_excel` with a ODS file without cached formatted cell for float values (:issue:`55219`)

pandas/core/dtypes/common.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -1664,9 +1664,12 @@ def is_all_strings(value: ArrayLike) -> bool:
16641664
dtype = value.dtype
16651665

16661666
if isinstance(dtype, np.dtype):
1667-
return dtype == np.dtype("object") and lib.is_string_array(
1668-
np.asarray(value), skipna=False
1669-
)
1667+
if len(value) == 0:
1668+
return dtype == np.dtype("object")
1669+
else:
1670+
return dtype == np.dtype("object") and lib.is_string_array(
1671+
np.asarray(value), skipna=False
1672+
)
16701673
elif isinstance(dtype, CategoricalDtype):
16711674
return dtype.categories.inferred_type == "string"
16721675
return dtype == "string"

pandas/tests/dtypes/test_common.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -301,14 +301,23 @@ def test_is_categorical_dtype():
301301
assert com.is_categorical_dtype(pd.CategoricalIndex([1, 2, 3]))
302302

303303

304-
def test_is_string_dtype():
305-
assert not com.is_string_dtype(int)
306-
assert not com.is_string_dtype(pd.Series([1, 2]))
307-
308-
assert com.is_string_dtype(str)
309-
assert com.is_string_dtype(object)
310-
assert com.is_string_dtype(np.array(["a", "b"]))
311-
assert com.is_string_dtype(pd.StringDtype())
304+
@pytest.mark.parametrize(
305+
"dtype, expected",
306+
[
307+
(int, False),
308+
(pd.Series([1, 2]), False),
309+
(str, True),
310+
(object, True),
311+
(np.array(["a", "b"]), True),
312+
(pd.StringDtype(), True),
313+
(pd.Index([], dtype="O"), True),
314+
],
315+
)
316+
def test_is_string_dtype(dtype, expected):
317+
# GH#54661
318+
319+
result = com.is_string_dtype(dtype)
320+
assert result is expected
312321

313322

314323
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)