U
    c                     @  s  d dl mZ d dlmZ d dlZd dlmZmZmZm	Z	m
Z
mZmZ d dlZd dlmZmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZm Z!m"Z" d dl#m$Z$ d d	l%m&Z& d d
l'm(Z(m)Z) d dl*m+Z+m,Z,m-Z-m.Z.m/Z/ d dl0m1Z1m2Z2m3Z3m4Z4 d dl5m6Z6m7Z7 d dl8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@ d dlAmBZB d dlCmDZDmEZEmFZFmGZG d dlHmIZI d dlJmK  mLZ d dlMmNZO d dlPmK  mQZR erd dl0mSZSmTZT d dlMmUZUmVZV d dlWmXZX ededZYddiZZd=ddddZ[G dd deOj\e!j]Z^dd  Z_d>d"d#d$dd%d&d'Z`eddd(d)d*Zaed+d,d(d-d*Zad.dd(d/d*Zad?d0d1d2d3Zd@d5d6ZbdAd7d1d8d9Zcd:d1d;d<ZddS )B    )annotations)	timedeltaN)TYPE_CHECKINGAnyCallableLiteralSequenceTypeVaroverload)algoslib)NDArrayBacked)
BaseOffsetNaTNaTType	Timedeltaastype_overflowsafedt64arr_to_periodarrget_unit_from_dtypeiNaTparsingperiod	to_offset)	FreqGroup)isleapyear_arr)Tickdelta_to_tick)DIFFERENT_FREQIncompatibleFrequencyPeriodget_period_field_arrperiod_asfreq_arr)AnyArrayLikeDtypeNpDtypenpt)cache_readonlydoc)ensure_objectis_datetime64_any_dtypeis_datetime64_dtypeis_dtype_equalis_float_dtypeis_integer_dtypeis_period_dtypepandas_dtype)PeriodDtype)ABCIndexABCPeriodIndex	ABCSeriesABCTimedeltaArray)isna)datetimelike)NumpySorterNumpyValueArrayLike)DatetimeArrayTimedeltaArray)ExtensionArrayBaseOffsetT)boundklassPeriodArraystrnamec                   s     fdd} |_ ||_t|S )Nc                   s   | j j}t | j|}|S N)freq_period_dtype_coder    asi8)selfbaseresultrA    =/tmp/pip-unpacked-wheel-g7fro6k3/pandas/core/arrays/period.pyfi   s    z_field_accessor.<locals>.f)__name____doc__property)rB   Z	docstringrL   rJ   rA   rK   _field_accessorh   s    rP   c                      s  e Zd ZU dZdZdZeeZ	e
fZeZdZeddddZg Zd	ed
< dgZd	ed< dddgZd	ed< dddddddddddddddd d!gZd	ed"< ee e Zd	ed#< d$d%d&gZd	ed'< d(ed)< dd,d-d.d/d0d1Zedd2d3d,d d4d5d6Zed*d+d7d8d9d,d-d d:d;d<Zed*d+d7d,d-d d/d=d>Zedd dd?d@ZedAdB ZddCd-dDdEdFdGZdHdIdJdKdLZ dd-dMdNdOZ!e"d(ddPdQZ#edRddSdTZ$ddUd2dVdWdXZ%ddYdZZ&e'dd[Z(e'dd\Z)e'dd]Z*e'dd^Z+e'dd_Z,e'dd`Z-e'ddaZ.e.Z/e'ddbZ0e0Z1e1Z2e'ddc Z3Z4e'dddZ5e'dZ6e'd deZ7e7Z8ed2ddfdgZ9ddHdidjdkdlZ:ddmd dndodpZ;dCddqdrZ<e=f e>dsdsdtddHd djdvdwZ?dd-dxdydzZ@eAjBd{d*d|d}dd~dZCdd-d fddZDddddddddZEdd d fddZFd ddHd dddZGddd dddZHdRdddZI fddZJdd dddZKdd ZL  ZMS )r?   a)  
    Pandas ExtensionArray for storing Period data.

    Users should use :func:`~pandas.period_array` to create new instances.
    Alternatively, :func:`~pandas.array` can be used to create new instances
    from a sequence of Period scalars.

    Parameters
    ----------
    values : Union[PeriodArray, Series[period], ndarray[int], PeriodIndex]
        The data to store. These should be arrays that can be directly
        converted to ordinals without inference or copy (PeriodArray,
        ndarray[int64]), or a box around such an array (Series[period],
        PeriodIndex).
    dtype : PeriodDtype, optional
        A PeriodDtype instance from which to extract a `freq`. If both
        `freq` and `dtype` are specified, then the frequencies must match.
    freq : str or DateOffset
        The `freq` to use for the array. Mostly applicable when `values`
        is an ndarray of integers, when `freq` is required. When `values`
        is a PeriodArray (or box around), it's checked that ``values.freq``
        matches `freq`.
    copy : bool, default False
        Whether to copy the ordinals before storing.

    Attributes
    ----------
    None

    Methods
    -------
    None

    See Also
    --------
    Period: Represents a period of time.
    PeriodIndex : Immutable Index for period data.
    period_range: Create a fixed-frequency PeriodArray.
    array: Construct a pandas array.

    Notes
    -----
    There are two components to a PeriodArray

    - ordinals : integer ndarray
    - freq : pd.tseries.offsets.Offset

    The values are physically stored as a 1-D ndarray of integers. These are
    called "ordinals" and represent some kind of offset from a base.

    The `freq` indicates the span covered by each element of the array.
    All elements in the PeriodArray have the same `freq`.
    i  Zperiodarray)r   ztype[Period]returnc                 C  s   t S rC   )r   rG   rJ   rJ   rK   _scalar_type   s    zPeriodArray._scalar_typez	list[str]
