o
    3g*                     @  s  d Z ddlmZ ddlZddlmZmZmZmZ ddl	m
Z
mZmZmZmZ ddlZddlmZ ddlmZ dd	lmZ ed
ZedZedZdPddZdQddZdRddZeddSddZdRd d!Zed"Zed#ZedTd+d,Ze
r{dUd.d/Z neZ dRd0d1Z!ed2d3 Z"e
red4ed5ef d6Z#dVd7d8Z$ne"Z$dRd9d:Z%dRd;d<Z&dRd=d>Z'ed?ed6Z(dWdBdCZ)dRdDdEZ*edFZ+edGZ,	dXdYdLdMZ-dRdNdOZ.dS )Zz
Various helpers/transforms of iterators

Ideally this should be as small as possible and we should rely on stdlib itertools or more_itertools
    )annotationsN)HashableIterableIteratorSized)TYPE_CHECKINGCallableTypeVarUnioncast)	decorator   )warnings)	ParamSpecTKVvreturnc                 C  s
   t t| S N)r   r   )r    r   1/home/garg/my-data/HPI/my/core/utils/itertools.py	_identity   s   
r   itIterable[T]keyCallable[[T], K]c                c  sX    i }| D ]$}||}| |d }|d ur"td| d| d| |||< |V  qd S )NzDuplicate key: z. Previous value: z, new value: )getRuntimeError)r   r   key2itemikpir   r   r   ensure_unique$   s   r#   Nonec                  C  s   dd l } ttg ddd dg dksJ g d}t|dd d}| jtdd	 t| W d    n1 s8w   Y  tt|d
d d d S )Nr      r      c                 S     | S r   r   r    r   r   r   <lambda>2       z$test_ensure_unique.<locals>.<lambda>r   )r&   r   r&      c                 S  r(   r   r   r)   r   r   r   r*   6   r+   Duplicate keymatchc                 S  s   t  S r   )object)_r   r   r   r*   =   s    )pytestlistr#   raisesr   )r3   dupsr   r   r   r   test_ensure_unique/   s   $
r7   )valuer8   Callable[[T], V]
dict[K, V]c                  sP    fdd| D }t |dd d}i }|D ]\}}|d u r|n||||< q|S )Nc                 3  s    | ]	} ||fV  qd S r   r   ).0r    r,   r   r   	<genexpr>G   s    zmake_dict.<locals>.<genexpr>c                 S  s   | d S )Nr   r   )pr   r   r   r*   H       zmake_dict.<locals>.<lambda>r,   )r#   )r   r   r8   	with_keysuniquesresr!   r    r   r,   r   	make_dict@   s   rB   c                  C  s   dd l } td}t|dd dd d}|ddddddksJ td}| jtd	d
 t|dd dd d}W d    n1 s@w   Y  t|dd d}t|dd dd d}d S )Nr      c                 S  r(   r   r   r)   r   r   r   r*   S   r+   z test_make_dict.<locals>.<lambda>c                 S     | d S Nr   r   r)   r   r   r   r*   S   r>   )r   r8   r&   )r   r&   r   r'   r-   r.   r/   c                 S  rD   rE   r   r)   r   r   r   r*   X   r>   c                 S  r(   r   r   r)   r   r   r   r*   X   r+   c                 S     t | S r   strr)   r   r   r   r*   [   r>   r,   c                 S  rF   r   rG   r)   r   r   r   r*   \   r>   c                 S  s   | d dkS )Nr   r   r   r)   r   r   r   r*   \   s    )r3   rangerB   r5   r   )r3   r   dd2d3r   r   r   test_make_dictO   s   rM   LFPLVfuncCallable[LFP, Iterable[LV]]argsLFP.argskwargs
LFP.kwargslist[LV]c                 O  s   t | |i |S )z
    Wraps a function's return value in wrapper (e.g. list)
    Useful when an algorithm can be expressed more cleanly as a generator
    )r4   )rP   rR   rT   r   r   r   _listifyc   s   rW   Callable[LFP, list[LV]]c                 C     d S r   r   rP   r   r   r   listifyq   r+   r[   c                  C  sB   ddl m}  tddd}| }| |tt  |ddgksJ d S )	Nr   assert_typer   Iterator[int]c                   s      dV  dV  d S )Nr&   r   r   r   r   r   r   r   z      
