77from pandas ._libs .tslibs import NaT , iNaT , period as libperiod
88from pandas ._libs .tslibs .fields import isleapyear_arr
99from pandas ._libs .tslibs .period import (
10- DIFFERENT_FREQ_INDEX , IncompatibleFrequency , Period , get_period_field_arr ,
10+ DIFFERENT_FREQ , IncompatibleFrequency , Period , get_period_field_arr ,
1111 period_asfreq_arr )
1212from pandas ._libs .tslibs .timedeltas import Timedelta , delta_to_nanoseconds
1313import pandas .compat as compat
3030from pandas .core .missing import backfill_1d , pad_1d
3131
3232from pandas .tseries import frequencies
33- from pandas .tseries .offsets import Tick
33+ from pandas .tseries .offsets import DateOffset , Tick , _delta_to_tick
3434
3535
3636def _field_accessor (name , alias , docstring = None ):
@@ -166,8 +166,9 @@ def __init__(self, values, freq=None, dtype=None, copy=False):
166166
167167 if isinstance (values , type (self )):
168168 if freq is not None and freq != values .freq :
169- msg = DIFFERENT_FREQ_INDEX .format (values .freq .freqstr ,
170- freq .freqstr )
169+ msg = DIFFERENT_FREQ .format (cls = type (self ).__name__ ,
170+ own_freq = values .freq .freqstr ,
171+ other_freq = freq .freqstr )
171172 raise IncompatibleFrequency (msg )
172173 values , freq = values ._data , values .freq
173174
@@ -239,8 +240,7 @@ def _generate_range(cls, start, end, periods, freq, fields):
239240
240241 def _check_compatible_with (self , other ):
241242 if self .freqstr != other .freqstr :
242- msg = DIFFERENT_FREQ_INDEX .format (self .freqstr , other .freqstr )
243- raise IncompatibleFrequency (msg )
243+ _raise_on_incompatible (self , other )
244244
245245 # --------------------------------------------------------------------
246246 # Data / Attributes
@@ -372,15 +372,13 @@ def __setitem__(
372372 value = period_array (value )
373373
374374 if self .freqstr != value .freqstr :
375- msg = DIFFERENT_FREQ_INDEX .format (self .freqstr , value .freqstr )
376- raise IncompatibleFrequency (msg )
375+ _raise_on_incompatible (self , value )
377376
378377 value = value .asi8
379378 elif isinstance (value , Period ):
380379
381380 if self .freqstr != value .freqstr :
382- msg = DIFFERENT_FREQ_INDEX .format (self .freqstr , value .freqstr )
383- raise IncompatibleFrequency (msg )
381+ _raise_on_incompatible (self , value )
384382
385383 value = value .ordinal
386384 elif isna (value ):
@@ -696,8 +694,7 @@ def _add_offset(self, other):
696694 assert not isinstance (other , Tick )
697695 base = frequencies .get_base_alias (other .rule_code )
698696 if base != self .freq .rule_code :
699- msg = DIFFERENT_FREQ_INDEX .format (self .freqstr , other .freqstr )
700- raise IncompatibleFrequency (msg )
697+ _raise_on_incompatible (self , other )
701698
702699 # Note: when calling parent class's _add_timedeltalike_scalar,
703700 # it will call delta_to_nanoseconds(delta). Because delta here
@@ -760,10 +757,7 @@ def _add_delta(self, other):
760757 """
761758 if not isinstance (self .freq , Tick ):
762759 # We cannot add timedelta-like to non-tick PeriodArray
763- raise IncompatibleFrequency ("Input has different freq from "
764- "{cls}(freq={freqstr})"
765- .format (cls = type (self ).__name__ ,
766- freqstr = self .freqstr ))
760+ _raise_on_incompatible (self , other )
767761
768762 new_ordinals = super (PeriodArray , self )._add_delta (other )
769763 return type (self )(new_ordinals , freq = self .freq )
@@ -815,10 +809,7 @@ def _check_timedeltalike_freq_compat(self, other):
815809 # by which will be added to self.
816810 return delta
817811
818- raise IncompatibleFrequency ("Input has different freq from "
819- "{cls}(freq={freqstr})"
820- .format (cls = type (self ).__name__ ,
821- freqstr = self .freqstr ))
812+ _raise_on_incompatible (self , other )
822813
823814 def _values_for_argsort (self ):
824815 return self ._data
@@ -827,6 +818,34 @@ def _values_for_argsort(self):
827818PeriodArray ._add_comparison_ops ()
828819
829820
821+ def _raise_on_incompatible (left , right ):
822+ """
823+ Helper function to render a consistent error message when raising
824+ IncompatibleFrequency.
825+
826+ Parameters
827+ ----------
828+ left : PeriodArray
829+ right : DateOffset, Period, ndarray, or timedelta-like
830+
831+ Raises
832+ ------
833+ IncompatibleFrequency
834+ """
835+ # GH#24283 error message format depends on whether right is scalar
836+ if isinstance (right , np .ndarray ):
837+ other_freq = None
838+ elif isinstance (right , (ABCPeriodIndex , PeriodArray , Period , DateOffset )):
839+ other_freq = right .freqstr
840+ else :
841+ other_freq = _delta_to_tick (Timedelta (right )).freqstr
842+
843+ msg = DIFFERENT_FREQ .format (cls = type (left ).__name__ ,
844+ own_freq = left .freqstr ,
845+ other_freq = other_freq )
846+ raise IncompatibleFrequency (msg )
847+
848+
830849# -------------------------------------------------------------------
831850# Constructor Helpers
832851
0 commit comments