_other_opsis_leap_year	_bool_ops
start_timeZend_timerD   _object_opsyearmonthdayhourminutesecond
weekofyearweekdayweek	dayofweekday_of_week	dayofyearday_of_yearquarterqyeardays_in_monthdaysinmonth
_field_ops_datetimelike_opsstrftimeto_timestampasfreq_datetimelike_methodsr0   _dtypeNFzDtype | NoneboolNone)dtypecopyrR   c                 C  s   t ||}|d k	rt|}t|trD|j}t|t| sTtdnt|trT|j}t|t| r|d k	r~||j	kr~t
|||j|j	 }}tj|d|d}|d krtdt| |t| d S )NzIncorrect dtypeint64rt   ru   z,freq is not specified and cannot be inferred)validate_dtype_freqr   _maybe_convert_freq
isinstancer3   _valuestype	TypeErrorr2   rD   raise_on_incompatible_ndarraynparray
ValueErrorr   __init__r0   )rG   valuesrt   rD   ru   rJ   rJ   rK   r      s"    





zPeriodArray.__init__z
np.ndarrayzBaseOffset | None)r   rD   rt   rR   c                 C  s0   d}t |tjr|jdks"t|| |||dS )Nz Should be numpy array of type i8i8)rD   rt   )rz   r   ndarrayrt   AssertionError)clsr   rD   rt   Zassertion_msgrJ   rJ   rK   _simple_new   s    zPeriodArray._simple_newrw   ztype[PeriodArray]z&Sequence[Period | None] | AnyArrayLike)r   scalarsrt   ru   rR   c                C  st   |rt |tr|j}nd }t || r@t|j| |r<| }|S tj|td}|pZt	
|}t	||}| ||dS )Nrt   rD   )rz   r0   rD   rx   rt   ru   r   asarrayobject	libperiodZextract_freqZextract_ordinals)r   r   rt   ru   rD   periodsordinalsrJ   rJ   rK   _from_sequence   s    
zPeriodArray._from_sequencec                C  s   | j |||dS )Nrw   )r   )r   stringsrt   ru   rJ   rJ   rK   _from_sequence_of_strings  s    z%PeriodArray._from_sequence_of_stringsc                 C  s   t |||\}}| ||dS )a  
        Construct a PeriodArray from a datetime64 array

        Parameters
        ----------
        data : ndarray[datetime64[ns], datetime64[ns, tz]]
        freq : str or Tick
        tz : tzinfo, optional

        Returns
        -------
        PeriodArray[freq]
        r   )r   )r   datarD   tzrJ   rJ   rK   _from_datetime64  s    zPeriodArray._from_datetime64c                 C  s   t |}|d k	rt|}t|}|d k	s4|d k	rX|dkrDtdt||||\}}n(|dkrxtf d|i|\}}ntd||fS )Nr   z=Can either instantiate from fields or endpoints, but not bothrD   z/Not enough parameters to construct Period range)dtlZvalidate_periodsr   ry   lenr   _get_ordinal_range_range_from_fields)r   startendr   rD   fieldsZfield_countZsubarrrJ   rJ   rK   _generate_range-  s    

zPeriodArray._generate_rangezPeriod | NaTTypeznp.int64)valuesetitemrR   c                 C  sN   |t krt|jS t|| jr:| j||d t|jS td| dd S )Nr   z!'value' should be a Period. Got 'z
' instead.)	r   r   rv   r   rz   rT   _check_compatible_withordinalr   )rG   r   r   rJ   rJ   rK   _unbox_scalarH  s    zPeriodArray._unbox_scalarr@   r   )r   rR   c                 C  s   t || jdS )Nr   )r   rD   )rG   r   rJ   rJ   rK   _scalar_from_stringV  s    zPeriodArray._scalar_from_stringr   c                 C  s   |t krd S | | d S rC   )r   _require_matching_freq)rG   otherr   rJ   rJ   rK   r   Y  s    z"PeriodArray._check_compatible_withc                 C  s   | j S rC   )rq   rS   rJ   rJ   rK   rt   a  s    zPeriodArray.dtyper   c                 C  s   | j jS )zC
        Return the frequency object for this PeriodArray.
        rt   rD   rS   rJ   rJ   rK   rD   f  s    zPeriodArray.freqzNpDtype | None)rt   rR   c                 C  s0   |dkr| j S |tkr| j S tjt| tdS )Nr   r   )rF   rr   _isnanr   r   listr   )rG   rt   rJ   rJ   rK   	__array__m  s
    zPeriodArray.__array__c                 C  s   ddl }ddlm} |dk	r|j|r>|j| j|  |dS t||rp| j	|j
krtd| j	 d|j
 dntd| d	|| j	}|j| j|  d
d}|j||S )z6
        Convert myself into a pyarrow Array.
        r   N)ArrowPeriodType)maskr|   zENot supported to convert PeriodArray to array with different 'freq' (z vs )z)Not supported to convert PeriodArray to 'z' typerv   )pyarrowZ(pandas.core.arrays.arrow.extension_typesr   types
is_integerr   r   r5   rz   freqstrrD   r}   r;   Zfrom_storage)rG   r|   r   r   Zperiod_typeZstorage_arrayrJ   rJ   rK   __arrow_array__v  s     


zPeriodArray.__arrow_array__z)
        The year of the period.
        z6
        The month as January=1, December=12.
        z)
        The days of the period.
        z)
        The hour of the period.
        z+
        The minute of the period.
        z+
        The second of the period.
        z/
        The week ordinal of the year.
        z>
        The day of the week with Monday=0, Sunday=6.
        z.
        The ordinal day of the year.
        z*
        The quarter of the date.
        z2
        The number of days in the month.
        c                 C  s   t t| jS )zH
        Logical indicating if the date belongs to a leap year.
        )r   r   r   rZ   rS   rJ   rJ   rK   rV     s    zPeriodArray.is_leap_yearr   r9   )howrR   c                 C  s2  ddl m} t|}|dk}|rx|dks4| jdkrXtddtdd }| jdd	| S tdd}| | j jdd	| S |d
kr| j }|}nt	
|}|j}| j||d	}t|j|}||}	| jjdkr$t| j}
t|
dkr |
d }|| jjkr| j|	_n|dkr | jj|	_|	S |	dS d
S )a  
        Cast to DatetimeArray/Index.

        Parameters
        ----------
        freq : str or DateOffset, optional
            Target frequency. The default is 'D' for week or longer,
            'S' otherwise.
        how : {'s', 'e', 'start', 'end'}
            Whether to use the start or end of the time period being converted.

        Returns
        -------
        DatetimeArray/Index
        r   )r9   EB   Dnsr   )r   NZinfer)pandas.core.arraysr9   r   validate_end_aliasrD   r   rn   rq   Z_get_to_timestamp_baser   ry   rE   ro   Zperiodarr_to_dt64arrrF   rB   libalgosZunique_deltasr   nZ_freqrH   Z
_with_freq)rG   rD   r   r9   r   adjustrH   Znew_parrnew_datadtaZdiffsZdiffrJ   rJ   rK   rn     s6    






zPeriodArray.to_timestampint)r   rR   c                 C  s&   |dk	rt dt| j d| | S )a  
        Shift each value by `periods`.

        Note this is different from ExtensionArray.shift, which
        shifts the *position* of each element, padding the end with
        missing values.

        Parameters
        ----------
        periods : int
            Number of periods to shift by.
        freq : pandas.DateOffset, pandas.Timedelta, or str
            Frequency increment to shift by.
        Nz%`freq` argument is not supported for z._time_shift)r}   r|   rM   )rG   r   rD   rJ   rJ   rK   _time_shift  s
    zPeriodArray._time_shiftc                 C  s   t j|| jdS )N)r   rD   )r   Z_from_ordinalrD   )rG   xrJ   rJ   rK   	_box_func4  s    zPeriodArray._box_funcZPeriodIndex)r   Z
other_namer   c           	      C  sx   t |}t|}| jj}|j}| j}|dk}|rF|| jj	 d }n|}t
||||}| jrht|| j< t| ||dS )a  
        Convert the {klass} to the specified frequency `freq`.

        Equivalent to applying :meth:`pandas.Period.asfreq` with the given arguments
        to each :class:`~pandas.Period` in this {klass}.

        Parameters
        ----------
        freq : str
            A frequency.
        how : str {{'E', 'S'}}, default 'E'
            Whether the elements should be aligned to the end
            or start within pa period.

            * 'E', 'END', or 'FINISH' for end,
            * 'S', 'START', or 'BEGIN' for start.

            January 31st ('END') vs. January 1st ('START') for example.

        Returns
        -------
        {klass}
            The transformed {klass} with the new frequency.

        See Also
        --------
        {other}.asfreq: Convert each Period in a {other_name} to the given frequency.
        Period.asfreq : Convert a :class:`~pandas.Period` object to the given frequency.

        Examples
        --------
        >>> pidx = pd.period_range('2010-01-01', '2015-01-01', freq='A')
        >>> pidx
        PeriodIndex(['2010', '2011', '2012', '2013', '2014', '2015'],
        dtype='period[A-DEC]')

        >>> pidx.asfreq('M')
        PeriodIndex(['2010-12', '2011-12', '2012-12', '2013-12', '2014-12',
        '2015-12'], dtype='period[M]')

        >>> pidx.asfreq('M', how='S')
        PeriodIndex(['2010-01', '2011-01', '2012-01', '2013-01', '2014-01',
        '2015-01'], dtype='period[M]')
        r   r   r   )r   r   r   ry   rq   Z_dtype_coderE   rF   rD   r   r!   _hasnar   r   r|   )	rG   rD   r   Zbase1Zbase2rF   r   r   r   rJ   rJ   rK   ro   7  s    .


zPeriodArray.asfreq)boxedc                 C  s   |rt S djS )Nz'{}')r@   format)rG   r   rJ   rJ   rK   
_formatter~  s    zPeriodArray._formatterr   )na_repdate_formatznpt.NDArray[np.object_]c                  s|   |  t} r fddndd | jr`| j}|||< | }tfdd|| D ||< ntfdd|D }|S )z3
        actually format my specific types
        c                   s
   |   S rC   )rm   per)r   rJ   rK   <lambda>      z2PeriodArray._format_native_types.<locals>.<lambda>c                 S  s   t | S rC   )r@   r   rJ   rJ   rK   r     r   c                   s   g | ]} |qS rJ   rJ   .0r   	formatterrJ   rK   
<listcomp>  s     z4PeriodArray._format_native_types.<locals>.<listcomp>c                   s   g | ]} |qS rJ   rJ   r   r   rJ   rK   r     s     )astyper   r   r   r   r   )rG   r   r   kwargsr   r   ZimaskrJ   )r   r   rK   _format_native_types  s    
"z PeriodArray._format_native_typesTru   c                   sj   t |}t|| jr$|s| S |  S t|r8| |jS t|rZt|dd }| 	 
|S t j||dS )Nr   r   )r/   r+   rq   ru   r.   ro   rD   r)   getattrrn   Ztz_localizesuperr   )rG   rt   ru   r   	__class__rJ   rK   r     s    zPeriodArray.astypeleftz$NumpyValueArrayLike | ExtensionArrayzLiteral[('left', 'right')]r7   znpt.NDArray[np.intp] | np.intp)r   sidesorterrR   c                 C  s,   |  |d}| jd}|j|||dS )NM8[ns])r   r   )Z_validate_searchsorted_valueviewr   searchsorted)rG   r   r   r   ZnpvalueZm8arrrJ   rJ   rK   r     s    zPeriodArray.searchsortedc                   s@   |d k	r.|  d}|j|||d}| | jS t j|||dS )Nr   )r   methodlimit)r   fillnart   r   )rG   r   r   r   r   rI   r   rJ   rK   r     s
    
zPeriodArray.fillnaznpt.NDArray[np.float64])rG   qsinterpolationrR   c                 C  s   |  d||}| | jS )Nr   )r   	_quantilert   )rG   r   r   ZdtresrJ   rJ   rK   r     s    zPeriodArray._quantileznp.ndarray | intzCallable[[Any, Any], Any])r   oprR   c                 C  sJ   |t jt jfkst|t jkr$| }tj| j|| jd}t| || j	dS )a$  
        Add or subtract array of integers; equivalent to applying
        `_time_shift` pointwise.

        Parameters
        ----------
        other : np.ndarray[int64] or int
        op : {operator.add, operator.sub}

        Returns
        -------
        result : PeriodArray
        )arr_maskr   )
operatoraddsubr   r   checked_add_with_arrrF   r   r|   rD   )rG   r   r   
res_valuesrJ   rJ   rK   _addsub_int_array_or_scalar  s
    
z'PeriodArray._addsub_int_array_or_scalar)r   c                 C  s,   t |trt| j|dd | |jtjS )NT)rH   )rz   r   r   r   r   r   r   r   )rG   r   rJ   rJ   rK   _add_offset  s    zPeriodArray._add_offsetc                   sD   t | jtst| |t|r*t |S tt	|j
}| |S )z
        Parameters
        ----------
        other : timedelta, Tick, np.timedelta64

        Returns
        -------
        PeriodArray
        )rz   rD   r   r~   r5   r   _add_timedeltalike_scalarr   r   r   asm8_add_timedelta_arraylike)rG   r   tdr   rJ   rK   r     s    

z%PeriodArray._add_timedeltalike_scalarz,TimedeltaArray | npt.NDArray[np.timedelta64])r   rR   c              
   C  s   | j }t|ts td| j td|j d}ztt||ddd}W n, t	k
rz } zt
d|W 5 d}~X Y nX t|}tj| j|d| j|d	}t|| j|B t t| || j d
S )z
        Parameters
        ----------
        other : TimedeltaArray or ndarray[timedelta64]

        Returns
        -------
        PeriodArray
        z2Cannot add or subtract timedelta64[ns] dtype from m8[]Frt   ru   Zround_okznCannot add/subtract timedelta-like from PeriodArray that is not an integer multiple of the PeriodArray's freq.Nr   )r   b_maskr   )rD   rz   r   r}   rt   r   
_td64_unitr   r   r   r   Zisnatr   r   rF   r   r   Zputmaskr   r|   )rG   r   rD   rt   deltaerrr   r   rJ   rJ   rK   r     s8    

   

   z$PeriodArray._add_timedelta_arraylikec              
   C  s   t | jtsttd| jj d}t |ttjtfrJt	t
|j}n
t	|}zt||ddd}W n. tk
r } zt| ||W 5 d}~X Y nX |d}t|S )a<  
        Arithmetic operations with timedelta-like scalars or array `other`
        are only valid if `other` is an integer multiple of `self.freq`.
        If the operation is valid, find that integer multiple.  Otherwise,
        raise because the operation is invalid.

        Parameters
        ----------
        other : timedelta, np.timedelta64, Tick,
                ndarray[timedelta64], TimedeltaArray, TimedeltaIndex

        Returns
        -------
        multiple : int or ndarray[int64]

        Raises
        ------
        IncompatibleFrequency
        r   r   Fr   Nr   )rz   rD   r   r   r   rt   r   r   Ztimedelta64r   r   r   r   r   r~   r   r   Zitem_from_zerodim)rG   r   rt   r   r   r   rJ   rJ   rK    _check_timedeltalike_freq_compat1  s    

z,PeriodArray._check_timedeltalike_freq_compat)NNF)NN)N)F)F)N)N)Nr   )N)Nr   )F)T)r   N)NNN)NrM   
__module____qualname__rN   Z__array_priority__Z_typr   rv   r   Z_internal_fill_valuer   Z_recognized_scalarsr.   Z_is_recognized_dtypeZ_infer_matchesrO   rT   rU   __annotations__rW   rY   rk   rl   rp   r   classmethodr   r   r   r   r   r   r   r   r&   rt   rD   r   r   rP   rZ   r[   r\   r]   r^   r_   r`   rb   rd   rc   ra   re   rf   rg   rh   ri   rj   rV   rn   r   r   r'   _shared_doc_kwargsro   r   r   Zravel_compatr   r   r   r   r   r   r   r   r   r   __classcell__rJ   rJ   r   rK   r?   s   s  
7
        
 	
;F   
)c                 C  sf   t |tjtfs|dkrd}n(t |ttttfr8|j}nt	t
|j}tjt| j| j|d}t|S )a>  
    Helper function to render a consistent error message when raising
    IncompatibleFrequency.

    Parameters
    ----------
    left : PeriodArray
    right : None, DateOffset, Period, ndarray, or timedelta-like

    Returns
    -------
    IncompatibleFrequency
        Exception to be raised by the caller.
    N)r   Zown_freq
