Skip to content

Commit 4b18266

Browse files
authored
API: IncompatibleFrequency subclass TypeError (#61875)
1 parent 6fca116 commit 4b18266

File tree

12 files changed

+22
-19
lines changed

12 files changed

+22
-19
lines changed

ci/code_checks.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ if [[ -z "$CHECK" || "$CHECK" == "docstrings" ]]; then
7474
-i "pandas.Series.dt PR01" `# Accessors are implemented as classes, but we do not document the Parameters section` \
7575
-i "pandas.Period.freq GL08" \
7676
-i "pandas.Period.ordinal GL08" \
77+
-i "pandas.errors.IncompatibleFrequency SA01,SS06,EX01" \
7778
-i "pandas.core.groupby.DataFrameGroupBy.plot PR02" \
7879
-i "pandas.core.groupby.SeriesGroupBy.plot PR02" \
7980
-i "pandas.core.resample.Resampler.quantile PR01,PR07" \

doc/source/reference/testing.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Exceptions and warnings
3636
errors.DuplicateLabelError
3737
errors.EmptyDataError
3838
errors.IncompatibilityWarning
39+
errors.IncompatibleFrequency
3940
errors.IndexingError
4041
errors.InvalidColumnName
4142
errors.InvalidComparison

doc/source/whatsnew/v3.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ Other API changes
414414
- Index set operations (like union or intersection) will now ignore the dtype of
415415
an empty ``RangeIndex`` or empty ``Index`` with object dtype when determining
416416
the dtype of the resulting Index (:issue:`60797`)
417+
- :class:`IncompatibleFrequency` now subclasses ``TypeError`` instead of ``ValueError``. As a result, joins with mismatched frequencies now cast to object like other non-comparable joins, and arithmetic with indexes with mismatched frequencies align (:issue:`55782`)
417418
- Comparison operations between :class:`Index` and :class:`Series` now consistently return :class:`Series` regardless of which object is on the left or right (:issue:`36759`)
418419
- Numpy functions like ``np.isinf`` that return a bool dtype when called on a :class:`Index` object now return a bool-dtype :class:`Index` instead of ``np.ndarray`` (:issue:`52676`)
419420

pandas/_libs/tslibs/period.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ from pandas._typing import (
1515
INVALID_FREQ_ERR_MSG: str
1616
DIFFERENT_FREQ: str
1717

18-
class IncompatibleFrequency(ValueError): ...
18+
class IncompatibleFrequency(TypeError): ...
1919

2020
def periodarr_to_dt64arr(
2121
periodarr: npt.NDArray[np.int64], # const int64_t[:]

pandas/_libs/tslibs/period.pyx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,11 @@ DIFFERENT_FREQ = ("Input has different freq={other_freq} "
16251625
"from {cls}(freq={own_freq})")
16261626

16271627

1628-
class IncompatibleFrequency(ValueError):
1628+
class IncompatibleFrequency(TypeError):
1629+
"""
1630+
Raised when trying to compare or operate between Periods with different
1631+
frequencies.
1632+
"""
16291633
pass
16301634

16311635

pandas/core/arrays/datetimelike.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ def _validate_comparison_value(self, other):
544544
other = self._scalar_type(other)
545545
try:
546546
self._check_compatible_with(other)
547-
except (TypeError, IncompatibleFrequency) as err:
547+
except TypeError as err:
548548
# e.g. tzawareness mismatch
549549
raise InvalidComparison(other) from err
550550

@@ -558,7 +558,7 @@ def _validate_comparison_value(self, other):
558558
try:
559559
other = self._validate_listlike(other, allow_object=True)
560560
self._check_compatible_with(other)
561-
except (TypeError, IncompatibleFrequency) as err:
561+
except TypeError as err:
562562
if is_object_dtype(getattr(other, "dtype", None)):
563563
# We will have to operate element-wise
564564
pass

pandas/core/indexes/base.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
no_default,
3939
)
4040
from pandas._libs.tslibs import (
41-
IncompatibleFrequency,
4241
OutOfBoundsDatetime,
4342
Timestamp,
4443
tz_compare,
@@ -3139,7 +3138,7 @@ def _union(self, other: Index, sort: bool | None):
31393138
# test_union_same_value_duplicated_in_both fails)
31403139
try:
31413140
return self._outer_indexer(other)[0]
3142-
except (TypeError, IncompatibleFrequency):
3141+
except TypeError:
31433142
# incomparable objects; should only be for object dtype
31443143
value_list = list(lvals)
31453144

pandas/errors/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from pandas._config.config import OptionError
1010

1111
from pandas._libs.tslibs import (
12+
IncompatibleFrequency,
1213
OutOfBoundsDatetime,
1314
OutOfBoundsTimedelta,
1415
)
@@ -917,6 +918,7 @@ class InvalidComparison(Exception):
917918
"DuplicateLabelError",
918919
"EmptyDataError",
919920
"IncompatibilityWarning",
921+
"IncompatibleFrequency",
920922
"IndexingError",
921923
"IntCastingNaNError",
922924
"InvalidColumnName",

pandas/tests/indexes/period/test_indexing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ def test_get_indexer2(self):
502502
)
503503

504504
msg = "Input has different freq=None from PeriodArray\\(freq=h\\)"
505-
with pytest.raises(ValueError, match=msg):
505+
with pytest.raises(libperiod.IncompatibleFrequency, match=msg):
506506
idx.get_indexer(target, "nearest", tolerance="1 minute")
507507

508508
tm.assert_numpy_array_equal(

pandas/tests/indexes/period/test_join.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import numpy as np
2-
import pytest
3-
4-
from pandas._libs.tslibs import IncompatibleFrequency
52

63
from pandas import (
74
DataFrame,
@@ -51,8 +48,9 @@ def test_join_does_not_recur(self):
5148
tm.assert_index_equal(res, expected)
5249

5350
def test_join_mismatched_freq_raises(self):
51+
# pre-GH#55782 this raises IncompatibleFrequency
5452
index = period_range("1/1/2000", "1/20/2000", freq="D")
5553
index3 = period_range("1/1/2000", "1/20/2000", freq="2D")
56-
msg = r".*Input has different freq=2D from Period\(freq=D\)"
57-
with pytest.raises(IncompatibleFrequency, match=msg):
58-
index.join(index3)
54+
result = index.join(index3)
55+
expected = index.astype(object).join(index3.astype(object))
56+
tm.assert_index_equal(result, expected)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy