3
d2                 @   s   d dl mZ d dlmZ d dlmZmZmZ ed ZddgZdd Z	e
edrZdd	dZnG d
d deZdddZdd ZG dd deZG dd deZdS )    )PY2)wraps)datetime	timedeltatzinfotzname_in_python2enfoldc                s$   t rt  fdd}|S  S dS )zChange unicode output into bytestrings in Python 2

    tzname() API changed in Python 3. It used to return bytes, but was changed
    to unicode strings
    c                 s    | |}|d k	r|j  }|S )N)encode)argskwargsname)namefunc >/tmp/pip-build-7vycvbft/python-dateutil/dateutil/tz/_common.pyadjust_encoding   s    
z*tzname_in_python2.<locals>.adjust_encodingN)r   r   )r   r   r   )r   r   r      s    fold   c             C   s   | j |dS )a  
        Provides a unified interface for assigning the ``fold`` attribute to
        datetimes both before and after the implementation of PEP-495.

        :param fold:
            The value for the ``fold`` attribute in the returned datetime. This
            should be either 0 or 1.

        :return:
            Returns an object for which ``getattr(dt, 'fold', 0)`` returns
            ``fold`` for all versions of Python. In versions prior to
            Python 3.6, this is a ``_DatetimeWithFold`` object, which is a
            subclass of :py:class:`datetime.datetime` with the ``fold``
            attribute added, if ``fold`` is 1.

        .. versionadded:: 2.6.0
        )r   )replace)dtr   r   r   r   r   %   s    c               @   s(   e Zd ZdZf Zdd Zedd ZdS )_DatetimeWithFoldz
        This is a class designed to provide a PEP 495-compliant interface for
        Python versions before 3.6. It is used only for dates in a fold, so
        the ``fold`` attribute is fixed at ``1``.

        .. versionadded:: 2.6.0
        c             O   s~   d}x4t ||D ]&\}}||kr.td	j||||< qW x"|D ]}||kr@t| |||< q@W |jd
drp| jnt}|f |S )a  
            Return a datetime with the same attributes, except for those
            attributes given new values by whichever keyword arguments are
            specified. Note that tzinfo=None can be specified to create a naive
            datetime from an aware datetime with no conversion of date and time
            data.

            This is reimplemented in ``_DatetimeWithFold`` because pypy3 will
            return a ``datetime.datetime`` even if ``fold`` is unchanged.
            yearmonthdayhourminutesecondmicrosecondr   zDuplicate argument: {}r   r   )r   r   r   r   r   r   r   r   )zip	TypeErrorformatgetattrget	__class__r   )selfr
   r   argnamesargZargnameZdt_classr   r   r   r   D   s     
z_DatetimeWithFold.replacec             C   s   dS )Nr   r   )r#   r   r   r   r   b   s    z_DatetimeWithFold.foldN)__name__
__module____qualname____doc__	__slots__r   propertyr   r   r   r   r   r   :   s   r   c             C   sL   t | dd|kr| S | j dd }|| j| jf7 }|r@t| S t| S dS )a  
        Provides a unified interface for assigning the ``fold`` attribute to
        datetimes both before and after the implementation of PEP-495.

        :param fold:
            The value for the ``fold`` attribute in the returned datetime. This
            should be either 0 or 1.

        :return:
            Returns an object for which ``getattr(dt, 'fold', 0)`` returns
            ``fold`` for all versions of Python. In versions prior to
            Python 3.6, this is a ``_DatetimeWithFold`` object, which is a
            subclass of :py:class:`datetime.datetime` with the ``fold``
            attribute added, if ``fold`` is 1.

        .. versionadded:: 2.6.0
        r   r   N   )r    	timetupler   r   r   r   )r   r   r
   r   r   r   r   f   s    c                s   t   fdd}|S )z
    The CPython version of ``fromutc`` checks that the input is a ``datetime``
    object and that ``self`` is attached as its ``tzinfo``.
    c                s.   t |tstd|j| k	r$td | |S )Nz&fromutc() requires a datetime argumentzdt.tzinfo is not self)