other_freq)rz   r   r   r4   r2   r?   r   r   r   r   r   r   r   r|   rM   r   )r   rightr  msgrJ   rJ   rK   r~   W  s      r~   Fz,Sequence[Period | str | None] | AnyArrayLikezstr | Tick | Nonerr   )r   rD   ru   rR   c                 C  s   t | dd}t|r t| |S t|r4t| |dS t| tjtt	t
fsPt| } t| }|rht|}nd}t|rt|dkrtdt|jr|jtjdd}t||}t||dS t|} tj| |dS )	a  
    Construct a new PeriodArray from a sequence of Period scalars.

    Parameters
    ----------
    data : Sequence of Period objects
        A sequence of Period objects. These are required to all have
        the same ``freq.`` Missing values can be indicated by ``None``
        or ``pandas.NaT``.
    freq : str, Tick, or Offset
        The frequency of every element of the array. This can be specified
        to avoid inferring the `freq` from `data`.
    copy : bool, default False
        Whether to ensure a copy of the data is made.

    Returns
    -------
    PeriodArray

    See Also
    --------
    PeriodArray
    pandas.PeriodIndex

    Examples
    --------
    >>> period_array([pd.Period('2017', freq='A'),
    ...               pd.Period('2018', freq='A')])
    <PeriodArray>
    ['2017', '2018']
    Length: 2, dtype: period[A-DEC]

    >>> period_array([pd.Period('2017', freq='A'),
    ...               pd.Period('2018', freq='A'),
    ...               pd.NaT])
    <PeriodArray>
    ['2017', '2018', 'NaT']
    Length: 3, dtype: period[A-DEC]

    Integers that look like years are handled

    >>> period_array([2000, 2001, 2002], freq='D')
    <PeriodArray>
    ['2000-01-01', '2001-01-01', '2002-01-01']
    Length: 3, dtype: period[D]

    Datetime-like strings may also be passed

    >>> period_array(['2000-Q1', '2000-Q2', '2000-Q3', '2000-Q4'], freq='Q')
    <PeriodArray>
    ['2000Q1', '2000Q2', '2000Q3', '2000Q4']
    Length: 4, dtype: period[Q-DEC]
    rt   Nr   r   z9PeriodIndex does not allow floating point in constructionFr   r   )r   r*   r?   r   r.   rz   r   r   r   tupler3   r   r0   r,   r   r}   r-   rt   r   rv   r   Zfrom_ordinalsr(   r   )r   rD   ru   Z
data_dtypeZarrdatart   Zarrr   rJ   rJ   rK   period_arrayx  s&    :


r  )rD   rR   c                 C  s   d S rC   rJ   r   rJ   rJ   rK   rx     s    rx   ztimedelta | str | Noner   c                 C  s   d S rC   rJ   r   rJ   rJ   rK   rx     s    z$BaseOffsetT | timedelta | str | Nonec                 C  sV   |dk	rt |}| dk	rRt| } t| s0td|dkr@| j}n|| jkrRtd|S )at  
    If both a dtype and a freq are available, ensure they match.  If only
    dtype is available, extract the implied freq.

    Parameters
    ----------
    dtype : dtype
    freq : DateOffset or None

    Returns
    -------
    freq : DateOffset

    Raises
    ------
    ValueError : non-period dtype
    IncompatibleFrequency : mismatch between dtype and freq
    Nzdtype must be PeriodDtypez&specified freq and dtype are different)r   r/   r.   r   rD   r   r   rJ   rJ   rK   rx     s    
