a
    GGbF                    @  s  d dl mZ d dlmZmZ d dlZd dlmZmZmZm	Z	m
Z
mZmZmZmZmZ d dlZd dlZd dlmZ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!m"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/m0Z0m1Z1m2Z2 d d
l3m4Z5 d dl6m7Z7m8Z8m9Z9 d dl:m;Z;m<Z<m=Z= d dl>m?Z? d dl@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZP d dlQmRZR d dlSmTZTmUZU d dlVmWZWmXZX d dlYmZZZm[Z[m\Z\m]Z] d dl^m_Z_ d dl`maZambZb d dlcmd  meZf d dlgmhZimjZj d dlkmlZlmmZm d dlnmoZo d dlpmqZqmrZr d dlsmtZt erPd dlumvZvmwZw ee*ef ZxedddZyG dd dezZ{G d d de_eaZ|G d!d" d"e|Z}d#Z~d$Zd%Zd&Zed'd(dZG d)d( d(e|Zd*d+ Zd,d- Zd.d/ ZdS )0    )annotations)datetime	timedeltaN)
TYPE_CHECKINGAnyCallableLiteralSequenceTypeVarUnioncastfinaloverload)algoslib)
BaseOffsetIncompatibleFrequencyNaTNaTTypePeriod
ResolutionTick	Timestampdelta_to_nanosecondsiNaTints_to_pydatetime	to_offset)RoundToround_nsint64)integer_op_not_supported)
	ArrayLikeDatetimeLikeScalarDtypeDtypeObjNpDtypePositionalIndexer2DPositionalIndexerTupleScalarIndexerSequenceIndexernpt)function)AbstractMethodErrorNullFrequencyErrorPerformanceWarning)AppenderSubstitutioncache_readonly)find_stack_level)is_all_stringsis_categorical_dtypeis_datetime64_any_dtypeis_datetime64_dtypeis_datetime64tz_dtypeis_datetime_or_timedelta_dtypeis_dtype_equalis_float_dtypeis_integer_dtypeis_list_likeis_object_dtypeis_period_dtypeis_string_dtypeis_timedelta64_dtypeis_unsigned_integer_dtypepandas_dtype)ExtensionDtype)is_valid_na_for_dtypeisna)nanopsops)checked_add_with_arrisinmodeunique1d)OpsMixin)NDArrayBackedExtensionArrayravel_compat)arrayextract_array)check_array_indexercheck_setitem_lengths)unpack_zerodim_and_defer)invalid_comparisonmake_invalid_op)frequencies)DatetimeArrayTimedeltaArrayDatetimeLikeArrayTDatetimeLikeArrayMixin)boundc                   @  s   e Zd ZdZdS )InvalidComparisonzm
    Raised by _validate_comparison_value to indicate to caller it should
    return invalid_comparison.
    N)__name__
__module____qualname____doc__ r`   r`   >lib/python3.9/site-packages/pandas/core/arrays/datetimelike.pyr[      s   r[   c                      sz  e Zd ZU dZded< ded< ded< ded	< ed
dddZdddddZeddddZ	dddddZ
ddd
ddddZddd
d d!d"d#Zeddd$d%Zd&d' Zddd(d)Zd*d+ Zed,dd-d.Zd/dd0d1d2Zdd
d3d4d5Zdd6dd7d8d9Zed:dd;d<d=Zed>d?d>d@dAd=Zd>dBdCdD fdEd=ZdFddGdHZdIdJd dK fdLdMZdNdO Zdd
dQ fdRdSZed>d>dTdUdVZedWdXd7dYdVZedZd[d7d\dVZeddd^d7d_dVZddd^d7 fd`dVZeddbdcddd>de fdfdgZdd>d>dT fdidjZdkdl Zedbd>d>dmdndoZ dpdq Z!drds Z"ddPdPdtd
d
d
dtdudvZ#dd
ddwdxdyZ$dd
dzd{d|Z%d}d~ Z&dd Z'dd
ddddZ(e)dd Z*ddddZ+ddddZ,eddddZ-ed
dddZ.e/dfdddddZ0edd Z1e1j2dd Z1eddddZ3eddddZ4eddddZ5eddddZ6edd Z7edbd>dddZ8ed
dddZ9ed
dddZ:ed
dddZ;dd Z<e=dZ>e=dZ?e=dZ@e=dZAe=dZBe=dZCe=dZDe=dZEe=dZFe=dZGe=dZHe=dZIdd ZJeJZKdd ZLeLZMdd ZNddddZOddĄ ZPddƄ ZQddȄ ZReSddʄ ZTeSdd̄ ZUdd΄ ZVddddЄZWdd>ddd>dќddӄZXeYdԃddք ZZdd؄ Z[eYdكddۄ Z\dd݄ Z]dd߄ Z^dd Z_ddPddd
dddZ`ddPddd
dddZadPdadd
ddddZbddPddd
dddZcdd
dddZd  ZeS )rY   z
    Shared Base/Mixin class for DatetimeArray, TimedeltaArray, PeriodArray

    Assumes that __new__/__init__ defines:
        _data
        _freq

    and that the inheriting class has methods:
        _generate_range
    ztuple[str, ...]_infer_matcheszCallable[[DtypeObj], bool]_is_recognized_dtypeztuple[type, ...]_recognized_scalarsz
np.ndarray_ndarrayboolreturnc                 C  s   dS )NTr`   selfr`   r`   ra   _can_hold_na   s    z#DatetimeLikeArrayMixin._can_hold_naNFzDtype | Nonedtypec                 C  s   t | d S Nr+   )rj   datarm   freqcopyr`   r`   ra   __init__   s    zDatetimeLikeArrayMixin.__init__ztype[DatetimeLikeScalar]c                 C  s   t | dS )z
        The scalar associated with this datelike

        * PeriodArray : Period
        * DatetimeArray : Timestamp
        * TimedeltaArray : Timedelta
        Nro   ri   r`   r`   ra   _scalar_type   s    	z#DatetimeLikeArrayMixin._scalar_typestrDTScalarOrNaT)valuerh   c                 C  s   t | dS )ay  
        Construct a scalar type from a string.

        Parameters
        ----------
        value : str

        Returns
        -------
        Period, Timestamp, or Timedelta, or NaT
            Whatever the type of ``self._scalar_type`` is.

        Notes
        -----
        This should call ``self._check_compatible_with`` before
        unboxing the result.
        Nro   rj   rw   r`   r`   ra   _scalar_from_string   s    z*DatetimeLikeArrayMixin._scalar_from_stringz)np.int64 | np.datetime64 | np.timedelta64)rw   setitemrh   c                 C  s   t | dS )a  
        Unbox the integer value of a scalar `value`.

        Parameters
        ----------
        value : Period, Timestamp, Timedelta, or NaT
            Depending on subclass.
        setitem : bool, default False
            Whether to check compatibility with setitem strictness.

        Returns
        -------
        int

        Examples
        --------
        >>> self._unbox_scalar(Timedelta("10s"))  # doctest: +SKIP
        10000000000
        Nro   )rj   rw   rz   r`   r`   ra   _unbox_scalar   s    z$DatetimeLikeArrayMixin._unbox_scalarNone)otherrz   rh   c                 C  s   t | dS )a  
        Verify that `self` and `other` are compatible.

        * DatetimeArray verifies that the timezones (if any) match
        * PeriodArray verifies that the freq matches
        * Timedelta has no verification

        In each case, NaT is considered compatible.

        Parameters
        ----------
        other
        setitem : bool, default False
            For __setitem__ we may have stricter compatibility restrictions than
            for comparisons.

        Raises
        ------
        Exception
        Nro   rj   r}   rz   r`   r`   ra   _check_compatible_with   s    z-DatetimeLikeArrayMixin._check_compatible_withc                 C  s   | j S rn   )re   ri   r`   r`   ra   _data   s    zDatetimeLikeArrayMixin._datac                 C  s   t | dS )zI
        box function to get object from internal representation
        Nro   )rj   xr`   r`   ra   	_box_func  s    z DatetimeLikeArrayMixin._box_funcc                 C  s   t j|| jddS )z1
        apply box func to passed values
        F)convert)r   Z	map_inferr   )rj   valuesr`   r`   ra   _box_values  s    z"DatetimeLikeArrayMixin._box_valuesc                   s<    j dkr$ fddtt D S  fdd jD S d S )N   c                 3  s   | ]} | V  qd S rn   r`   ).0nri   r`   ra   	<genexpr>      z2DatetimeLikeArrayMixin.__iter__.<locals>.<genexpr>c                 3  s   | ]}  |V  qd S rn   )r   )r   vri   r`   ra   r     r   )ndimrangelenasi8ri   r`   ri   ra   __iter__  s    