isinstancer   r   r   
ValueError)r#   r   )fr   r   fromutc   s
    

z)_validate_fromutc_inputs.<locals>.fromutc)r   )r0   r1   r   )r0   r   _validate_fromutc_inputs   s    	r2   c               @   s<   e Zd ZdZdd Zdd Zdd Zdd	 Zed
d Z	dS )_tzinfoz=
    Base class for all ``dateutil`` ``tzinfo`` objects.
    c             C   sV   |j | d}t|dd}t|dd}|j |j k}|j dd|j ddk}|oT| S )a6  
        Whether or not the "wall time" of a given datetime is ambiguous in this
        zone.

        :param dt:
            A :py:class:`datetime.datetime`, naive or time zone aware.


        :return:
            Returns ``True`` if ambiguous, ``False`` otherwise.

        .. versionadded:: 2.6.0
        )r   r   )r   r   N)r   r   	utcoffset)r#   r   Zwall_0Zwall_1Zsame_offsetZsame_dtr   r   r   is_ambiguous   s    z_tzinfo.is_ambiguousc             C   s4   | j |r,|| }t||j |j  k}nd}|S )a  
        Determine the fold status of a "wall" datetime, given a representation
        of the same datetime as a (naive) UTC datetime. This is calculated based
        on the assumption that ``dt.utcoffset() - dt.dst()`` is constant for all
        datetimes, and that this offset is the actual number of hours separating
        ``dt_utc`` and ``dt_wall``.

        :param dt_utc:
            Representation of the datetime as UTC

        :param dt_wall:
            Representation of the datetime as "wall time". This parameter must
            either have a `fold` attribute or have a fold-naive
            :class:`datetime.tzinfo` attached, otherwise the calculation may
            fail.
        r   )r5   intr4   dst)r#   dt_utcdt_wallZ
delta_wall_foldr   r   r   _fold_status   s
    
z_tzinfo._fold_statusc             C   s   t |ddS )Nr   r   )r    )r#   r   r   r   r   r:      s    z_tzinfo._foldc             C   sh   |j  }|dkrtd|j }|dkr0td|| }||7 }t|ddj }|dkr`td|| S )a  
        Given a timezone-aware datetime in a given timezone, calculates a
        timezone-aware datetime in a new timezone.

        Since this is the one time that we *know* we have an unambiguous
        datetime object, we take this opportunity to determine whether the
        datetime is ambiguous and in a "fold" state (e.g. if it's the first
        occurrence, chronologically, of the ambiguous datetime).

        :param dt:
            A timezone-aware :class:`datetime.datetime` object.
        Nz0fromutc() requires a non-None utcoffset() resultz*fromutc() requires a non-None dst() resultr   )r   z;fromutc(): dt.dst gave inconsistent results; cannot convert)r4   r/   r7   r   )r#   r   ZdtoffZdtdstdeltar   r   r   _fromutc   s    z_tzinfo._fromutcc             C   s"   | j |}| j||}t||dS )a  
        Given a timezone-aware datetime in a given timezone, calculates a
        timezone-aware datetime in a new timezone.

        Since this is the one time that we *know* we have an unambiguous
        datetime object, we take this opportunity to determine whether the
        datetime is ambiguous and in a "fold" state (e.g. if it's the first
        occurrence, chronologically, of the ambiguous datetime).

        :param dt:
            A timezone-aware :class:`datetime.datetime` object.
        )r   )r=   r;   r   )r#   r   r9   r:   r   r   r   r1      s    