z(tuple[npt.NDArray[np.int64], BaseOffset]rQ   c                 C  s   t | jtjr| jjdkr*td| j |dkrht | trL| j| j } }q|t | tr|| j| j	j } }nt | ttfr|| j} t
| j}t|}|j}t| d|||d|fS )a  
    Convert an datetime-like array to values Period ordinals.

    Parameters
    ----------
    data : Union[Series[datetime64[ns]], DatetimeIndex, ndarray[datetime64ns]]
    freq : Optional[Union[str, Tick]]
        Must match the `freq` on the `data` if `data` is a DatetimeIndex
        or Series.
    tz : Optional[tzinfo]

    Returns
    -------
    ordinals : ndarray[int64]
    freq : Tick
        The frequency extracted from the Series or DatetimeIndex if that's
        used.

    MzWrong dtype: Nr   )reso)rz   rt   r   kindr   r1   r{   rD   r3   dtr   r   ry   rE   c_dt64arr_to_periodarrr   )r   rD   r   r
  rH   rJ   rJ   rK   r     s    



r   r   c                 C  sH  t | ||dkrtd|d k	r0t|}|j}| d k	rBt| |} |d k	rTt||}t| t}t|t}|r|r| j|jkrtd| tks|tkrtd|d kr|r| j}n|r|j}ntd|d k	r$|| }| d krt	j
|j| | |jd |t	jd}nt	j
| j| j| |t	jd}nt	j
| j|jd |t	jd}||fS )N   zOOf the three parameters: start, end, and periods, exactly two must be specifiedz!start and end must have same freqzstart and end must not be NaTz#Could not infer freq from start/endr   r   )comZcount_not_noner   r   r   r   rz   rD   r   r   Zaranger   rv   )r   r   r   rD   ZmultZis_start_perZ
is_end_perr   rJ   rJ   rK   r   .  sP    





      r   ztuple[np.ndarray, BaseOffset]c                 C  sP  |d krd}|d krd}|d kr$d}|d kr0d}g }|d k	r|d krVt d}tjj}	n&t |}t|}	|	tjjkr|td|j}
t| |\} }t	| |D ]>\}}t
|||
\}}t||dddddd|		}|| qn`t |}t|}	t| |||||}t	| D ]2\}}}}}}|t||||||dd|		 qtj|tjd|fS )Nr   r   Qzbase must equal FR_QTRr   )r   r   ZFR_QTRr   r   Zfreq_to_dtype_coder   r   _make_field_arrayszipr   Zquarter_to_myearZperiod_ordinalappendr   r   rv   )rZ   r[   rg   r\   r]   r^   r_   rD   r   rH   r   yqmvalZarraysZmthdhmnsrJ   rJ   rK   r   ^  s:    



$r   zlist[np.ndarray]c                    s`   d  | D ]D}t |ttjtfr d k	r<t| kr<tdq d krt| q fdd| D S )NzMismatched Period array lengthsc                   s4   g | ],}t |tjttfr$t|n
t| qS rJ   )rz   r   r   r   r3   r   repeat)r   r   lengthrJ   rK   r     s   z&_make_field_arrays.<locals>.<listcomp>)rz   r   r   r   r3   r   r   )r   r   rJ   r  rK   r    s    


r  )N)NF)N)r   )NNNNNNNN)e
__future__r   datetimer   r   typingr   r   r   r   r   r	   r
   Znumpyr   Zpandas._libsr   r   r   Zpandas._libs.arraysr   Zpandas._libs.tslibsr   r   r   r   r   r   r  r   r   r   r   r   r   Zpandas._libs.tslibs.dtypesr   Zpandas._libs.tslibs.fieldsr   Zpandas._libs.tslibs.offsetsr   r   Zpandas._libs.tslibs.periodr   r   r   r    r!   Zpandas._typingr"   r#   r$   r%   Zpandas.util._decoratorsr&   r'   Zpandas.core.dtypes.commonr(   r)   r*   r+   r,   r-   r.   r/   Zpandas.core.dtypes.dtypesr0   Zpandas.core.dtypes.genericr1   r2   r3   r4   Zpandas.core.dtypes.missingr5   Zpandas.core.algorithmscoreZ
algorithmsr   r6   r   Zpandas.core.commoncommonr  r7   r8   r9   r:   Zpandas.core.arrays.baser;   r<   r  rP   ZDatelikeOpsZPeriodMixinr?   r~   r  rx   r   r   r  rJ   rJ   rJ   rK   <module>   sr   $
4(
      i#  \) (
1        /