zDatetimeLikeArrayMixin.__iter__znpt.NDArray[np.int64]c                 C  s   | j dS )z
        Integer representation of the values.

        Returns
        -------
        ndarray
            An ndarray with int64 dtype.
        i8)re   viewri   r`   r`   ra   r     s    zDatetimeLikeArrayMixin.asi8r   )na_repdate_formatc                C  s   t | dS )z|
        Helper method for astype when converting to strings.

        Returns
        -------
        ndarray[str]
        Nro   )rj   r   r   r`   r`   ra   _format_native_types(  s    z+DatetimeLikeArrayMixin._format_native_types)boxedc                 C  s   dj S )Nz'{}')format)rj   r   r`   r`   ra   
_formatter2  s    z!DatetimeLikeArrayMixin._formatterzNpDtype | None)rm   rh   c                 C  s    t |rtjt| tdS | jS Nrl   )r<   nprN   listobjectre   rj   rm   r`   r`   ra   	__array__9  s    z DatetimeLikeArrayMixin.__array__r'   )itemrh   c                 C  s   d S rn   r`   rj   r   r`   r`   ra   __getitem__?  s    z"DatetimeLikeArrayMixin.__getitem__rX   z(SequenceIndexer | PositionalIndexerTuple)rj   r   rh   c                 C  s   d S rn   r`   r   r`   r`   ra   r   C  s    r%   z"DatetimeLikeArrayT | DTScalarOrNaT)rj   keyrh   c                   s:   t dt |}t|r |S t t|}| ||_|S )z
        This getitem defers to the underlying array, which by-definition can
        only handle list-likes, slices, and integer scalars
        z(Union[DatetimeLikeArrayT, DTScalarOrNaT])r   superr   r   	is_scalarrX   _get_getitem_freq_freq)rj   r   result	__class__r`   ra   r   J  s    


zBaseOffset | Nonec                 C  s   t | j}|r| j}n| jdkr&d}nt| |}d}t|trh| jdur`|jdur`|j| j }q| j}n@|tu rx| j}n0t	
|rt|tj}t|tr| |S |S )z\
        Find the `freq` attribute to assign to the result of a __getitem__ lookup.
        r   N)r=   rm   rq   r   rP   
isinstanceslicestepEllipsiscomZis_bool_indexerr   Zmaybe_booleans_to_slicer   r   Zuint8r   )rj   r   Z	is_periodrq   Znew_keyr`   r`   ra   r   _  s$    






z(DatetimeLikeArrayMixin._get_getitem_freqz,int | Sequence[int] | Sequence[bool] | slicezNaTType | Any | Sequence[Any])r   rw   rh   c                   s.   t ||| }|rd S t || |   d S rn   )rQ   r   __setitem___maybe_clear_freq)rj   r   rw   Zno_opr   r`   ra   r   }  s
    
