U
    Mh)                  	   @   sL  U d dl Z d dlZd dlmZ d dlmZmZmZmZm	Z	m
Z
 ee eedddZeeeee	eeef  ddd	Zee ee ee d
ddZeedddZeedddZee	eeef eeef ee eeee f f dddZee e	eeef eeef ee eeee f f dddZd6eeee dddZeedddZd7e
eee f ee ee eeeef eee dd d!Zd"Zeed#< d$d%hZee ed&< e Zee ed'< d(d(d)Zeeef ed*< d+Zeed,< d$d%hZee ed-< e Zee ed.< d/d0iZ eeef ed1< dd2d3d4Z!e"d5krHe!  dS )8    N)defaultdict)AnyDictListSetTupleUnion)linesindentationreturnc                 C   sF   d}dd|  }t | D ](\}}|dkr0||7 }||d|7 }q|S )N 
 r   )	enumeratereplace)r	   r
   outputZnew_line_with_indentiline r   T/var/www/html/venv/lib/python3.8/site-packages/torch/utils/data/datapipes/gen_pyi.pymaterialize_lines   s    r   dirtemplate_nameoutput_namereplacementsc              
   C   s~   t j| |}t j| |}t|}| }W 5 Q R X |D ]<\}}	}
t|d"}||t|	|
}|| W 5 Q R X q<d S )Nw)ospathjoinopenreadr   r   write)r   r   r   r   Ztemplate_pathZoutput_pathfcontentplaceholderr	   r
   r   r   r   gen_from_template   s    
r&   )	dir_pathsfiles_to_excluder   c                    sV   t  }| D ]F t }dd |D }fdd|D }| fdd|D  q
|S )z
    When given a path to a directory, returns the paths to the relevant files within it.

    This function does NOT recursive traverse to subdirectories.
    c                 S   s    h | ]}d |dd kr|qS )z.pyNr   .0fnamer   r   r   	<setcomp>(   s      z"find_file_paths.<locals>.<setcomp>c                    s   h | ]}| kr|qS r   r   r*   r(   r   r   r-   )   s      c                    s   h | ]}t j |qS r   r   r   r   r*   )dir_pathr   r   r-   *   s     )setr   listdirupdate)r'   r(   paths	all_filesZpython_filesZfilter_filesr   )r0   r(   r   find_file_paths   s    
r6   )r   r   c                 C   s\   d| krd\}}n d| kr$d\}}nt d|  | |t| | | }}| || S )zXExtract method name from decorator in the form of "@functional_datapipe({method_name})".(")r7   z")(')r8   z')z4Unable to find appropriate method name within line:
)RuntimeErrorfindlenr   Zstart_tokenZ	end_tokenstartendr   r   r   extract_method_name.   s    

r?   c                 C   s2   d}d}|  |t| |  | }}| || S )zVExtract class name from class definition in the form of "class {CLASS_NAME}({Type}):".class ()r:   r;   r<   r   r   r   extract_class_name:   s    rB   )	file_pathr   c              	   C   s  i i t    }}}tt}t| d}d}d\}}}	d}
|D ]D}|dd dkrZ|
 }
