U
    <cN>                     @   s  d dl Z d dl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 d dlmZmZmZmZ d dlmZ d dlmZ d dlmZ G dd	 d	eZG d
d dejZG dd dejZeeeee ej!e"ej#e$e	e%ee&ee'ede(di	Z)d#ddZ*d$ddZ+d%ddZ,dd Z-G dd dZ.edddZ/e.ee/ Z0G dd deZ1G dd de1Z2dd  Z3d!d" Z4dS )&    N)hook_iterator_SnapshotState)
AnyDictIteratorGenericListSetTupleTypeVarUnionget_type_hints)
_eval_type	_tp_cache_type_check
_type_repr)
ForwardRef)ABCMeta)_GenericAliasc                   @   s   e Zd ZdS )GenericMetaN__name__
__module____qualname__ r   r   F/tmp/pip-unpacked-wheel-gikjz4vx/torch/utils/data/datapipes/_typing.pyr      s   r   c                   @   s   e Zd ZdS )IntegerNr   r   r   r   r   r      s   r   c                   @   s   e Zd ZdS )BooleanNr   r   r   r   r   r      s   r   Tc                    s   t | | } t ||}|tks(| |kr,dS t|trJt|ddtkrJdS |tdkrZdS t| t	 dksvt krzdS | tkrdS t| }t	|dkrdS t
 fdd|D S )a  
    Check if the left-side type is a subtype of the right-side type.
    If any of type is a composite type like `Union` and `TypeVar` with
    bounds, it would be expanded into a list of types and check all
    of left-side types are subtypes of either one from right-side types.
    T
__origin__NFr   c                 3   s   | ]}t | V  qd S N_issubtype_with_constraints).0variantconstraints	recursiver   r   	<genexpr>W   s     zissubtype.<locals>.<genexpr>)TYPE2ABCgetr   
isinstancer   getattrr   type_decompose_typelenall)leftrightr&   variantsr   r$   r   	issubtype3   s$    
r3   c                 C   sj   t | tr*| jd k	r| jg}qTt| j}n*t| drF| jtkrF| j}n|sNd S | g}tdd |D }|S )Nr   c                 s   s   | ]}t ||V  qd S r   )r(   r)   )r"   Z_tr   r   r   r'   h   s     z"_decompose_type.<locals>.<genexpr>)	r*   r   	__bound__list__constraints__hasattrr   r   __args__)tto_listtsr   r   r   r-   Z   s    


r-   c           
         sB  |  krdS t | dd}|dk	r8t fdd|D S t| dr`| jdk	r`| j}t| dd}n| }d} D ]}t |dd}|dk	rt| |r dS qlt|dr.|jdk	r.|j}||kr<s dS t|dd}	|	dkst|	d	kr dS |dk	r<t|t|	kr<td
d t||	D r< dS ql||krl dS qldS )z
    Check if the variant is a subtype of either one from constraints.
    For composite types like `Union` and `TypeVar` with bounds, they
    would be expanded for testing.
    TF)r:   Nc                 3   s   | ]}t | V  qd S r   r    )r"   vr$   r   r   r'      s     z._issubtype_with_constraints.<locals>.<genexpr>r   r8   r   c                 s   s   | ]\}}t ||V  qd S r   )r3   )r"   Zv_argZc_argr   r   r   r'      s     )r-   r/   r7   r   r+   r!   r.   zip)
r#   r%   r&   vsZv_originZv_args
constraintcsZc_originZc_argsr   r$   r   r!   l   s<    
r!   c                    s   t t| |ddsdS t|dd }t| trp|d ks@t|dkrDdS t|t| krXdS tdd t| |D S t| tt	fr|d kst|dkrdS |d tfdd| D S t| t
r|d kst|dkrdS |\ t fd	d|  D S dS )
NF)r&   r8   r   Tc                 s   s   | ]\}}t ||V  qd S r   issubinstance)r"   dr9   r   r   r   r'      s     z issubinstance.<locals>.<genexpr>c                 3   s   | ]}t | V  qd S r   rA   )r"   rC   )r9   r   r   r'      s     c                 3   s&   | ]\}}t | ot |V  qd S r   rA   )r"   kr<   )ktvtr   r   r'      s     )r3   r,   r+   r*   tupler.   r/   r=   r5   setdictitems)data	data_typeZdt_argsr   )rE   r9   rF   r   rB      s(    

rB   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )_DataPipeTypez)
    Save type annotation in `param`
    c                 C   s
   || _ d S r   )param)selfrN   r   r   r   __init__   s    z_DataPipeType.__init__c                 C   s
   t | jS r   )r   rN   rO   r   r   r   __repr__   s    z_DataPipeType.__repr__c                 C   s   t |tr| j|jkS tS r   )r*   rM   rN   NotImplementedrO   otherr   r   r   __eq__   s    
z_DataPipeType.__eq__c                 C   s
   t | jS r   )hashrN   rQ   r   r   r   __hash__   s    z_DataPipeType.__hash__c                 C   sf   t |jtr"t|jdd tkr"dS t |tr:t| j|jS t |trPt| j|S td	t|d S )Nr   Tz0Expected '_DataPipeType' or 'type', but found {})
r*   rN   r   r+   r   rM   r3   r,   	TypeErrorformatrT   r   r   r   r3      s    

z_DataPipeType.issubtypec                 C   s   t || jS r   )rB   rN   rT   r   r   r   issubtype_of_instance   s    z#_DataPipeType.issubtype_of_instanceN)
r   r   r   __doc__rP   rR   rV   rX   r3   r[   r   r   r   r   rM      s   
rM   T_co)	covariantc                       sR   e Zd ZU dZeed<  fddZ fddZedd Z	d	d
 Z