z"DatetimeLikeArrayMixin.__setitem__c                 C  s   d S rn   r`   ri   r`   r`   ra   r     s    z(DatetimeLikeArrayMixin._maybe_clear_freqTrr   c                   s  t |}t|r^| jjdkrF| j }t|| j| jdd}|	| j
S | | j 	| j
S t|trxt j||dS t|r|  S t|r| j}t|r|d}|r| }|S t|rt| j|rt|rdt| j d| }t|ntj| |dS d S )	NMZ	timestamp)tzrq   Zboxr   Zuint64zCannot cast z
 to dtype rl   )rA   r<   rm   kindr   ravelr   r   rq   reshapeshaper   r   rB   r   astyper>   r   r:   r@   r   rr   r7   r8   r9   typer\   	TypeErrorr   asarray)rj   rm   rr   Zi8dataZ	convertedr   msgr   r`   ra   r     s@    




zDatetimeLikeArrayMixin.astype)rj   rh   c                 C  s   d S rn   r`   ri   r`   r`   ra   r     s    zDatetimeLikeArrayMixin.viewzLiteral['M8[ns]']rV   c                 C  s   d S rn   r`   r   r`   r`   ra   r     s    zLiteral['m8[ns]']rW   c                 C  s   d S rn   r`   r   r`   r`   ra   r     s    .r    c                 C  s   d S rn   r`   r   r`   r`   ra   r     s    c                   s   t  |S rn   )r   r   r   r   r`   ra   r     s    r   ztype[DatetimeLikeArrayT]zSequence[DatetimeLikeArrayT]int)cls	to_concataxisrh   c                   s   t  ||}|d   j}d }t|r0 j}nl|dkrdd |D } jd urt fdd|D rt|d d |dd  }t fdd|D r j}||_|S )	Nr   c                 S  s   g | ]}t |r|qS r`   )r   r   r   r`   r`   ra   
<listcomp>  r   z<DatetimeLikeArrayMixin._concat_same_type.<locals>.<listcomp>c                 3  s   | ]}|j  j kV  qd S rn   rq   r   objr`   ra   r     r   z;DatetimeLikeArrayMixin._concat_same_type.<locals>.<genexpr>r   c                 3  s,   | ]$}|d  d  j  |d d  kV  qdS )r   r   r   Nr   )r   Zpairr   r`   ra   r     r   )r   _concat_same_typerm   r=   rq   allzipr   )r   r   r   new_objrm   new_freqZpairsr   r   ra   r     s     z(DatetimeLikeArrayMixin._concat_same_typeCc                   s   t  j|d}| j|_|S )N)order)r   rr   rq   r   )rj   r   r   r   r`   ra   rr     s    zDatetimeLikeArrayMixin.copyc                 C  s   | j ttfS rn   )re   r   int64r   ri   r`   r`   ra   _values_for_factorize  s    z,DatetimeLikeArrayMixin._values_for_factorize)r   originalrh   c                 C  s   | ||j dS r   rl   )r   r   r   r`   r`   ra   _from_factorized  s    z'DatetimeLikeArrayMixin._from_factorizedc              
   C  s0  t |tr8z| |}W n ttfy6   t|Y n0 t || jsL|tu r| |}z| 	| W n2 t
tfy } zt||W Y d }~n
d }~0 0 nt|st|nt|t| krtdnfz| j|dd}| 	| W nH t
tfy* } z*tt|dd rn
t||W Y d }~n
d }~0 0 |S )NzLengths must matchTallow_objectrm   )r   ru   ry   
ValueErrorr   r[   rd   r   rt   r   r   r;   r   _validate_listliker<   getattr)rj   r}   errr`   r`   ra   _validate_comparison_value  s.    

"

 z1DatetimeLikeArrayMixin._validate_comparison_valuec                 C  s   t || jrt}ntt|| jr*| |}n\| jtu rPt|rPtj	|| j
