From 92f0e2e6aeee5220f2532f616a84890e81123e74 Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 17:00:28 +0000 Subject: [PATCH 01/10] timezonedtypemismatcherror --- pandas/core/arrays/datetimes.py | 4 ++-- pandas/core/dtypes/cast.py | 14 +++++++------- pandas/errors/__init__.py | 11 +++++++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 64d0347aa815e..9f0fd9858d26a 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -45,7 +45,7 @@ tzconversion, ) from pandas._libs.tslibs.dtypes import abbrev_to_npy_unit -from pandas.errors import PerformanceWarning +from pandas.errors import PerformanceWarning, TimezoneDtypeMismatchError from pandas.util._exceptions import find_stack_level from pandas.util._validators import validate_inclusive @@ -2830,7 +2830,7 @@ def _validate_tz_from_dtype( # We also need to check for the case where the user passed a # tz-naive dtype (i.e. datetime64[ns]) if tz is not None and not timezones.tz_compare(tz, dtz): - raise ValueError( + raise TimezoneDtypeMismatchError( "cannot supply both a tz and a " "timezone-naive dtype (i.e. datetime64[ns])" ) diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index 3b615c70ebea2..abb31d6df04d3 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -45,6 +45,7 @@ from pandas.errors import ( IntCastingNaNError, LossySetitemError, + TimezoneDtypeMismatchError, ) from pandas.core.dtypes.common import ( @@ -1095,16 +1096,15 @@ def maybe_cast_to_datetime( else: try: dta = DatetimeArray._from_sequence(value, dtype=dtype) - except ValueError as err: - # We can give a Series-specific exception message. - if "cannot supply both a tz and a timezone-naive dtype" in str(err): - raise ValueError( + except TimezoneDtypeMismatchError as err: + raise ValueError( "Cannot convert timezone-aware data to " "timezone-naive dtype. Use " "pd.Series(values).dt.tz_localize(None) instead." - ) from err - raise - + ) from err + except ValueError: + raise + return dta diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index 8c26744f171c3..01e47e122f428 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -1038,6 +1038,16 @@ class InvalidComparison(Exception): """ +class TimezoneDtypeMismatchError(ValueError): + """ + Raised when both a separate tz and a tz-naive numpy datetime64 dtype are + supplied (e.g. tz is not None and dtype is datetime64[ns]). + + Use case / message: + "cannot supply both a tz and a timezone-naive dtype (i.e. datetime64[ns])" + """ + + __all__ = [ "AbstractMethodError", "AttributeConflictWarning", @@ -1081,6 +1091,7 @@ class InvalidComparison(Exception): "PyperclipException", "PyperclipWindowsException", "SpecificationError", + "TimezoneDtypeMismatchError", "UndefinedVariableError", "UnsortedIndexError", "UnsupportedFunctionCall", From 0fb8210c5eb7aea45467a6e4c13f573f7ac69f63 Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 17:07:38 +0000 Subject: [PATCH 02/10] updated test --- pandas/tests/indexes/datetimes/test_constructors.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py index c418b2a18008b..bef6eb7b85dda 100644 --- a/pandas/tests/indexes/datetimes/test_constructors.py +++ b/pandas/tests/indexes/datetimes/test_constructors.py @@ -31,6 +31,7 @@ ) import pandas._testing as tm from pandas.core.arrays import period_array +from pandas.errors import TimezoneDtypeMismatchError class TestDatetimeIndex: @@ -709,7 +710,7 @@ def test_constructor_dtype_tz_mismatch_raises(self): "cannot supply both a tz and a timezone-naive dtype " r"\(i\.e\. datetime64\[ns\]\)" ) - with pytest.raises(ValueError, match=msg): + with pytest.raises(TimezoneDtypeMismatchError, match=msg): DatetimeIndex(idx, dtype="datetime64[ns]") # this is effectively trying to convert tz's From 5814dd3f095759532551f2db6246b2f9fd7f2604 Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 17:23:13 +0000 Subject: [PATCH 03/10] ruff --- pandas/errors/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index 01e47e122f428..2f31184451474 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -1047,7 +1047,6 @@ class TimezoneDtypeMismatchError(ValueError): "cannot supply both a tz and a timezone-naive dtype (i.e. datetime64[ns])" """ - __all__ = [ "AbstractMethodError", "AttributeConflictWarning", From 0df537f09c9150443fd9892e994b0352da5edaa5 Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 17:59:32 +0000 Subject: [PATCH 04/10] case --- doc/source/reference/testing.rst | 1 + pandas/errors/__init__.py | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/source/reference/testing.rst b/doc/source/reference/testing.rst index 65b20b70ca317..5746e468a9a83 100644 --- a/doc/source/reference/testing.rst +++ b/doc/source/reference/testing.rst @@ -66,6 +66,7 @@ Exceptions and warnings errors.PyperclipException errors.PyperclipWindowsException errors.SpecificationError + errors.TimezoneDtypeMismatchError errors.UndefinedVariableError errors.UnsortedIndexError errors.UnsupportedFunctionCall diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index 2f31184451474..01e47e122f428 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -1047,6 +1047,7 @@ class TimezoneDtypeMismatchError(ValueError): "cannot supply both a tz and a timezone-naive dtype (i.e. datetime64[ns])" """ + __all__ = [ "AbstractMethodError", "AttributeConflictWarning", From 564d041c60f87c06e72714ca1c0c95d0deb2fa5d Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 18:10:14 +0000 Subject: [PATCH 05/10] isort --- pandas/tests/indexes/datetimes/test_constructors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py index bef6eb7b85dda..593b4d8c70088 100644 --- a/pandas/tests/indexes/datetimes/test_constructors.py +++ b/pandas/tests/indexes/datetimes/test_constructors.py @@ -19,6 +19,7 @@ astype_overflowsafe, timezones, ) +from pandas.errors import TimezoneDtypeMismatchError import pandas as pd from pandas import ( @@ -31,7 +32,6 @@ ) import pandas._testing as tm from pandas.core.arrays import period_array -from pandas.errors import TimezoneDtypeMismatchError class TestDatetimeIndex: From 8ca039314052d9a94174f7ef43738d068f53e0f3 Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 21:25:24 +0000 Subject: [PATCH 06/10] pre-commit --- pandas/core/arrays/datetimes.py | 5 ++++- pandas/core/dtypes/cast.py | 12 ++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 9f0fd9858d26a..d6a28d4c9d164 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -45,7 +45,10 @@ tzconversion, ) from pandas._libs.tslibs.dtypes import abbrev_to_npy_unit -from pandas.errors import PerformanceWarning, TimezoneDtypeMismatchError +from pandas.errors import ( + PerformanceWarning, + TimezoneDtypeMismatchError, +) from pandas.util._exceptions import find_stack_level from pandas.util._validators import validate_inclusive diff --git a/pandas/core/dtypes/cast.py b/pandas/core/dtypes/cast.py index abb31d6df04d3..e56a0061b2e17 100644 --- a/pandas/core/dtypes/cast.py +++ b/pandas/core/dtypes/cast.py @@ -1098,13 +1098,13 @@ def maybe_cast_to_datetime( dta = DatetimeArray._from_sequence(value, dtype=dtype) except TimezoneDtypeMismatchError as err: raise ValueError( - "Cannot convert timezone-aware data to " - "timezone-naive dtype. Use " - "pd.Series(values).dt.tz_localize(None) instead." - ) from err + "Cannot convert timezone-aware data to " + "timezone-naive dtype. Use " + "pd.Series(values).dt.tz_localize(None) instead." + ) from err except ValueError: - raise - + raise + return dta From 5a4c70c19f77f48bb5d5381d80e482d37c6cebb7 Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 22:11:59 +0000 Subject: [PATCH 07/10] ruff --- pandas/errors/__init__.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index 01e47e122f428..b901a0db6c85e 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -1045,6 +1045,15 @@ class TimezoneDtypeMismatchError(ValueError): Use case / message: "cannot supply both a tz and a timezone-naive dtype (i.e. datetime64[ns])" + + Examples + -------- + >>> from pandas.core.arrays import datetimes # doctest: +SKIP + >>> datetimes._validate_tz_from_dtype("datetime64[ns]", tz="UTC") # doctest: +SKIP + Traceback (most recent call last): + ... + TimezoneDtypeMismatchError: cannot supply both a tz and a timezone-naive dtype + (i.e. datetime64[ns]) """ From c76b1744a8ba0035866298c65b40d1316d8c3bf6 Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 22:40:12 +0000 Subject: [PATCH 08/10] precommit --- pandas/errors/__init__.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index b901a0db6c85e..f503abb7cc035 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -1040,12 +1040,18 @@ class InvalidComparison(Exception): class TimezoneDtypeMismatchError(ValueError): """ - Raised when both a separate tz and a tz-naive numpy datetime64 dtype are - supplied (e.g. tz is not None and dtype is datetime64[ns]). + Raised when a tz is supplied with a timezone-naive numpy datetime64 dtype. Use case / message: "cannot supply both a tz and a timezone-naive dtype (i.e. datetime64[ns])" + See Also + -------- + pandas.core.dtypes.dtypes.DatetimeTZDtype : Datetime dtype with an associated + timezone. + pandas.core.arrays.datetimes._validate_tz_from_dtype : Validation helper that may + raise this error. + Examples -------- >>> from pandas.core.arrays import datetimes # doctest: +SKIP From 7b09f73b371746e98a0866f5bbe673bb228b870e Mon Sep 17 00:00:00 2001 From: Lirong Date: Sun, 19 Oct 2025 23:28:30 +0000 Subject: [PATCH 09/10] fix seel also --- pandas/errors/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index f503abb7cc035..42e80c60d095d 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -1047,9 +1047,8 @@ class TimezoneDtypeMismatchError(ValueError): See Also -------- - pandas.core.dtypes.dtypes.DatetimeTZDtype : Datetime dtype with an associated - timezone. - pandas.core.arrays.datetimes._validate_tz_from_dtype : Validation helper that may + core.dtypes.dtypes.DatetimeTZDtype : Datetime dtype with an associated timezone. + core.arrays.datetimes._validate_tz_from_dtype : Validation helper that may raise this error. Examples From 225c7a4d318146e5c1115f1b8e7ff81c136edb19 Mon Sep 17 00:00:00 2001 From: Lirong Date: Mon, 20 Oct 2025 01:00:22 +0000 Subject: [PATCH 10/10] fix see also --- pandas/errors/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/errors/__init__.py b/pandas/errors/__init__.py index 42e80c60d095d..6e556a84d6e65 100644 --- a/pandas/errors/__init__.py +++ b/pandas/errors/__init__.py @@ -1049,7 +1049,7 @@ class TimezoneDtypeMismatchError(ValueError): -------- core.dtypes.dtypes.DatetimeTZDtype : Datetime dtype with an associated timezone. core.arrays.datetimes._validate_tz_from_dtype : Validation helper that may - raise this error. + raise this error. Examples --------