z_tzinfo.fromutcN)
r&   r'   r(   r)   r5   r;   r:   r=   r2   r1   r   r   r   r   r3      s   %r3   c               @   sz   e Zd ZdZdd Zdd Zdd Zedd	 Zd
d Z	dd Z
dd Zdd Zedd ZdZdd Zdd ZejZdS )tzrangebasea  
    This is an abstract base class for time zones represented by an annual
    transition into and out of DST. Child classes should implement the following
    methods:

        * ``__init__(self, *args, **kwargs)``
        * ``transitions(self, year)`` - this is expected to return a tuple of
          datetimes representing the DST on and off transitions in standard
          time.

    A fully initialized ``tzrangebase`` subclass should also provide the
    following attributes:
        * ``hasdst``: Boolean whether or not the zone uses DST.
        * ``_dst_offset`` / ``_std_offset``: :class:`datetime.timedelta` objects
          representing the respective UTC offsets.
        * ``_dst_abbr`` / ``_std_abbr``: Strings representing the timezone short
          abbreviations in DST and STD, respectively.
        * ``_hasdst``: Whether or not the zone has DST.

    .. versionadded:: 2.6.0
    c             C   s   t dd S )Nz%tzrangebase is an abstract base class)NotImplementedError)r#   r   r   r   __init__!  s    ztzrangebase.__init__c             C   s*   | j |}|d krd S |r | jS | jS d S )N)_isdst_dst_offset_std_offset)r#   r   isdstr   r   r   r4   $  s    
ztzrangebase.utcoffsetc             C   s(   | j |}|d krd S |r | jS tS d S )N)rA   _dst_base_offsetZERO)r#   r   rD   r   r   r   r7   .  s    
ztzrangebase.dstc             C   s   | j |r| jS | jS d S )N)rA   Z	_dst_abbrZ	_std_abbr)r#   r   r   r   r   tzname8  s    
ztzrangebase.tznamec       
      C   s   t |tstd|j| k	r$td| j|j}|dkrF|| j| S |\}}|| j8 }|| j8 }||f}|j	dd}| j
||}|r|| j }n
|| j }t| o| j|}	t||	dS )z, Given a datetime in UTC, return local time z&fromutc() requires a datetime argumentzdt.tzinfo is not selfN)r   )r   )r.   r   r   r   r/   transitionsr   r4   rC   r   _naive_isdstrB   r6   r5   r   )
r#   r   rH   dstondstoffZutc_transitionsr8   rD   r9   r:   r   r   r   r1   ?  s$    




ztzrangebase.fromutcc             C   sD   | j s
dS | j|j\}}|jdd}||  ko>|| j k S   S )a6  
        Whether or not the "wall time" of a given datetime is ambiguous in this
        zone.

        :param dt:
            A :py:class:`datetime.datetime`, naive or time zone aware.


        :return:
            Returns ``True`` if ambiguous, ``False`` otherwise.

        .. versionadded:: 2.6.0
        FN)r   )hasdstrH   r   r   rE   )r#   r   startendr   r   r   r5   `  s
    ztzrangebase.is_ambiguousc             C   sj   | j s
dS |d krd S | j|j}|d kr.dS |jd d}| j||}| rb| j|rb| j| S |S d S )NF)r   )rL   rH   r   r   rI   r5   r:   )r#   r   rH   rD   r   r   r   rA   v  s    ztzrangebase._isdstc             C   sT   |\}}|j d d}||k r6||  ko.|k n  }n||  koH|k n   }|S )N)r   )r   )r#   r   rH   rJ   rK   rD   r   r   r   rI     s    ztzrangebase._naive_isdstc             C   s   | j | j S )N)rB   rC   )r#   r   r   r   rE     s    ztzrangebase._dst_base_offsetNc             C   s
   | |k S )Nr   )r#   otherr   r   r   __ne__  s    ztzrangebase.__ne__c             C   s   d| j j S )Nz%s(...))r"   r&   )r#   r   r   r   __repr__  s    ztzrangebase.__repr__)r&   r'   r(   r)   r@   r4   r7   r   rG   r1   r5   rA   rI   r+   rE   __hash__rP   rQ   object
__reduce__r   r   r   r   r>     s   

!r>   N)r   )r   )sixr   	functoolsr   r   r   r   rF   __all__r   hasattrr   r   r2   r3   r>   r   r   r   r   <module>   s   
,
v