d}n
| |}tjdt| d| jj dtt d |}| j|ddS )Nr   zPassing zA to shift is deprecated and will raise in a future version, pass z	 instead.)
stacklevelTrz   )rC   rm   r   r   rd   rt   r   r   
is_integerZ_from_ordinalrq   warningswarnr   r\   FutureWarningr1   _unbox)rj   
fill_valueZnew_fillr`   r`   ra   _validate_shift_value0  s     
	z,DatetimeLikeArrayMixin._validate_shift_value)allow_listlikerz   unboxc             
   C  s   t || jrnt |trdz| |}W q ty` } z"| ||}t||W Y d}~qd}~0 0 n\t|| jrvt	}nJt
|r| ||}t|n,t || jr| |}n| ||}t||s|S | j||dS )av  
        Validate that the input value can be cast to our scalar_type.

        Parameters
        ----------
        value : object
        allow_listlike: bool, default False
            When raising an exception, whether the message should say
            listlike inputs are allowed.
        setitem : bool, default True
            Whether to check compatibility with setitem strictness.
        unbox : bool, default True
            Whether to unbox the result before returning.  Note: unbox=False
            skips the setitem compatibility check.

        Returns
        -------
        self._scalar_type or NaT
        Nr   )r   rt   ru   ry   r   _validation_error_messager   rC   rm   r   rD   rd   r{   )rj   rw   r   rz   r   r   r   r`   r`   ra   _validate_scalarO  s(    
"
z'DatetimeLikeArrayMixin._validate_scalar)r   rh   c                 C  sB   |r"d| j j dt|j d}nd| j j dt|j d}|S )a+  
        Construct an exception message on validation error.

        Some methods allow only scalar inputs, while others allow either scalar
        or listlike.

        Parameters
        ----------
        allow_listlike: bool, default False

        Returns
        -------
        str
        zvalue should be a 'z"', 'NaT', or array of those. Got 'z
' instead.z' or 'NaT'. Got ')rt   r\   r   )rj   rw   r   r   r`   r`   ra   r     s    z0DatetimeLikeArrayMixin._validation_error_messager   c              	   C  sn  t |t| r|S t |tr<t|dkr<t| jg | jdS t|dr|jtkrt	|| j
v rzt| |}W n6 ttfy   |r| Y S | |d}t|Y n0 t|dd}t|}t|dd}t|rzt| j|| jd}W n ty   Y n0 t|jr0t|jj| jr0| }t|dd}|rDt|jrDn&t| |jsj| |d}t||S )Nr   rl   rm   TZextract_numpy)r   r   r   r   _from_sequencerm   hasattrr   r   infer_dtyperb   r   r   r   rO   pd_arrayr2   r3   r8   Z
categoriesZ_internal_get_valuesr<   rc   )rj   rw   r   r   r`   r`   ra   r     s>    z)DatetimeLikeArrayMixin._validate_listlikec                 C  s,   t |s| j|dddS | |}| |S )NTF)r   rz   )r;   r   r   r   rx   r`   r`   ra   _validate_searchsorted_value  s    
z3DatetimeLikeArrayMixin._validate_searchsorted_valuec                 C  s0   t |r| |}n| j|ddS | j|ddS )NT)r   r   )r;   r   r   r   rx   r`   r`   ra   _validate_setitem_value  s    z.DatetimeLikeArrayMixin._validate_setitem_valuez6np.int64 | np.datetime64 | np.timedelta64 | np.ndarray)rz   rh   c                 C  s2   t |r| j||d}n| j||d |j}|S )zZ
        Unbox either a scalar with _unbox_scalar or an instance of our own type.
        r   )r   r   r{   r   re   r~   r`   r`   ra   r     s
    
zDatetimeLikeArrayMixin._unboxc                 C  s   ddl m} || |jS )Nr   )Index)Zpandasr   maprN   )rj   Zmapperr   r`   r`   ra   r     s    zDatetimeLikeArrayMixin.mapznpt.NDArray[np.bool_]c              	   C  s  t |dst|}|jjdv r0tj| jtdS t|t	| sg d}|jt
krtj|dd}||vr|dkrpn(d|v rt| t
|S tj| jtdS zt	| |}W n" ty   t| t
| Y S 0 z| | W n( ttfy   tj| jtd Y S 0 t| j|jS )	z
        Compute boolean array of whether each value is found in the
        passed set of values.

        Parameters
        ----------
        values : set or sequence of values

        Returns
        -------
        ndarray[bool]
        rm   )fiucrl   )r   timedelta64r   
datetime64dateZperiodF)skipnastringZmixed)r   r   r   rm   r   Zzerosr   rf   r   r   r   r   r   rH   r   r   r   r   r   r   )rj   r   Z	inferableinferredr`   r`   ra   rH   	  s.    


zDatetimeLikeArrayMixin.isinc                 C  s   | j S rn   )_isnanri   r`   r`   ra   rD   A  s    zDatetimeLikeArrayMixin.isnac                 C  s
   | j tkS )z-
        return if each value is nan
        )r   r   ri   r`   r`   ra   r   D  s    zDatetimeLikeArrayMixin._isnanc                 C  s   t | j S )zJ
        return if I have any nans; enables various perf speedups
        )rf   r   anyri   r`   r`   ra   _hasnaK  s    zDatetimeLikeArrayMixin._hasna)r   rh   c                 C  s6   | j r2|r||}|du r"tj}t|| j| |S )az  
        Parameters
        ----------
        result : np.ndarray
        fill_value : object, default iNaT
        convert : str, dtype or None

        Returns
        -------
        result : ndarray with values replace by the fill_value

        mask the result if needed, convert to the provided dtype if its not
        None

        This is an internal routine.
        N)r   r   r   nanputmaskr   )rj   r   r   r   r`   r`   ra   _maybe_mask_resultsR  s    
z*DatetimeLikeArrayMixin._maybe_mask_resultsc                 C  s   | j S )zK
        Return the frequency object if it is set, otherwise None.
        r   ri   r`   r`   ra   rq   p  s    zDatetimeLikeArrayMixin.freqc                 C  s8   |d ur.t |}| | | | jdkr.td|| _d S )Nr   zCannot set freq with ndim > 1)r   _validate_frequencyr   r   r   rx   r`   r`   ra   rq   w  s    
z
str | Nonec                 C  s   | j du rdS | j jS )zU
        Return the frequency object as a string if its set, otherwise None.
        N)rq   freqstrri   r`   r`   ra   r    s    
zDatetimeLikeArrayMixin.freqstrc                 C  s4   | j dkrdS zt| W S  ty.   Y dS 0 dS )z
        Tries to return a string representing a frequency guess,
        generated by infer_freq.  Returns None if it can't autodetect the
        frequency.
        r   N)r   rU   Z
infer_freqr   ri   r`   r`   ra   inferred_freq  s    
z$DatetimeLikeArrayMixin.inferred_freqzResolution | Nonec                 C  s8   | j }|d u rd S zt|W S  ty2   Y d S 0 d S rn   )r  r   Zget_reso_from_freqKeyError)rj   r  r`   r`   ra   _resolution_obj  s    z&DatetimeLikeArrayMixin._resolution_objc                 C  s   | j jS )zO
        Returns day, hour, minute, second, millisecond or microsecond
        )r  attrnameri   r`   r`   ra   
resolution  s    z!DatetimeLikeArrayMixin.resolutionc              
   K  s   |j }|jdks||jkrdS z:| jf |d dt||d|}t|j|jsVtW nL ty } z4dt	|v rx|td| d|j |W Y d}~n
d}~0 0 dS )am  
        Validate that a frequency is compatible with the values of a given
        Datetime Array/Index or Timedelta Array/Index

        Parameters
        ----------
        index : DatetimeIndex or TimedeltaIndex
            The index on which to determine if the given frequency is valid
        freq : DateOffset
            The frequency to validate
        r   Nstartendperiodsrq   z	non-fixedInferred frequency 9 from passed values does not conform to passed frequency )
r  sizer  _generate_ranger   r   Zarray_equalr   r   ru   )r   indexrq   kwargsr   Zon_freqer`   r`   ra   r     s*    z*DatetimeLikeArrayMixin._validate_frequency)r   rh   c                 O  s   t | d S rn   ro   )r   r  r	  r
  rq   argsr  r`   r`   ra   r    s    z&DatetimeLikeArrayMixin._generate_rangec                 C  s   t j| jddd S )NTZtimeliker   r   Zis_monotonicr   ri   r`   r`   ra   _is_monotonic_increasing  s    z/DatetimeLikeArrayMixin._is_monotonic_increasingc                 C  s   t j| jddd S )NTr  r   r  ri   r`   r`   ra   _is_monotonic_decreasing  s    z/DatetimeLikeArrayMixin._is_monotonic_decreasingc                 C  s   t t| jd| jkS )NK)r   rJ   r   r   r  ri   r`   r`   ra   
_is_unique  s    z!DatetimeLikeArrayMixin._is_uniquec           	   	   C  s  | j dkr6t|dd | jkr6||  | | jS z| |}W n tyb   t| || Y S 0 t|dd }t|rt	j
dd* t|t	| t|}W d    n1 s0    Y  |S | |}|| jd|d}t|}| j|B }| r|tju }t	||| |S )Nr   r   rm   ignore)r   r   )r   r   r   r   r   r   r[   rS   r<   r   ZerrstaterF   Zcomp_method_OBJECT_ARRAYr   r   r   r   re   r   rD   r   r   operatorner   )	rj   r}   oprm   r   Z
other_valsZo_maskmaskZ
nat_resultr`   r`   ra   _cmp_method  s*    "



z"DatetimeLikeArrayMixin._cmp_method__pow____rpow____mul____rmul____truediv____rtruediv____floordiv____rfloordiv____mod____rmod__
__divmod____rdivmod__c                 C  s$   t dt| j dt|j d S )Nzcannot add  and r   r   r\   rj   r}   r`   r`   ra   _add_datetimelike_scalar  s    z/DatetimeLikeArrayMixin._add_datetimelike_scalarc                 C  s$   |t usJ tdt| j d S )Nz"cannot subtract a datelike from a )r   r   r   r\   r-  r`   r`   ra   _sub_datetimelike_scalar   s    z/DatetimeLikeArrayMixin._sub_datetimelike_scalarc                 C  s   t dt| j d S )Nzcannot subtract Period from a r,  r-  r`   r`   ra   _sub_period'  s    z"DatetimeLikeArrayMixin._sub_periodr   )r}   c                 C  s   t dt| j d S )Nzcannot add Period to a r,  r-  r`   r`   ra   _add_period+  s    z"DatetimeLikeArrayMixin._add_periodc                 C  s   t | d S rn   ro   )rj   offsetr`   r`   ra   _add_offset/  s    z"DatetimeLikeArrayMixin._add_offsetc                 C  s   t |r4tj| jdd}|t t| || jdS t|}t	| j
|| jd}|d}| |}|| jj}d}t| jtst| jr| j}t| j|| j|dS )zk
        Add a delta of a timedeltalike

        Returns
        -------
        Same type as self
        r   rl   )arr_maskNrm   rq   )rD   r   emptyr   fillr   r   rm   r   rG   r   r   r   r   re   r   rq   r   r=   _simple_new)rj   r}   
new_valuesZincr   r`   r`   ra   _add_timedeltalike_scalar2  s    


z0DatetimeLikeArrayMixin._add_timedeltalike_scalarc                 C  s   t | t |krtdt|tjr:ddlm} ||}| j}|j}t	||| j
|j
d}| jsf|jr| j
|j
B }t||t t| || jdS )zl
        Add a delta of a TimedeltaIndex

        Returns
        -------
        Same type as self
        z$cannot add indices of unequal lengthr   rW   )r4  Zb_maskrl   )r   r   r   r   ndarraypandas.core.arraysrW   r   r   rG   r   r   r   r   r   rm   )rj   r}   rW   Zself_i8Zother_i8r9  r  r`   r`   ra   _add_timedelta_arraylikeP  s    

z/DatetimeLikeArrayMixin._add_timedelta_arraylikec                 C  sZ   t | jr*tdt| j dttj tj| jtj	d}|
t t| || jddS )z$
        Add pd.NaT to self
        zCannot add r+  rl   Nr5  )r=   rm   r   r   r\   r   r   r6  r   r   r7  r   rj   r   r`   r`   ra   _add_natn  s    

zDatetimeLikeArrayMixin._add_natc                 C  s&   t j| jt jd}|t |dS )z+
        Subtract pd.NaT from self
        rl   ztimedelta64[ns])r   r6  r   r   r7  r   r   r?  r`   r`   ra   _sub_nat~  s    
zDatetimeLikeArrayMixin._sub_natc                 C  s    t d|j dt| j d S )Ncannot subtract z-dtype from )r   rm   r   r\   r-  r`   r`   ra   _sub_period_array  s    z(DatetimeLikeArrayMixin._sub_period_arrayc                 C  s   |t jt jfv sJ t|dkr8| jdkr8|| |d S tdt| j dt	 | j
|j
ksnJ | j
|j
ft 4 tjdtd || dt|}W d   n1 s0    Y  t| }t|d	d
| j
}|S )z
        Add or subtract array-like of DateOffset objects

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

        Returns
        -------
        result : same class as self
        r   r   z)Adding/subtracting object-dtype array to z not vectorized.r  )categoryONTr   )r  addsubr   r   r   r   r   r\   r-   r   catch_warningsfilterwarningsr   r   r   r   r   r   rO   r   )rj   r}   r  Z
res_valuesr   r`   r`   ra   _addsub_object_array  s(    
4z+DatetimeLikeArrayMixin._addsub_object_array)rj   r
  rh   c                 C  s   |dur4|| j kr4t|tr$t|}|| }| | S |dksHt| dkrP|  S | j du rbtd| d || j   }| d || j   }| j||d| 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.
        Nr   zCannot shift with no freqr   r  )rq   r   ru   r   r   rr   r,   r  )rj   r
  rq   r2  r  r	  r`   r`   ra   _time_shift  s    

z"DatetimeLikeArrayMixin._time_shift__add__c                 C  sd  t |dd }|tu r |  }nt|tttjfr>| |}nt|t	rT| 
|}nt|ttjfrp| |}nt|trt| jr| |}nt|rt| jst| | |}nzt|r| |}nft|r| |tj}nNt|st|r | |S t|r.t| jst| |  |tj}nt!S t|tj"r`t|jr`ddl#m$} ||S |S Nrm   r   r;  )%r   r   r@  r   r   r   r   r   r:  r   r3  r   r   r.  r   r?   rm   r1  r   r   r=   r   rK  r>  r<   rJ  r  rF  r5   r6   _add_datetime_arrayliker:   _addsub_int_arrayNotImplementedr<  r=  rW   rj   r}   other_dtyper   rW   r`   r`   ra   rL    s<    




zDatetimeLikeArrayMixin.__add__c                 C  s
   |  |S rn   )rL  r-  r`   r`   ra   __radd__  s    zDatetimeLikeArrayMixin.__radd____sub__c                 C  s|  t |dd }|tu r |  }n*t|tttjfrB| | }nt|t	rZ| 
| }nt|ttjfrv| |}nt|rt| jst| | | }nt|tr| |}nt|r| | }n~t|r| |tj}nft|st|r| |}nHt|r| |}n2t |rFt| js6t| | !|tj}nt"S t|tj#rxt|jrxddl$m%} ||S |S rM  )&r   r   rA  r   r   r   r   r   r:  r   r3  r   r   r/  r   r   r=   rm   r   rK  r   r0  r?   r>  r<   rJ  r  rG  r5   r6   _sub_datetime_arraylikerC  r:   rO  rP  r<  r=  rW   rQ  r`   r`   ra   rT    s@    





zDatetimeLikeArrayMixin.__sub__c                 C  s   t |dd }t|rZt| jrZt|r4t||  S t|tsRddl	m
} ||}||  S t| jrt|drt|jstdt| j dt|j nNt| jrt|rtdt| j d|j nt| jrtd| } |  | S | |  S )Nrm   r   )rV   rB  z from rW   )r   r4   r?   rm   r   r   r   r   rY   r=  rV   r   r   r   r\   r=   r   )rj   r}   rR  rV   r`   r`   ra   __rsub__N  s.    




zDatetimeLikeArrayMixin.__rsub__c                 C  s2   | | }|d d  | d d < t | js.|j| _| S rn   r=   rm   rq   r   rj   r}   r   r`   r`   ra   __iadd__q  s
    
zDatetimeLikeArrayMixin.__iadd__c                 C  s2   | | }|d d  | d d < t | js.|j| _| S rn   rW  rX  r`   r`   ra   __isub__z  s
    
zDatetimeLikeArrayMixin.__isub__r   r   
int | Nonec                K  s   t d| t || j t| jrxtj| j	d||d}|t
u rHt
S |	d}|du sd| jdkrn| |S | |S tj| j||d}| ||S )a  
        Return the minimum value of the Array or minimum along
        an axis.

        See Also
        --------
        numpy.ndarray.min
        Index.min : Return the minimum value in an Index.
        Series.min : Return the minimum value in a Series.
        r`   M8[ns]r[  r   Nr   )nvZvalidate_minvalidate_minmax_axisr   r=   rm   rE   Znanminre   r   r   r   _from_backing_data_wrap_reduction_resultrj   r   r   r  r   r`   r`   ra   min  s    



