U
    j                     @  s   d dl mZ d dlmZmZmZ d dlmZ ddlm	Z	 erld dl
Z
d dlmZ d dlmZmZ dd	lmZ d
ZG dd dZdgZdS )    )annotations)TYPE_CHECKINGOptionalUnion)to_datetime   )WINDOWS_TO_OLSONN)rrule)calprop)
TZProviderzoneinfoc                   @  s  e Zd ZdZefddddZdddd	Zddd
dZdddddZddddZ	dd Z
dddddZddddddZddddd Zd!d"dd#d$d%Zdd&dd'd(Zd)d)d*d+d,Zd)d-d.d/d0Zd1dd2d3Zd1dd4d5Zed)dd6d7Zd)dd8d9Zd:S );TZPzThis is the timezone provider proxy.

    If you would like to have another timezone implementation,
    you can create a new one and pass it to this proxy.
    All of icalendar will then use this timezone implementation.
    zUnion[str, TZProvider])providerc                 C  s   |  | dS )z+Create a new timezone implementation proxy.N)useselfr    r   :/tmp/pip-unpacked-wheel-g40nyxg1/icalendar/timezone/tzp.py__init__   s    zTZP.__init__None)returnc                 C  s   ddl m} | |  dS )z"Use pytz as the timezone provider.r   )PYTZN)Zpytzr   _use)r   r   r   r   r   use_pytz!   s    zTZP.use_pytzc                 C  s   ddl m} | |  dS )z&Use zoneinfo as the timezone provider.r   )ZONEINFON)r   r   r   )r   r   r   r   r   use_zoneinfo'   s    zTZP.use_zoneinfor   )r   r   c                 C  s   i | _ || _dS )zUse a timezone implementation.N)_TZP__tz_cache_TZP__providerr   r   r   r   r   -   s    zTZP._usec                 C  sJ   t |tr<t| d| d}|dkr4td| d|  n
| | dS )z(Switch to a different timezone provider.Zuse_NzUnknown provider z. Use 'pytz' or 'zoneinfo'.)
isinstancestrgetattr
ValueErrorr   )r   r   Zuse_providerr   r   r   r   2   s    

zTZP.usec                 C  s   |  t dS )z"Use the default timezone provider.N)r   DEFAULT_TIMEZONE_PROVIDERr   r   r   r   use_default>   s    zTZP.use_defaultzdatetime.datezdatetime.datetime)dtr   c                 C  s   | j t|S )zgReturn the datetime in UTC.

        If the datetime has no timezone, set UTC as its timezone.
        )r   localize_utcr   )r   r&   r   r   r   r'   B   s    zTZP.localize_utcz!Union[datetime.tzinfo, str, None])r&   tzr   c                 C  s:   t |tr| |}|dkr(|jddS | jt||S )z"Localize a datetime to a timezone.N)tzinfo)r   r    timezonereplacer   localizer   )r   r&   r(   r   r   r   r,   I   s
    

zTZP.localizezcal.Timezone)timezone_componentr   c                 C  sL   |d }|  |}| j|sH| j|sH|| jkrH|j| dd| j|< dS )zCache the timezone that is created from a timezone component
        if it is not already known.

        This can influence the result from timezone(): Once cached, the
        custom timezone is returned from timezone().
        ZTZIDF)Zlookup_tzidN)clean_timezone_idr   Zknows_timezone_idr   Zto_tz)r   r-   _unclean_idZ_idr   r   r   cache_timezone_componentS   s    


zTZP.cache_timezone_componentr	   zprop.vRecur)r	   
ical_rruler   c                 C  s   | j || dS )z Make sure the until value works.N)r   fix_rrule_until)r   r	   r1   r   r   r   r2   c   s    zTZP.fix_rrule_untilzdatetime.tzinfoc                 C  s   | j |S )zaCreate a timezone from a timezone component.

        This component will not be cached.
        )r   create_timezone)r   r-   r   r   r   r3   g   s    zTZP.create_timezoner    )tzidr   c                 C  s
   | dS )zReturn a clean version of the timezone id.

        Timezone ids can be a bit unclean, starting with a / for example.
        Internally, we should use this to identify timezones.
        /)strip)r   r4   r   r   r   r.   n   s    zTZP.clean_timezone_idzOptional[datetime.tzinfo])tz_idr   c                 C  sZ   |}|  |}| j|}|dk	r&|S |tkr>| jt| }|pX| j|pX| j|S )z:Return a timezone with an id or None if we cannot find it.N)r.   r   r*   r   r   get)r   r7   r/   r(   r   r   r   r*   v   s    
zTZP.timezoneboolc                 C  s
   | j  S )zWhether we use pytz at all.)r   	uses_pytzr$   r   r   r   r:      s    zTZP.uses_pytzc                 C  s
   | j  S )zWhether we use zoneinfo.)r   uses_zoneinfor$   r   r   r   r;      s    zTZP.uses_zoneinfoc                 C  s   | j jS )z(The name of the timezone component used.)r   namer$   r   r   r   r<      s    zTZP.namec                 C  s   | j j dt| j dS )N())	__class____name__reprr<   r$   r   r   r   __repr__   s    zTZP.__repr__N)r@   
__module____qualname____doc__r#   r   r   r   r   r   r%   r'   r,   r0   r2   r3   r.   r*   r:   r;   propertyr<   rB   r   r   r   r   r      s&   
r   )
__future__r   typingr   r   r   Zicalendar.toolsr   Zwindows_to_olsonr   datetimeZdateutil.rruler	   Z	icalendarr
   r   r   r   r#   r   __all__r   r   r   r   <module>   s   }