ztest_listify.<locals>.itr&   r   r^   )compatr]   r[   r4   int)r]   r   rA   r   r   r   test_listifyw   s   rd   c                   sR    |i |t trt}|dkrtd  d S  fdd}| S )Nr   	Function zB returned empty container, make sure your config paths are correctc                  3  s8    d} D ]}|V  d} q| rt d  d d S d S )NTFre   z> didn't emit any data, make sure your config paths are correct)core_warningsmedium)emptyr    rP   iterabler   r   wit   s   z_warn_if_empty.<locals>.wit)
isinstancer   lenrf   rg   )rP   rR   rT   szrk   r   ri   r   _warn_if_empty   s   
ro   FF.)boundc                 C  rY   r   r   rZ   r   r   r   warn_if_empty   r+   rr   c                  C  s  ddl m}  tddd}tjdd,}| }t|d	ksJ | |tt  t|d
dgks0J t|d	ks8J W d    n1 sBw   Y  tddd}tjdd+}| }t|d	ks`J | |tt	  t|g ksoJ t|dkswJ W d    d S 1 sw   Y  d S )Nr   r\   r   Iterator[str]c                   s  r_   )Naabar   r   r   r   r   nonempty   r`   z-test_warn_if_empty_iterator.<locals>.nonemptyTrecordr   rt   ru   r^   c                   s  s    g E d H  d S r   r   r   r   r   r   rh      s   z*test_warn_if_empty_iterator.<locals>.emptyr&   )r   rs   ra   )
rb   r]   rr   r   catch_warningsrm   r   rH   r4   rc   r]   rv   wres1rh   res2r   r   r   test_warn_if_empty_iterator   s&   "r~   c                    s  ddl m}  g d td fdd}tjdd	'}| }t|d
ks%J | |tt  t|ts3J | u s9J W d    n1 sCw   Y  tddd}tjdd	(}| }t|dksaJ | |tt	  t|tsoJ |g ksuJ W d    d S 1 sw   Y  d S )Nr   r\   r%   r   	list[int]c                     s    S r   r   r   llr   r   rv         z)test_warn_if_empty_list.<locals>.nonemptyTrw   r   	list[str]c                   S  s   g S r   r   r   r   r   r   rh      r   z&test_warn_if_empty_list.<locals>.emptyr&   )r   r   )r   r   )
rb   r]   rr   r   ry   rm   r4   rc   rl   rH   rz   r   r   r   test_warn_if_empty_list   s(   "r   c                  C  s   t ddd} d S )Nr   floatc                   S  s   dS )Ng        r   r   r   r   r   bad_return_type   r   z7test_warn_if_empty_unsupported.<locals>.bad_return_type)r   r   )rr   )r   r   r   r   test_warn_if_empty_unsupported   s   r   _HTrj   Iterable[_HT]c                   s>   t  trd fdd}| S  D ]}t |tsJ |q S )a/  
    NOTE: Despite Hashable bound, typing annotation doesn't guarantee runtime safety
          Consider hashable type X, and Y that inherits from X, but not hashable
          Then l: list[X] = [Y(...)] is a valid expression, and type checks against Hashable,
           but isn't runtime hashable
    r   Iterator[_HT]c                  3  s.     D ]} t | tsJ | tt| V  qd S r   )rl   r   r   r   r)   rj   r   r   rA      s
   zcheck_if_hashable.<locals>.resN)r   r   )rl   r   r   )rj   rA   r    r   r   r   check_if_hashable   s   

r   c                  C  s  ddl m}  dd l}ddlm} ddg}t|}||tt  ||u s%J td}t|}||tt	tt
f   t|ddgksBJ d	}t|}||tt  ||u sUJ h d
h dg}	|t t|	}
W d    n1 sqw   Y  tddhddhg}t|}|t t| W d    n1 sw   Y  | ddG dd d}|ddg}t|}||u sJ | G dd d|}|dddg}|t t| W d    d S 1 sw   Y  d S )Nr   )	dataclassr   r\   r&   ){   ru   r   ru   )i  ru   >   r&   r   r'   >   r-   rC      r'   r-   T)unsafe_hashc                   @     e Zd ZU ded< dS )z!test_check_if_hashable.<locals>.Xrc   rt   N__name__
__module____qualname____annotations__r   r   r   r   X,     
 r   )rt   c                   @  r   )z!test_check_if_hashable.<locals>.YrH   bNr   r   r   r   r   Y5  r   r   )rt   r   )dataclassesr   r3   rb   r]   r   r   rc   iterr
   rH   r4   r1   r5   	Exception)r   r3   r]   x1r1x2r2x3r3x4r4x5r5r   x6r6r   x7r   r   r   test_check_if_hashable  sF   


"r   _UET_UEUfun-Callable[[], Iterable[_UET]] | Iterable[_UET]Callable[[_UET], _UEU] | NoneIterator[_UET]c                 C  sJ   dd l }t| r|  }n| }|d u r|jdd urt|}tj||dS )Nr   HPI_CHECK_UNIQUE_EVERSEEN)rj   r   )oscallableenvironr   r   more_itertoolsunique_everseen)r   r   r   rj   r   r   r   r   G  s   r   c               	   C  s  dd l } ddlm} ddd}dd	 }|d
d< tt|dgks$J | t t| W d    n1 s8w   Y  g d}tt|g dksMJ W d    n1 sWw   Y  |d
d  tt|ddhddhgksrJ W d    d S 1 s}w   Y  d S )Nr   r   )tmp_environ_setr   r^   c                   s  s    dV  d S )Nr   r   r   r   r   r   fun_good_  s   
z&test_unique_everseen.<locals>.fun_goodc                   S  s   ddhddhddhgS )Nr&   r   r'   r   r   r   r   r   fun_badb  s   z%test_unique_everseen.<locals>.fun_badr   yesr   )r-   r'   r   r&   r   r'   r-   )r-   r'   r   r&   r&   r'   ra   )r3   tests.commonr   r4   r   r5   r   )r3   r   r   r   	good_listr   r   r   test_unique_everseenZ  s   

""r   )r   r   r   r   )r   r   r   r   r   r   )r   r$   )r   r   r   r   r8   r9   r   r:   )rP   rQ   rR   rS   rT   rU   r   rV   )rP   rQ   r   rX   )rP   rp   r   rp   )rj   r   r   r   r   )r   r   r   r   r   r   )/__doc__
__future__r   r   collections.abcr   r   r   r   typingr   r   r	   r
   r   r   r    rf   rb   r   r   r   r   r   r#   r7   rB   rM   rN   rO   rW   r[   rd   ro   rp   rr   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sV    










8