zDatetimeLikeArrayMixin.minc                K  s   t d| t || j t| jrxtj| j	d||d}|t
u rH|S |	d}|du sd| jdkrn| |S | |S tj| j||d}| ||S )a  
        Return the maximum value of the Array or maximum along
        an axis.

        See Also
        --------
        numpy.ndarray.max
        Index.max : Return the maximum value in an Index.
        Series.max : Return the maximum value in a Series.
        r`   r]  r[  r   Nr   )r^  Zvalidate_maxr_  r   r=   rm   rE   Znanmaxre   r   r   r   r`  ra  rb  r`   r`   ra   max  s    



zDatetimeLikeArrayMixin.max)r   r   c                C  sD   t | jr tdt| j dtj| j|||  d}| 	||S )an  
        Return the mean value of the Array.

        .. versionadded:: 0.25.0

        Parameters
        ----------
        skipna : bool, default True
            Whether to ignore any NaT elements.
        axis : int, optional, default 0

        Returns
        -------
        scalar
            Timestamp or Timedelta.

        See Also
        --------
        numpy.ndarray.mean : Returns the average of array elements along a given axis.
        Series.mean : Return the mean value in a Series.

        Notes
        -----
        mean is only defined for Datetime and Timedelta dtypes, not for Period.
        zmean is not implemented for zX since the meaning is ambiguous.  An alternative is obj.to_timestamp(how='start').mean()r   r   r  )