|
sfd|krv|| | q<d|krt|}g ||< q<|rd|krt|}q<|rd	|ksd
|krd
|kr|| |d7 }|	dt
d }||d }|dkr<||d7 }||d8 }|dkrZ|d}|	|d| 7 }	t|	||< |||< d\}}}	q<|dk rntdq<|	|dd7 }	q<W 5 Q R X ||||fS )zfGiven a path to file, parses the file and returns a dictionary of method names to function signatures.r   )r   r   r   Fz"""      z@functional_datapiper@   zdef __init__(zdef __new__(rA   N)z7open parenthesis count < 0. This shouldn't be possible.r   r   )r1   r   listr    countappendr?   rB   addr:   r;   rfindprocess_signaturer9   strip)rC   method_to_signaturemethod_to_class_nameZspecial_output_typedoc_string_dictr#   Zopen_paren_countmethod_name
class_name	signatureskipr   r=   r>   r   r   r   parse_datapipe_fileB   sL    






 rU   )
file_pathsr   c           
      C   sd   i i t    }}}i }| D ]<}t|\}}}}	|| || || ||	 q||||fS )N)r1   rU   r3   )
rV   methods_and_signaturesmethods_and_class_namesZ!methods_with_special_output_typesmethods_and_doc_stringsr   rN   rO   Z$methods_needing_special_output_typesrP   r   r   r   parse_datapipe_filesm   s    


rZ   ,)r   	delimiterr   c                 C   sp   d}d}g }| D ]P}|dkr&|d7 }n2|dkr8|d8 }n ||krX|dkrX| | d}q||7 }q| | |S )zRGiven a line of text, split it on comma unless the comma is within a bracket '[]'.r   r   [rE   ])rI   )r   r\   Zbracket_countZ
curr_tokenrescharr   r   r   split_outside_bracket~   s    




ra   c                 C   s   t | }t|D ]\}}|d||< |dkr8d||< q|dkrjd||d  krj|| d dkrjd||< qd|kr|d	d
\}}|dd ||< qdd |D }d|} | S )z
    Clean up a given raw function signature.

    This includes removing the self-referential datapipe argument, default
    arguments of input functions, newlines, and spaces.
    r   clsselfr   rE   *r   z
Callable ==rD   z= ...c                 S   s   g | ]}|d kr|qS )r   r   )r+   tr   r   r   
<listcomp>   s      z%process_signature.<locals>.<listcomp>z, )ra   r   rM   rsplitr   )r   tokensr   tokenheadZdefault_argr   r   r   rL      s    
(

rL   r   )rC   r(   deprecated_filesdefault_output_typemethod_to_special_output_typerootr   c                    s
   dkrt ttj  t| t r,| gn| }  fdd| D } t| ||d}t	|\}}}	}
|D ]}||	krh|	
| qhg }| D ]h\}}|| }||	kr|| }n|}d|
| }|dkrd}|d| d| d| d	| d
| 
 q|jdd d |S )a  
    #.pyi generation for functional DataPipes Process.

    # 1. Find files that we want to process (exclude the ones who don't)
    # 2. Parse method name and signature
    # 3. Remove first argument after self (unless it is "*datapipes"), default args, and spaces
    r   c                    s   g | ]}t j |qS r   r/   )r+   r   ro   r   r   rg      s     z*get_method_definitions.<locals>.<listcomp>r.   z    ...
z# Functional form of 'z'
def rA   z) -> z:
c                 S   s   |  dd S )Nr   rE   )split)sr   r   r   <lambda>       z(get_method_definitions.<locals>.<lambda>)key)strpathlibPath__file__parentresolve
isinstancer6   unionrZ   rJ   itemsr   rI   sort)rC   r(   rl   rm   rn   ro   rV   rW   rX   Zmethods_w_special_output_typesrY   fn_nameZmethod_definitionsrQ   	argumentsrR   output_typeZ
doc_stringr   rp   r   get_method_definitions   s0    

*r   iteriterDP_file_pathz__init__.pyzutils.pyiterDP_files_to_excludeiterDP_deprecated_fileszList[IterDataPipe])Zdemuxfork$iterDP_method_to_special_output_typemapmapDP_file_pathmapDP_files_to_excludemapDP_deprecated_filesshuffleIterDataPipe#mapDP_method_to_special_output_type)r   c                  C   s\   t tttdt} t tttdt}t	
tj }d| dfd|dfg}tt|dd|d d	S )
a  
    # Inject file into template datapipe.pyi.in.

    TODO: The current implementation of this script only generates interfaces for built-in methods. To generate
          interface for user-defined DataPipes, consider changing `IterDataPipe.register_datapipe_as_function`.
    r   ZMapDataPipez${IterDataPipeMethods}   z${MapDataPipeMethods}zdatapipe.pyi.inzdatapipe.pyir   N)r   r   r   r   r   r   r   r   r   rw   rx   ry   rz   r{   r&   rv   )Ziter_method_definitionsZmap_method_definitionsr   r   r   r   r   main   s"      r   __main__)r[   )r   )#r   rw   collectionsr   typingr   r   r   r   r   r   rv   intr   r&   r6   r?   rB   rU   rZ   ra   rL   r   r   __annotations__r   r1   r   r   r   r   r   r   r   __name__r   r   r   r   <module>   sB     
"<+@ 
 -
