From 784ed8157e53eace4288fcd5390b8fd4e8ccc335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Wed, 24 Jan 2024 16:39:29 -0600 Subject: [PATCH 1/9] check for ExtensionType in is_datetime64_any_dtype --- doc/source/whatsnew/v2.2.1.rst | 2 +- pandas/core/dtypes/common.py | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v2.2.1.rst b/doc/source/whatsnew/v2.2.1.rst index 75445c978d262..25744ae73bd51 100644 --- a/doc/source/whatsnew/v2.2.1.rst +++ b/doc/source/whatsnew/v2.2.1.rst @@ -20,7 +20,7 @@ Fixed regressions Bug fixes ~~~~~~~~~ -- +- Bug in :meth:`api.types.is_datetime64_any_dtype` where a custom :class:`ExtensionDtype` would not return ``True`` for array-likes (:issue:`57055`) .. --------------------------------------------------------------------------- .. _whatsnew_221.other: diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 5e5b7bdad74d8..3e43b40bc3f5e 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -890,7 +890,11 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: tipo = _get_dtype(arr_or_dtype) except TypeError: return False - return lib.is_np_dtype(tipo, "M") or isinstance(tipo, DatetimeTZDtype) + return ( + lib.is_np_dtype(tipo, "M") + or isinstance(tipo, DatetimeTZDtype) + or (isinstance(tipo, ExtensionDtype) and tipo.kind == 'M') + ) def is_datetime64_ns_dtype(arr_or_dtype) -> bool: From 89655f4c065770b1f08220fc17be326dd5261650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Wed, 24 Jan 2024 17:05:22 -0600 Subject: [PATCH 2/9] use pre-commit --- pandas/core/dtypes/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 3e43b40bc3f5e..a53bbe9935684 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -893,7 +893,7 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: return ( lib.is_np_dtype(tipo, "M") or isinstance(tipo, DatetimeTZDtype) - or (isinstance(tipo, ExtensionDtype) and tipo.kind == 'M') + or (isinstance(tipo, ExtensionDtype) and tipo.kind == "M") ) From e6b1789f8e9d4046d615344e3fa51417a6dc5560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Thu, 25 Jan 2024 11:02:45 -0600 Subject: [PATCH 3/9] add test and move doc entry --- doc/source/whatsnew/v2.2.1.rst | 2 +- doc/source/whatsnew/v3.0.0.rst | 2 +- pandas/tests/extension/test_arrow.py | 9 +++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v2.2.1.rst b/doc/source/whatsnew/v2.2.1.rst index 25744ae73bd51..75445c978d262 100644 --- a/doc/source/whatsnew/v2.2.1.rst +++ b/doc/source/whatsnew/v2.2.1.rst @@ -20,7 +20,7 @@ Fixed regressions Bug fixes ~~~~~~~~~ -- Bug in :meth:`api.types.is_datetime64_any_dtype` where a custom :class:`ExtensionDtype` would not return ``True`` for array-likes (:issue:`57055`) +- .. --------------------------------------------------------------------------- .. _whatsnew_221.other: diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 950082f9281c5..4a9073544a966 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -118,7 +118,7 @@ Bug fixes ~~~~~~~~~ - Fixed bug in :meth:`DataFrame.join` inconsistently setting result index name (:issue:`55815`) - Fixed bug in :meth:`Series.diff` allowing non-integer values for the ``periods`` argument. (:issue:`56607`) -- +- Fixed bug in :meth:`api.types.is_datetime64_any_dtype` where a custom :class:`ExtensionDtype` would not return ``True`` for array-likes (:issue:`57055`) Categorical ^^^^^^^^^^^ diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index 6970c589dd36f..f9a41d29d1a24 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -53,6 +53,7 @@ from pandas.api.extensions import no_default from pandas.api.types import ( is_bool_dtype, + is_datetime64_any_dtype, is_float_dtype, is_integer_dtype, is_numeric_dtype, @@ -1531,6 +1532,14 @@ def test_is_unsigned_integer_dtype(data): assert not is_unsigned_integer_dtype(data) +def test_is_datetime64_any_dtype(data): + pa_type = data.dtype.pyarrow_dtype + if pa.types.is_timestamp(pa_type): + assert is_datetime64_any_dtype(data) + else: + assert not is_datetime64_any_dtype(data) + + def test_is_float_dtype(data): pa_type = data.dtype.pyarrow_dtype if pa.types.is_floating(pa_type): From 3b85fe6b13f0dcef75b1889bafe43d0b41fa3976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Thu, 25 Jan 2024 11:50:59 -0600 Subject: [PATCH 4/9] check not date in test --- pandas/tests/extension/test_arrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index f9a41d29d1a24..98ca310616175 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -1534,7 +1534,7 @@ def test_is_unsigned_integer_dtype(data): def test_is_datetime64_any_dtype(data): pa_type = data.dtype.pyarrow_dtype - if pa.types.is_timestamp(pa_type): + if pa.types.is_timestamp(pa_type) and not pa.types.is_date(pa_type): assert is_datetime64_any_dtype(data) else: assert not is_datetime64_any_dtype(data) From 623cd240a5fc8e4d8783b28a4a98c4f19462d3b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Thu, 25 Jan 2024 11:54:58 -0600 Subject: [PATCH 5/9] fix condition --- pandas/tests/extension/test_arrow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index 98ca310616175..62e4629ca7cb7 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -1534,7 +1534,7 @@ def test_is_unsigned_integer_dtype(data): def test_is_datetime64_any_dtype(data): pa_type = data.dtype.pyarrow_dtype - if pa.types.is_timestamp(pa_type) and not pa.types.is_date(pa_type): + if pa.types.is_timestamp(pa_type) or pa.types.is_date(pa_type): assert is_datetime64_any_dtype(data) else: assert not is_datetime64_any_dtype(data) From bbbb2fa8f72f3a1ec235433858652e4e04a9a310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Thu, 25 Jan 2024 12:41:18 -0600 Subject: [PATCH 6/9] check type is not datetime.date --- pandas/core/dtypes/common.py | 13 +++++++++++-- pandas/tests/extension/test_arrow.py | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index a53bbe9935684..fb6eac9308890 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -3,6 +3,7 @@ """ from __future__ import annotations +import datetime from typing import ( TYPE_CHECKING, Any, @@ -881,7 +882,11 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: """ if isinstance(arr_or_dtype, (np.dtype, ExtensionDtype)): # GH#33400 fastpath for dtype object - return arr_or_dtype.kind == "M" + if isinstance(arr_or_dtype, np.dtype): + return arr_or_dtype.kind == "M" + return arr_or_dtype.kind == "M" and not isinstance( + arr_or_dtype.type, datetime.date + ) if arr_or_dtype is None: return False @@ -893,7 +898,11 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: return ( lib.is_np_dtype(tipo, "M") or isinstance(tipo, DatetimeTZDtype) - or (isinstance(tipo, ExtensionDtype) and tipo.kind == "M") + or ( + isinstance(tipo, ExtensionDtype) + and tipo.kind == "M" + and not isinstance(tipo.type, datetime.date) + ) ) diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index 62e4629ca7cb7..f9a41d29d1a24 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -1534,7 +1534,7 @@ def test_is_unsigned_integer_dtype(data): def test_is_datetime64_any_dtype(data): pa_type = data.dtype.pyarrow_dtype - if pa.types.is_timestamp(pa_type) or pa.types.is_date(pa_type): + if pa.types.is_timestamp(pa_type): assert is_datetime64_any_dtype(data) else: assert not is_datetime64_any_dtype(data) From c1aa67454861405e9027e19c863f03019451114c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Thu, 25 Jan 2024 13:49:56 -0600 Subject: [PATCH 7/9] fix comparison --- pandas/core/dtypes/common.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index fb6eac9308890..d7c9c14a55e9b 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -884,9 +884,7 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: # GH#33400 fastpath for dtype object if isinstance(arr_or_dtype, np.dtype): return arr_or_dtype.kind == "M" - return arr_or_dtype.kind == "M" and not isinstance( - arr_or_dtype.type, datetime.date - ) + return arr_or_dtype.kind == "M" and arr_or_dtype.type != datetime.date if arr_or_dtype is None: return False @@ -901,7 +899,7 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: or ( isinstance(tipo, ExtensionDtype) and tipo.kind == "M" - and not isinstance(tipo.type, datetime.date) + and tipo.type != datetime.date ) ) From 734bb030abb5a7a51aa98e2f852f7b197412c354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Wed, 31 Jan 2024 11:59:33 -0600 Subject: [PATCH 8/9] move description to ExtensionArray --- doc/source/whatsnew/v3.0.0.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 4a9073544a966..2244c0428f70d 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -118,7 +118,6 @@ Bug fixes ~~~~~~~~~ - Fixed bug in :meth:`DataFrame.join` inconsistently setting result index name (:issue:`55815`) - Fixed bug in :meth:`Series.diff` allowing non-integer values for the ``periods`` argument. (:issue:`56607`) -- Fixed bug in :meth:`api.types.is_datetime64_any_dtype` where a custom :class:`ExtensionDtype` would not return ``True`` for array-likes (:issue:`57055`) Categorical ^^^^^^^^^^^ @@ -207,7 +206,7 @@ Sparse ExtensionArray ^^^^^^^^^^^^^^ -- +- Fixed bug in :meth:`api.types.is_datetime64_any_dtype` where a custom :class:`ExtensionDtype` would return ``False`` for array-likes and ``True`` for date types (:issue:`57055`) - Styler From 178c0621bbe2da9eec7d643847e176dd780a919f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Morales?= Date: Wed, 31 Jan 2024 14:08:55 -0600 Subject: [PATCH 9/9] return True for date types --- doc/source/whatsnew/v3.0.0.rst | 2 +- pandas/core/dtypes/common.py | 11 ++--------- pandas/tests/extension/test_arrow.py | 2 +- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 2244c0428f70d..9cc377ac6797f 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -206,7 +206,7 @@ Sparse ExtensionArray ^^^^^^^^^^^^^^ -- Fixed bug in :meth:`api.types.is_datetime64_any_dtype` where a custom :class:`ExtensionDtype` would return ``False`` for array-likes and ``True`` for date types (:issue:`57055`) +- Fixed bug in :meth:`api.types.is_datetime64_any_dtype` where a custom :class:`ExtensionDtype` would return ``False`` for array-likes (:issue:`57055`) - Styler diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index d7c9c14a55e9b..a53bbe9935684 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -3,7 +3,6 @@ """ from __future__ import annotations -import datetime from typing import ( TYPE_CHECKING, Any, @@ -882,9 +881,7 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: """ if isinstance(arr_or_dtype, (np.dtype, ExtensionDtype)): # GH#33400 fastpath for dtype object - if isinstance(arr_or_dtype, np.dtype): - return arr_or_dtype.kind == "M" - return arr_or_dtype.kind == "M" and arr_or_dtype.type != datetime.date + return arr_or_dtype.kind == "M" if arr_or_dtype is None: return False @@ -896,11 +893,7 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: return ( lib.is_np_dtype(tipo, "M") or isinstance(tipo, DatetimeTZDtype) - or ( - isinstance(tipo, ExtensionDtype) - and tipo.kind == "M" - and tipo.type != datetime.date - ) + or (isinstance(tipo, ExtensionDtype) and tipo.kind == "M") ) diff --git a/pandas/tests/extension/test_arrow.py b/pandas/tests/extension/test_arrow.py index f9a41d29d1a24..62e4629ca7cb7 100644 --- a/pandas/tests/extension/test_arrow.py +++ b/pandas/tests/extension/test_arrow.py @@ -1534,7 +1534,7 @@ def test_is_unsigned_integer_dtype(data): def test_is_datetime64_any_dtype(data): pa_type = data.dtype.pyarrow_dtype - if pa.types.is_timestamp(pa_type): + if pa.types.is_timestamp(pa_type) or pa.types.is_date(pa_type): assert is_datetime64_any_dtype(data) else: assert not is_datetime64_any_dtype(data)