r=   rm   r   r   r\   rE   Znanmeanre   rD   ra  )rj   r   r   r   r`   r`   ra   mean  s    
zDatetimeLikeArrayMixin.meanc                K  s   t d| |d ur*t|| jkr*tdt| jr|tj| j	
d||d}|
d}|d u sh| jdkrr| |S | |S tj| j	||d}| ||S )Nr`   z abs(axis) must be less than ndimr]  r[  r   r   )r^  Zvalidate_medianabsr   r   r=   rm   rE   Z	nanmedianre   r   r   r`  ra  rb  r`   r`   ra   median  s    



zDatetimeLikeArrayMixin.median)dropnac                 C  sL   | }|r|  }||  }t|d}|| jj}ttj|}| |S )Nr   )	rD   rI   r   re   rm   r   r   r<  r`  )rj   ri  r   r  Zi8modesZnpmodesr`   r`   ra   _mode  s    
zDatetimeLikeArrayMixin._mode)NNF)F)F)F)N)T).)N)r   )r   )F)F)F)N)T)fr\   r]   r^   r_   __annotations__r0   rk   rs   propertyrt   ry   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr   rr   r   r   r   r   r   r   r   r   r   r   rM   r   rH   rD   r   r   r   r   rq   setterr  r  r  r  r   r  r  r  r  r  rT   r  r   r!  r"  r#  r$  r%  r&  r'  r(  r)  r*  r.  rN  r/  rU  r0  r1  r3  r:  r>  r   r@  rA  rC  rJ  rK  rR   rL  rS  rT  rV  rY  rZ  rc  rd  rf  rh  rj  __classcell__r`   r`   r   ra   rY      s  

  
2 	$#>3	 

8


	
&#

+ &
2
3#	'c                   @  s*   e Zd ZdZedddddddZd	S )
DatelikeOpszK
    Common ops for DatetimeIndex/PeriodIndex, but not TimedeltaIndex.
    zNhttps://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior)ZURLru   znpt.NDArray[np.object_])r   rh   c                 C  s   | j |tjd}|jtddS )a  
        Convert to Index using specified date_format.

        Return an Index of formatted strings specified by date_format, which
        supports the same string format as the python standard library. Details
        of the string format can be found in `python string format
        doc <%(URL)s>`__.

        Parameters
        ----------
        date_format : str
            Date format string (e.g. "%%Y-%%m-%%d").

        Returns
        -------
        ndarray[object]
            NumPy ndarray of formatted strings.

        See Also
        --------
        to_datetime : Convert the given argument to datetime.
        DatetimeIndex.normalize : Return DatetimeIndex with times to midnight.
        DatetimeIndex.round : Round the DatetimeIndex to the specified freq.
        DatetimeIndex.floor : Floor the DatetimeIndex to the specified freq.

        Examples
        --------
        >>> rng = pd.date_range(pd.Timestamp("2018-03-10 09:00"),
        ...                     periods=3, freq='s')
        >>> rng.strftime('%%B %%d, %%Y, %%r')
        Index(['March 10, 2018, 09:00:00 AM', 'March 10, 2018, 09:00:01 AM',
               'March 10, 2018, 09:00:02 AM'],
              dtype='object')
        )r   r   Fr   )r   r   r   r   r   )rj   r   r   r`   r`   ra   strftime  s    'zDatelikeOps.strftimeN)r\   r]   r^   r_   r/   rq  r`   r`   r`   ra   rp    s
   rp  aM	  
    Perform {op} operation on the data to the specified `freq`.

    Parameters
    ----------
    freq : str or Offset
        The frequency level to {op} the index to. Must be a fixed
        frequency like 'S' (second) not 'ME' (month end). See
        :ref:`frequency aliases <timeseries.offset_aliases>` for
        a list of possible `freq` values.
    ambiguous : 'infer', bool-ndarray, 'NaT', default 'raise'
        Only relevant for DatetimeIndex:

        - 'infer' will attempt to infer fall dst-transition hours based on
          order
        - bool-ndarray where True signifies a DST time, False designates
          a non-DST time (note that this flag is only applicable for
          ambiguous times)
        - 'NaT' will return NaT where there are ambiguous times
        - 'raise' will raise an AmbiguousTimeError if there are ambiguous
          times.

    nonexistent : 'shift_forward', 'shift_backward', 'NaT', timedelta, default 'raise'
        A nonexistent time does not exist in a particular timezone
        where clocks moved forward due to DST.

        - 'shift_forward' will shift the nonexistent time forward to the
          closest existing time
        - 'shift_backward' will shift the nonexistent time backward to the
          closest existing time
        - 'NaT' will return NaT where there are nonexistent times
        - timedelta objects will shift nonexistent times by the timedelta
        - 'raise' will raise an NonExistentTimeError if there are
          nonexistent times.

    Returns
    -------
    DatetimeIndex, TimedeltaIndex, or Series
        Index of the same type for a DatetimeIndex or TimedeltaIndex,
        or a Series with the same index for a Series.

    Raises
    ------
    ValueError if the `freq` cannot be converted.

    Notes
    -----
    If the timestamps have a timezone, {op}ing will take place relative to the
    local ("wall") time and re-localized to the same timezone. When {op}ing
    near daylight savings time, use ``nonexistent`` and ``ambiguous`` to
    control the re-localization behavior.

    Examples
    --------
    **DatetimeIndex**

    >>> rng = pd.date_range('1/1/2018 11:59:00', periods=3, freq='min')
    >>> rng
    DatetimeIndex(['2018-01-01 11:59:00', '2018-01-01 12:00:00',
                   '2018-01-01 12:01:00'],
                  dtype='datetime64[ns]', freq='T')
    a  >>> rng.round('H')
    DatetimeIndex(['2018-01-01 12:00:00', '2018-01-01 12:00:00',
                   '2018-01-01 12:00:00'],
                  dtype='datetime64[ns]', freq=None)

    **Series**

    >>> pd.Series(rng).dt.round("H")
    0   2018-01-01 12:00:00
    1   2018-01-01 12:00:00
    2   2018-01-01 12:00:00
    dtype: datetime64[ns]

    When rounding near a daylight savings time transition, use ``ambiguous`` or
    ``nonexistent`` to control how the timestamp should be re-localized.

    >>> rng_tz = pd.DatetimeIndex(["2021-10-31 03:30:00"], tz="Europe/Amsterdam")

    >>> rng_tz.floor("2H", ambiguous=False)
    DatetimeIndex(['2021-10-31 02:00:00+01:00'],
                  dtype='datetime64[ns, Europe/Amsterdam]', freq=None)

    >>> rng_tz.floor("2H", ambiguous=True)
    DatetimeIndex(['2021-10-31 02:00:00+02:00'],
                  dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
    a  >>> rng.floor('H')
    DatetimeIndex(['2018-01-01 11:00:00', '2018-01-01 12:00:00',
                   '2018-01-01 12:00:00'],
                  dtype='datetime64[ns]', freq=None)

    **Series**

    >>> pd.Series(rng).dt.floor("H")
    0   2018-01-01 11:00:00
    1   2018-01-01 12:00:00
    2   2018-01-01 12:00:00
    dtype: datetime64[ns]

    When rounding near a daylight savings time transition, use ``ambiguous`` or
    ``nonexistent`` to control how the timestamp should be re-localized.

    >>> rng_tz = pd.DatetimeIndex(["2021-10-31 03:30:00"], tz="Europe/Amsterdam")

    >>> rng_tz.floor("2H", ambiguous=False)
    DatetimeIndex(['2021-10-31 02:00:00+01:00'],
                 dtype='datetime64[ns, Europe/Amsterdam]', freq=None)

    >>> rng_tz.floor("2H", ambiguous=True)
    DatetimeIndex(['2021-10-31 02:00:00+02:00'],
                  dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
    a  >>> rng.ceil('H')
    DatetimeIndex(['2018-01-01 12:00:00', '2018-01-01 12:00:00',
                   '2018-01-01 13:00:00'],
                  dtype='datetime64[ns]', freq=None)

    **Series**

    >>> pd.Series(rng).dt.ceil("H")
    0   2018-01-01 12:00:00
    1   2018-01-01 12:00:00
    2   2018-01-01 13:00:00
    dtype: datetime64[ns]

    When rounding near a daylight savings time transition, use ``ambiguous`` or
    ``nonexistent`` to control how the timestamp should be re-localized.

    >>> rng_tz = pd.DatetimeIndex(["2021-10-31 01:30:00"], tz="Europe/Amsterdam")

    >>> rng_tz.ceil("H", ambiguous=False)
    DatetimeIndex(['2021-10-31 02:00:00+01:00'],
                  dtype='datetime64[ns, Europe/Amsterdam]', freq=None)

    >>> rng_tz.ceil("H", ambiguous=True)
    DatetimeIndex(['2021-10-31 02:00:00+02:00'],
                  dtype='datetime64[ns, Europe/Amsterdam]', freq=None)
    TimelikeOpsTTimelikeOpsc                      s   e Zd ZdZddd fddZdd Zeee j	d	d
d(ddZ
eee j	dd
d)ddZeee j	dd
d*ddZddddddddZddddddddZdddd Zd!d" Zd+dd% fd&d'Z  ZS ),rs  zK
    Common ops for TimedeltaIndex/DatetimeIndex, but not PeriodIndex.
    znp.ufuncru   )ufuncmethodc                   s`   |t jt jt jfv rDt|dkrD|d | u rDt||| jfi |S t j||g|R i |S )Nr   r   )	r   ZisnanZisinfZisfiniter   r   re   r   __array_ufunc__)rj   rt  ru  Zinputsr  r   r`   ra   rv    s    

zTimelikeOps.__array_ufunc__c           
      C  s   t | jr@td| } | d }|||||}|j| j||dS | d}ttj|}t	|j
}t|||}	| j|	td}|| jj}| j|| jdS )NrV   )	ambiguousnonexistentr   )r   rl   )r6   rm   r   Ztz_localize_roundr   r   r   r<  r   nanosr   r   r   re   r8  )
rj   rq   rI   rw  rx  Znaiver   r   rz  Z	result_i8r`   r`   ra   ry    s    