dd Z  ZS )_DataPipeMetaz
    Metaclass for `DataPipe`. Add `type` attribute and `__init_subclass__` based
    on the type, and validate the return hint of `__iter__`.

    Note that there is subclass `_IterDataPipeMeta` specifically for `IterDataPipe`.
    r,   c                    sr   t  j| |||f|S d|d< |D ](}t|tr"t  j| |||f|  S q"|ttd t  j| |||f|S )Nr,   F__type_class__)r,   __init_subclass__)super__new__r   r*   r_   update_DEFAULT_TYPE_dp_init_subclass)clsnamebases	namespacekwargsbase	__class__r   r   rc     s       
z_DataPipeMeta.__new__c                    s   t  j|||f| d S r   )rb   rP   )rO   rh   ri   rj   rk   rm   r   r   rP     s    z_DataPipeMeta.__init__c                    s  |d krt d| jt|tr*t|}t|ts:|f}d| j t fdd|D }t| jjt	rt
| jjdd }t|tr|tk	r| jj| }t|}tt| jd }| jd |  }|d t| d }| f| j }| ||t|d	d
S t|dkrt d| t|t|d }|| jsFt d|| j| j|krV| S | jd t| d }| f| j }| ||td	|dS )Nz{}[t]: t can not be Nonez{}[t]: t must be a typec                 3   s   | ]}t | V  qd S r   )r   )r"   pmsgr   r   r'   !  s     z*_DataPipeMeta._getitem_.<locals>.<genexpr>r      []T)ra   r,   r`      z0Too many parameters for {} actual {}, expected 1r   z1Can not subclass a DataPipe[{}] from DataPipe[{}])ra   r`   r,   )rY   rZ   r   r*   strr   rG   r,   rN   r   r+   r   rM   r.   	__bases__rn   rf   r3   )rO   paramsorigro   r9   lrh   ri   r   rp   r   	_getitem_  sR    

 z_DataPipeMeta._getitem_c                 C   sB   t |tstS | jd ks"|jd kr*| |kS | j|jko@| j|jkS r   )r*   r_   rS   r   r,   rT   r   r   r   _eq_G  s    

z_DataPipeMeta._eq_c                 C   s   t | j| jfS r   )rW   r   r,   rQ   r   r   r   _hash_P  s    z_DataPipeMeta._hash_)r   r   r   r\   rM   __annotations__rc   rP   r   r{   r|   r}   __classcell__r   r   rm   r   r_      s   

/	r_   c                       s    e Zd ZdZ fddZ  ZS )_IterDataPipeMetaz
    Metaclass for `IterDataPipe` and inherits from `_DataPipeMeta`. Aad various functions for behaviors
    specific to `IterDataPipe`.
    c                    s\   d|kr.|d  t   fdd}||d< d|krFt|d| t j| |||f|S )Nresetc                     s<   | d }|j tjtjfkr0d|_d|_ | | tj|_ dS )z
                Only execute DataPipe's `reset()` method if `_SnapshotState` is `Iterating` or `NotStarted`. This allows recently
                restored DataPipe to preserve its restored state during the initial `__iter__` call.
                r   N)Z_snapshot_stater   Z	IteratingZ
NotStartedZ_number_of_samples_yieldedZ_fast_forward_iterator)argsrk   ZdatapipeZ
reset_funcr   r   conditional_reset_  s    
z4_IterDataPipeMeta.__new__.<locals>.conditional_reset__iter__zenumerate(DataPipe)#{})	functoolswrapsr   rZ   rb   rc   )rg   rh   ri   rj   rk   r   rm   r   r   rc   Z  s    z_IterDataPipeMeta.__new__)r   r   r   r\   rc   r   r   r   rm   r   r   T  s   r   c           
   
   O   s>  t | _ t| ddrd S t| jjtrtj| j j	}zt
| jj|t }|| j_W n8 tk
r } ztd| jjj|W 5 d }~X Y nX d| j	kr:| j	d }t|}d|kr:|d }|tkrd S t|dr|jtks|jtjjkstd| jt|d |jd }	t|	| jjs:td	| jt|	| jd S )
Nr`   Fz${} is not supported by Python typingr   returnr   zOExpected 'Iterator' as the return annotation for `__iter__` of {}, but found {}r   zJExpected return type of '__iter__' as a subtype of {}, but found {} for {})reinforce_typer+   r*   r,   rN   r   sysmodulesr   __dict__r   localsrY   rZ   __forward_arg__r   r   r7   r   collectionsabcr   r   r8   r3   )
Zsub_clsr   rk   base_globalsrN   eZiter_fnhintsZreturn_hintrL   r   r   r   rf   u  sJ    


 

  rf   c                 C   sP   t |trt| }t|dd t|| jjsBtd| jt	|t
|| _| S )z
    Reinforce the type for DataPipe instance. And the 'expected_type' is required
    to be a subtype of the original type hint to restrict the type requirement
    of DataPipe instance.
    z'expected_type' must be a typerp   z7Expected 'expected_type' as subtype of {}, but found {})r*   rG   r
   r   r3   r,   rN   rY   rZ   r   rM   )rO   Zexpected_typer   r   r   r     s    
 
r   )T)T)T)5r   r   Znumbersr   Z)torch.utils.data.datapipes._hook_iteratorr   r   typingr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   r   Integralr   r   boolintfloatRealcomplexComplexrI   r5   rH   rG   r,   r(   r3   r-   r!   rB   rM   r]   re   r_   r   rf   r   r   r   r   r   <module>   sT   0	         
'

D""\!(