Skip to content

Commit 556b791

Browse files
TomAugspurgerjreback
authored andcommitted
BUG/API: Raise when extension class passed to astype (pandas-dev#17796)
Closes pandas-dev#17780
1 parent 22515f5 commit 556b791

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ Conversion
768768
- Bug in :attr:`Timestamp.weekday_name` returning a UTC-based weekday name when localized to a timezone (:issue:`17354`)
769769
- Bug in ``Timestamp.replace`` when replacing ``tzinfo`` around DST changes (:issue:`15683`)
770770
- Bug in ``Timedelta`` construction and arithmetic that would not propagate the ``Overflow`` exception (:issue:`17367`)
771+
- Bug in :meth:`~DataFrame.astype` converting to object dtype when passeed extension type classes (`DatetimeTZDtype``, ``CategoricalDtype``) rather than instances. Now a ``TypeError`` is raised when a class is passed (:issue:`17780`).
771772

772773
Indexing
773774
^^^^^^^^

pandas/core/internals.py

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import warnings
22
import copy
33
from warnings import catch_warnings
4+
import inspect
45
import itertools
56
import re
67
import operator
@@ -552,6 +553,11 @@ def _astype(self, dtype, copy=False, errors='raise', values=None,
552553
list(errors_legal_values), errors))
553554
raise ValueError(invalid_arg)
554555

556+
if inspect.isclass(dtype) and issubclass(dtype, ExtensionDtype):
557+
msg = ("Expected an instance of {}, but got the class instead. "
558+
"Try instantiating 'dtype'.".format(dtype.__name__))
559+
raise TypeError(msg)
560+
555561
# may need to convert to categorical
556562
# this is only called for non-categoricals
557563
if self.is_categorical_astype(dtype):

pandas/tests/frame/test_dtypes.py

+14
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,20 @@ def test_astype_duplicate_col(self):
612612
expected = concat([a1_str, b, a2_str], axis=1)
613613
assert_frame_equal(result, expected)
614614

615+
@pytest.mark.parametrize("cls", [
616+
pd.api.types.CategoricalDtype,
617+
pd.api.types.DatetimeTZDtype,
618+
pd.api.types.IntervalDtype
619+
])
620+
def test_astype_categoricaldtype_class_raises(self, cls):
621+
df = DataFrame({"A": ['a', 'a', 'b', 'c']})
622+
xpr = "Expected an instance of {}".format(cls.__name__)
623+
with tm.assert_raises_regex(TypeError, xpr):
624+
df.astype({"A": cls})
625+
626+
with tm.assert_raises_regex(TypeError, xpr):
627+
df['A'].astype(cls)
628+
615629
def test_timedeltas(self):
616630
df = DataFrame(dict(A=Series(date_range('2012-1-1', periods=3,
617631
freq='D')),

0 commit comments

Comments
 (0)