zTimelikeOps._roundround)r  raisec                 C  s   |  |tj||S rn   )ry  r   ZNEAREST_HALF_EVENrj   rq   rw  rx  r`   r`   ra   r{    s    zTimelikeOps.roundfloorc                 C  s   |  |tj||S rn   )ry  r   ZMINUS_INFTYr}  r`   r`   ra   r~    s    zTimelikeOps.floorceilc                 C  s   |  |tj||S rn   )ry  r   Z
PLUS_INFTYr}  r`   r`   ra   r    s    zTimelikeOps.ceilNTr[  r\  rf   c                C  s   t j| j|||  dS Nre  )rE   Znananyre   rD   rj   r   r   r`   r`   ra   r     s    zTimelikeOps.anyc                C  s   t j| j|||  dS r  )rE   Znanallre   rD   r  r`   r`   ra   r      s    zTimelikeOps.allr|   rg   c                 C  s
   d | _ d S rn   r   ri   r`   r`   ra   r     s    zTimelikeOps._maybe_clear_freqc                 C  sJ   |du r
n.t | dkr"t|tr"n|dks.J t| j}|  }||_|S )z
        Helper to get a view on the same data, with a new freq.

        Parameters
        ----------
        freq : DateOffset, None, or "infer"

        Returns
        -------
        Same type as self
        Nr   infer)r   r   r   r   r  r   r   )rj   rq   Zarrr`   r`   ra   
