Skip to content

Commit fe67b94

Browse files
TomAugspurgerjreback
authored andcommitted
Update type for PeriodDtype / DatetimeTZDtype / IntervalDtype (pandas-dev#22938)
1 parent b12e5ba commit fe67b94

File tree

5 files changed

+30
-42
lines changed

5 files changed

+30
-42
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@ ExtensionType Changes
505505
- :meth:`Series.astype` and :meth:`DataFrame.astype` now dispatch to :meth:`ExtensionArray.astype` (:issue:`21185:`).
506506
- Slicing a single row of a ``DataFrame`` with multiple ExtensionArrays of the same type now preserves the dtype, rather than coercing to object (:issue:`22784`)
507507
- Added :meth:`pandas.api.types.register_extension_dtype` to register an extension type with pandas (:issue:`22664`)
508+
- Updated the ``.type`` attribute for ``PeriodDtype``, ``DatetimeTZDtype``, and ``IntervalDtype`` to be instances of the dtype (``Period``, ``Timestamp``, and ``Interval`` respectively) (:issue:`22938`)
508509

509510
.. _whatsnew_0240.api.incompatibilities:
510511

pandas/core/dtypes/base.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,9 @@ def type(self):
181181
"""The scalar type for the array, e.g. ``int``
182182
183183
It's expected ``ExtensionArray[item]`` returns an instance
184-
of ``ExtensionDtype.type`` for scalar ``item``.
184+
of ``ExtensionDtype.type`` for scalar ``item``, assuming
185+
that value is valid (not NA). NA values do not need to be
186+
instances of `type`.
185187
"""
186188
raise AbstractMethodError(self)
187189

pandas/core/dtypes/common.py

+10-9
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
from pandas.compat import (string_types, text_type, binary_type,
55
PY3, PY36)
66
from pandas._libs import algos, lib
7-
from pandas._libs.tslibs import conversion
7+
from pandas._libs.tslibs import conversion, Period, Timestamp
8+
from pandas._libs.interval import Interval
89

910
from pandas.core.dtypes.dtypes import (
1011
registry, CategoricalDtype, CategoricalDtypeType, DatetimeTZDtype,
11-
DatetimeTZDtypeType, PeriodDtype, PeriodDtypeType, IntervalDtype,
12-
IntervalDtypeType, PandasExtensionDtype, ExtensionDtype,
12+
PeriodDtype, IntervalDtype,
13+
PandasExtensionDtype, ExtensionDtype,
1314
_pandas_registry)
1415
from pandas.core.dtypes.generic import (
1516
ABCCategorical, ABCPeriodIndex, ABCDatetimeIndex, ABCSeries,
@@ -1905,20 +1906,20 @@ def _get_dtype_type(arr_or_dtype):
19051906
elif isinstance(arr_or_dtype, CategoricalDtype):
19061907
return CategoricalDtypeType
19071908
elif isinstance(arr_or_dtype, DatetimeTZDtype):
1908-
return DatetimeTZDtypeType
1909+
return Timestamp
19091910
elif isinstance(arr_or_dtype, IntervalDtype):
1910-
return IntervalDtypeType
1911+
return Interval
19111912
elif isinstance(arr_or_dtype, PeriodDtype):
1912-
return PeriodDtypeType
1913+
return Period
19131914
elif isinstance(arr_or_dtype, string_types):
19141915
if is_categorical_dtype(arr_or_dtype):
19151916
return CategoricalDtypeType
19161917
elif is_datetime64tz_dtype(arr_or_dtype):
1917-
return DatetimeTZDtypeType
1918+
return Timestamp
19181919
elif is_period_dtype(arr_or_dtype):
1919-
return PeriodDtypeType
1920+
return Period
19201921
elif is_interval_dtype(arr_or_dtype):
1921-
return IntervalDtypeType
1922+
return Interval
19221923
return _get_dtype_type(np.dtype(arr_or_dtype))
19231924
try:
19241925
return arr_or_dtype.dtype.type

pandas/core/dtypes/dtypes.py

+10-26
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import numpy as np
55
from pandas import compat
66
from pandas.core.dtypes.generic import ABCIndexClass, ABCCategoricalIndex
7+
from pandas._libs.tslibs import Period, NaT, Timestamp
8+
from pandas._libs.interval import Interval
79

810
from .base import ExtensionDtype, _DtypeOpsMixin
911

@@ -469,13 +471,6 @@ def _is_boolean(self):
469471
return is_bool_dtype(self.categories)
470472

471473

472-
class DatetimeTZDtypeType(type):
473-
"""
474-
the type of DatetimeTZDtype, this metaclass determines subclass ability
475-
"""
476-
pass
477-
478-
479474
class DatetimeTZDtype(PandasExtensionDtype):
480475

481476
"""
@@ -485,7 +480,7 @@ class DatetimeTZDtype(PandasExtensionDtype):
485480
THIS IS NOT A REAL NUMPY DTYPE, but essentially a sub-class of
486481
np.datetime64[ns]
487482
"""
488-
type = DatetimeTZDtypeType
483+
type = Timestamp
489484
kind = 'M'
490485
str = '|M8[ns]'
491486
num = 101
@@ -583,20 +578,13 @@ def __eq__(self, other):
583578
str(self.tz) == str(other.tz))
584579

585580

586-
class PeriodDtypeType(type):
587-
"""
588-
the type of PeriodDtype, this metaclass determines subclass ability
589-
"""
590-
pass
591-
592-
593581
class PeriodDtype(PandasExtensionDtype):
594582
"""
595583
A Period duck-typed class, suitable for holding a period with freq dtype.
596584
597585
THIS IS NOT A REAL NUMPY DTYPE, but essentially a sub-class of np.int64.
598586
"""
599-
type = PeriodDtypeType
587+
type = Period
600588
kind = 'O'
601589
str = '|O08'
602590
base = np.dtype('O')
@@ -666,11 +654,15 @@ def construct_from_string(cls, string):
666654
raise TypeError("could not construct PeriodDtype")
667655

668656
def __unicode__(self):
669-
return "period[{freq}]".format(freq=self.freq.freqstr)
657+
return compat.text_type(self.name)
670658

671659
@property
672660
def name(self):
673-
return str(self)
661+
return str("period[{freq}]".format(freq=self.freq.freqstr))
662+
663+
@property
664+
def na_value(self):
665+
return NaT
674666

675667
def __hash__(self):
676668
# make myself hashable
@@ -705,13 +697,6 @@ def is_dtype(cls, dtype):
705697
return super(PeriodDtype, cls).is_dtype(dtype)
706698

707699

708-
class IntervalDtypeType(type):
709-
"""
710-
the type of IntervalDtype, this metaclass determines subclass ability
711-
"""
712-
pass
713-
714-
715700
@register_extension_dtype
716701
class IntervalDtype(PandasExtensionDtype, ExtensionDtype):
717702
"""
@@ -800,7 +785,6 @@ def construct_from_string(cls, string):
800785

801786
@property
802787
def type(self):
803-
from pandas import Interval
804788
return Interval
805789

806790
def __unicode__(self):

pandas/tests/dtypes/test_common.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -605,15 +605,15 @@ def test__get_dtype_fails(input_param):
605605
(pd.DatetimeIndex([1, 2]), np.datetime64),
606606
(pd.DatetimeIndex([1, 2]).dtype, np.datetime64),
607607
('<M8[ns]', np.datetime64),
608-
(pd.DatetimeIndex([1, 2], tz='Europe/London'), com.DatetimeTZDtypeType),
608+
(pd.DatetimeIndex([1, 2], tz='Europe/London'), pd.Timestamp),
609609
(pd.DatetimeIndex([1, 2], tz='Europe/London').dtype,
610-
com.DatetimeTZDtypeType),
611-
('datetime64[ns, Europe/London]', com.DatetimeTZDtypeType),
610+
pd.Timestamp),
611+
('datetime64[ns, Europe/London]', pd.Timestamp),
612612
(pd.SparseSeries([1, 2], dtype='int32'), np.int32),
613613
(pd.SparseSeries([1, 2], dtype='int32').dtype, np.int32),
614-
(PeriodDtype(freq='D'), com.PeriodDtypeType),
615-
('period[D]', com.PeriodDtypeType),
616-
(IntervalDtype(), com.IntervalDtypeType),
614+
(PeriodDtype(freq='D'), pd.Period),
615+
('period[D]', pd.Period),
616+
(IntervalDtype(), pd.Interval),
617617
(None, type(None)),
618618
(1, type(None)),
619619
(1.2, type(None)),

0 commit comments

Comments
 (0)