_with_freq
  s    
zTimelikeOps._with_freqr   F)sortc                   sh   | j d urZtjt| tjd}|  }|rR| j jdk rR|d d d }|d d d }||fS t j|dS )Nrl   r   r   )na_sentinel)	rq   r   Zaranger   Zintprr   r   r   	factorize)rj   r  r  ZcodesZuniquesr   r`   ra   r  )  s    
zTimelikeOps.factorize)r|  r|  )r|  r|  )r|  r|  )r   F)r\   r]   r^   r_   rv  ry  r.   
_round_doc_round_exampler   r{  _floor_exampler~  _ceil_exampler  r   r   r   r  r  ro  r`   r`   r   ra   rs    s   c                 C  s8   | dur4t | rt| } nt | s4td|  | S )a9  
    If a `periods` argument is passed to the Datetime/Timedelta Array/Index
    constructor, cast it to an integer.

    Parameters
    ----------
    periods : None, float, int

    Returns
    -------
    periods : None or int

    Raises
    ------
    TypeError
        if periods is None, float, or int
    Nzperiods must be a number, got )r   Zis_floatr   r   r   )r
  r`   r`   ra   validate_periods:  s    


r  c                 C  sH   |dur@| dur0| |kr0t d| d| j n| du r<|} d}| |fS )a  
    If the user passes a freq and another freq is inferred from passed data,
    require that they match.

    Parameters
    ----------
    freq : DateOffset or None
    inferred_freq : DateOffset or None
    freq_infer : bool

    Returns
    -------
    freq : DateOffset or None
    freq_infer : bool

    Notes
    -----
    We assume at this point that `maybe_infer_freq` has been called, so
    `freq` is either a DateOffset object or None.
    Nr  r  F)r   r  )rq   r  
freq_inferr`   r`   ra   validate_inferred_freqT  s    r  c                 C  s0   d}t | ts(| dkr t| } nd}d} | |fS )a  
    Comparing a DateOffset to the string "infer" raises, so we need to
    be careful about comparisons.  Make a dummy variable `freq_infer` to
    signify the case where the given freq is "infer" and set freq to None
    to avoid comparison trouble later on.

    Parameters
    ----------
    freq : {DateOffset, None, str}

    Returns
    -------
    freq : {DateOffset, None}
    freq_infer : bool
        Whether we should inherit the freq of passed data.
    Fr  TN)r   r   r   )rq   r  r`   r`   ra   maybe_infer_freqw  s    

r  )Z
__future__r   r   r   r  typingr   r   r   r   r	   r
   r   r   r   r   r   Znumpyr   Zpandas._libsr   r   Zpandas._libs.tslibsr   r   r   r   r   r   r   r   r   r   r   r   Zpandas._libs.tslibs.fieldsr   r   Zpandas._libs.tslibs.timestampsr   Zpandas._typingr    r!   r"   r#   r$   r%   r&   r'   r(   r)   Zpandas.compat.numpyr*   r^  Zpandas.errorsr+   r,   r-   Zpandas.util._decoratorsr.   r/   r0   Zpandas.util._exceptionsr1   Zpandas.core.dtypes.commonr2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   Zpandas.core.dtypes.dtypesrB   Zpandas.core.dtypes.missingrC   rD   Zpandas.corerE   rF   Zpandas.core.algorithmsrG   rH   rI   rJ   Zpandas.core.arraylikerK   Zpandas.core.arrays._mixinsrL   rM   Zpandas.core.commoncorecommonr   Zpandas.core.constructionrN   r   rO   Zpandas.core.indexersrP   rQ   Zpandas.core.ops.commonrR   Zpandas.core.ops.invalidrS   rT   Zpandas.tseriesrU   r=  rV   rW   rv   rX   	Exceptionr[   rY   rp  r  r  r  r  rr  rs  r  r  r  r`   r`   r`   ra   <module>   sj   080H	          |0?p#