o
    ॵiu                     @   s  d dl Z d dlZd dlZd dlZd dlmZ d dlZd dlZd dl	m	Z	 d dl
mZ d dlmZ d dlm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mZmZmZmZmZ d dlm Z m!Z! d d	l"m#Z# d d
l$m%Z% ee&Z'dZ(e') j*d Z+e# Z,dZ-ddgZ.g dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9dZ:dZ;dZ<dZ=dZ>d Z?d!Z@d"ZAd#ZBd$d% ZCeC ZDG d&d' d'eEZFG d(d) d)eEZGeG ZHd*eIdeeJef d+dfd,d-ZKd?d/d0ZLd@d1d2ZMd3d4 ZNd5d6 ZOdd.e,e0fd7d8ZPdAd9d:ZQdBd;d<ZReSd=krePdd>ZTeUeT dS dS )C    N)datetime)reduce)Path)Union)version)CustomDatasetsHeadsHooksLR_SchedulersMetricsModels
Optimizers	PipelinesPreprocessors
TaskModelsTrainers)FieldsTasks)get_modelscope_cache_dir)default_groupT   register_module
modelscope.)modelsmetrics	pipelinespreprocessorstrainers
msdatasets	exportersast_indexer
decoratorsexpressfrom_importsimportsfilepathmodelscope_pathr   md5indexfiles_mtimerequirementsmodule
class_name	group_keymodule_name
module_clsTEMPLATE_PATHzast_index_file.pyc                  C   s   t d} | t j | S )Nzmodelscope.ast)logging	getLoggersetLevelINFO)
ast_logger r7   N/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/utils/ast_utils.pyget_ast_logger;   s   
r9   c                	   @   s&  e Zd Zd)ddZdedefddZdejdefdd	Z	de
ejd
f defddZd*dejdedefddZd*dejdedefddZdd Zde
ejdef fddZ		d+de
ejdef dededefddZdejdefddZdd Zd ed!edefd"d#Zd$edefd%d&Zd'd( ZdS ),AstScanningreturnNc                 C       t  | _t  | _g | _g | _d S N)dictresult_importresult_from_importresult_decoratorr#   selfr7   r7   r8   __init__F      
zAstScanning.__init__nodec                 C   s   t |tjot |tj S r=   )
isinstanceastASTexpr_contextrC   rF   r7   r7   r8   _is_sub_nodeL   s
   zAstScanning._is_sub_nodec                 C   sT   |j D ]$}t||}| |r dS t|ttfr'|D ]}| |r&  dS qqdS )NFT)_fieldsgetattrrL   rG   listtuple)rC   rF   fieldattrvalr7   r7   r8   _is_leafP   s   



zAstScanning._is_leafstrc                 C   s"   t rt|jdks|dkrdS dS )NFunctionDefTF)SKIP_FUNCTION_SCANNINGtype__name__rK   r7   r7   r8   _skip_function\   s   zAstScanning._skip_functionTnshow_offsetsc                 C   s   |r|j |j S |jS r=   )_attributesrM   )rC   r[   r\   r7   r7   r8   rM   b   s   zAstScanning._fieldsc                 C   s^   t  }t|tjr-t  }| j||dD ]}| jt|||d}|||< q||t|j< |S |S )Nr\   )	r>   rG   rH   rI   rM   _leafrN   rX   rY   )rC   rF   r\   output
local_dictrQ   field_outputr7   r7   r8   r_   h   s   

zAstScanning._leafc                 C   r<   r=   )r>   r?   r@   rA   result_expressrB   r7   r7   r8   _refreshu   rE   zAstScanning._refreshc                 C   s   |    | j|ddd d S )Nz  F)indentr\   )_setup_globalscan_importrK   r7   r7   r8   scan_ast{   s   zAstScanning.scan_ast parent_node_namec                    s  |d u r|S   |r j|dS 	ddttjd tf dtdtf fdd}t }t|jdkrat	|d	}|d
krad
dg| }t|d	d t	|d}|d u rYt|d| nt|d||   j|dD ]U}	t	||	}
|
g kryg ||	< n| |rqht|
trt|
d
krt|
d tjr  |
d r||
d }|||	< nQt|
trt }|
D ].}||t|j}t|j}|dks|dks|dks|dkr||vrg ||< || | q|||	< nt|
tjr||
}|||	< n|
||	< t|jdkst|jdkrt|jdkrX|	dkrt  j||	 < |	dkrXt||	 d trHg }||	 d D ]}|d d }|| q1| j|d < n||	 d d }|g j|d < t|jdkr||	 d }t|tr~|D ]}|d  j|d d < qnn| j||	 d d < d|	kr|
g kr|
D ]
}t|t|j q j|
 |
g krt|
jdkr|dkr j|
 qht jt jt jt jiS )Nr^   ri   elrj   r;   c                    s    j | |dS )N)r\   rj   )rg   )rk   rj   rC   r\   r7   r8   _scan_import   s
   z-AstScanning.scan_import.<locals>._scan_import
ImportFromlevelr   r   r   r,   Importnamesaliasnamedecorator_listCallExpr)ri   )rT   r_   r   rH   rI   rU   r>   rX   rY   rN   joinsetattrrM   rZ   rG   rO   lenappendr@   r?   
CLASS_NAMErs   rA   extendrc   
IMPORT_KEYFROM_IMPORT_KEYDECORATOR_KEYEXPRESS_KEY)rC   rF   r\   rj   rm   outputsro   
path_levelr/   rQ   rR   	local_outel_dictrk   rs   r`   	item_nameitem
local_name
final_dictr7   rl   r8   rg      s   














zAstScanning.scan_importc                    sj   dt jdtfdd dtdtf fdd}dt jdtf fdd	} |j}||j}||j}|||fS )
NrF   r;   c                 S   sV   d\}}}t | jdkrt| d}t|d}t| d}t | jdkr't| d}||fS )N)NNN	AttributevalueidrR   Name)rX   rY   rN   )rF   r   r   rR   r7   r7   r8   _get_attribute_item   s   




z9AstScanning._parse_decorator.<locals>._get_attribute_itemnodesc                    s`   g }| D ])}t |jdkr||jd f qt |jdkr&||jd f q| | q|S )NStrConstant)rX   rY   rz   sr   )r   resultrF   r   r7   r8   _get_args_name   s   z4AstScanning._parse_decorator.<locals>._get_args_namec                    s   g }| D ]C}t |jdkrGt|d}t |jdkr&|t|d|jd f qt |jdkr:|t|d|jd f q|t|df |  q|S )Nkeywordr   r   argr   )rX   rY   rN   rz   r   r   )r   r   rF   attribute_noder   r7   r8   _get_keyword_name   s&   
z7AstScanning._parse_decorator.<locals>._get_keyword_name)rH   rI   rP   rO   funcargskeywords)rC   rF   r   r   	functions	args_listkeyword_listr7   r   r8   _parse_decorator   s   




zAstScanning._parse_decoratorc                 C   sH   |d u rd S |dkrt S |d}t|dkr|S tt|d |d S )Nr   r   r   r   )r   splitry   rN   eval)rC   key_item
split_listr7   r7   r8   _get_registry_value  s   
zAstScanning._get_registry_valueparsed_inputr-   c                 C   s  |\}}}t |d krdS |d g}t|dkr#t|dkr#|t t|dkr4t|dkr4|| t|dkrbt|dkrbd}|D ]}|\}	}
}|	tkrX||
|f |}qD|durb|| t|dkrm|t |D ]}|\}	}
}|	tkr}|
}qo||
|f qo|D ]-}|du r|d q|d du r||d  qt|tr|| q|d	| q|d | 
|d | 
|d fS )zformat registry information to a tuple indexer

        Return:
            tuple: (MODELS, Tasks.text-classification, Models.structbert)
        r   Nr   r      )REGISTER_MODULEry   rz   r   	GROUP_KEYremove
MODULE_CLSrG   rU   rw   r   )rC   r   r-   r   r   r   r`   remove_group_itemr   keyrs   rR   r7   r7   r8   _registry_indexer!  sH   








zAstScanning._registry_indexerr   c                 C   sr   g }|D ]2}t |jdkrqt|td}t|d}t|ddtkr"q| |}| ||}d|ur6|| q|S )zparse the AST nodes of decorators object to registry indexer

        Args:
            nodes (list): list of AST decorator nodes

        Returns:
            list: list of registry indexer
        ru   Nr   rR   )rX   rY   rN   r{   r   r   r   rz   )rC   r   resultsrF   r-   r   parse_outputr)   r7   r7   r8   parse_decoratorsU  s   	


zAstScanning.parse_decoratorsc                 C   s   |    t|ddd}| }W d    n1 sw   Y  d|}t|}| j|dd}| |t |t< | |t	 |t	< |t 
|t	  |S )Nrutf8)encodingri   Fr^   )rd   open	readlinesrw   rH   parserg   r   r   r   r|   )rC   filecodedatarF   r`   r7   r7   r8   generate_astn  s   


zAstScanning.generate_astr;   N)T)Tri   )rY   
__module____qualname__rD   objectboolrL   rH   rI   rT   r   rZ   rP   rM   rU   r_   rd   rh   rg   r   r   r   rO   r   r   r7   r7   r7   r8   r:   D   s2    

j,4r:   c                   @   s   e Zd ZdddZ	d dededefddZd	d
 ZdedefddZ	d!ddZ
d"ddZdd Zdd Zdd Zdd ZdeefddZeedfddZdS )#FilesAstScanningr;   Nc                 C   s   t  | _g | _g | _d S r=   )r:   	astScaner	file_dirsrequirement_dirsrB   r7   r7   r8   rD   }  s   
zFilesAstScanning.__init__import_packagecurrent_pathc           	      C   s   | td rtd d|ddd  d S | td rV|d}|d}d}t|D ]\}}|dkr<|} nq0|d|  }|||d  dd| d S |S )z
        Args:
            import_package (str): relative import or abs import
            current_path (str): path/to/current/file
        r   /r   r   N.pyri   )
startswithIGNORED_PACKAGESMODELSCOPE_PATHrw   r   	enumerater|   )	rC   r   r   current_path_listimport_package_listro   r)   r   abs_path_listr7   r7   r8   _parse_import_path  s&   


z#FilesAstScanning._parse_import_pathc                 C   s   d S r=   r7   )rC   import_abs_pathr7   r7   r8   _traversal_import  s   z"FilesAstScanning._traversal_importscan_resultc                 C   s   g }| t|t   | t|t   t|D ]\}}d|dd kr.d||< q|dd ||< qt }|D ]}tD ]}|	|rM|
| qAq=tt|t| S )a  parse import and from import dicts to a third party package list

        Args:
            scan_result (dict): including the import and from import result

        Returns:
            list: a list of package ignored 'modelscope' and relative path import
        ri   r   r   )r|   rO   r}   keysr~   r   r   setr   r   add)rC   r   r`   r)   r   ignoredignored_packager7   r7   r8   parse_import  s   	


zFilesAstScanning.parse_importFc                 C   sb   g | _ |d u st|dkr| j||d d S |D ]}tj||}tj|r.| j||d qd S )Nr   include_init)r   ry   _traversal_filesospathrw   isdir)rC   r   check_sub_dirr   r   sub_dirr7   r7   r8   traversal_files  s   z FilesAstScanning.traversal_filesc                 C   s   t |}|D ]Q}|jdkr|sq|jdr|jdks(|jds(|jdr)q| r6| j|j|d q| rH|jdrH| j	
|j q| rXd|jv rX| j
|j qd S )Nz__init__.py__z.jsonz.mdr   r   requirement)r   scandirrs   r   endswithis_dirr   r   is_filer   rz   r   )rC   r   r   dir_listr   r7   r7   r8   r     s&   

z!FilesAstScanning._traversal_filesc                 C   s   z| j |}W n8 ty@ } z,t|j}td| d|d j d|d j d|d j dt	|j
 d| d| d	d }~ww | |}|t |fS )
NzDuring ast indexing the file z', a related error excepted in the file z
 at line: z: "z" with error msg: "z: z'", please double check the origin file z- to see whether the file is correctly edited.)r   r   	Exception	traceback
extract_tb__traceback__filenamelinenolinerX   rY   r   r   )rC   r   r`   edetailimport_listr7   r7   r8   _get_single_file_scan_result  s.   
	z-FilesAstScanning._get_single_file_scan_resultc              	   C   sJ   t  }|D ]}|| t D ]}t|t|| t t|| t i||< qq|S r=   )r>   r   FILE_NAME_KEYr}   
MODULE_KEY)rC   forward_indexinverted_indexr)   r   r7   r7   r8   _inverted_index  s   
z FilesAstScanning._inverted_indexc                 C   s,   t  }| D ]\}}|t ||t < q|S r=   )r>   itemsr}   r   )rC   r   module_importr)   
value_dictr7   r7   r8   _module_import  s   zFilesAstScanning._module_importc                 C   s    d|v r|d= d|v r|d= |S )N)
OPTIMIZERSdefaultrs   )LR_SCHEDULERr   rs   r7   )rC   r   r7   r7   r8   _ignore_useless_keys  s
   z%FilesAstScanning._ignore_useless_keysc                 C   s   t   }|dur|| _n| || td| d|  t }| jD ]'}||dd }|tj	ddd}| 
|\}	}
t|	t|
t|i||< q#| |}| |}| |}t|t|i}tdt| d	t   |  d
 |S )a  the entry method of the ast scan method

        Args:
            target_file_list can override the dir and folders combine
            target_dir (str, optional): the absolute path of the target directory to be scanned. Defaults to None.
            target_folder (list, optional): the list of
            sub-folders to be scanned in the target folder.
            Defaults to SCAN_SUB_FOLDERS.

        Returns:
            dict: indexer of registry
        NzAST-Scanning the path "z!" with the following sub folders r   r   r   ri   zScanning done! A number of z. components indexed or updated! Time consumed r   )timer   r   loggerinfor>   rfindreplaceospsepr   r   r}   r   r   r  r   	INDEX_KEYREQUIREMENT_KEYry   )rC   target_file_list
target_dirtarget_foldersstartr   r   r&   r/   rt   r   inverted_index_with_resultsr   r)   r7   r7   r8   get_files_scan_results  s@   




z'FilesAstScanning.get_files_scan_resultsc           
      C   s   g | _ |rt|tr|| _ n| || g }t }| j D ]}tj|}|| |||< qt	dd |d}t
| }	|	 |fS )Nc                 S   s   t | t | S r=   rU   )xyr7   r7   r8   <lambda>?  s    z2FilesAstScanning.files_mtime_md5.<locals>.<lambda>ri   )r   rG   rO   r   r>   r   r   getmtimerz   r   hashlibr(   encode	hexdigest)
rC   target_pathtarget_subfolder	file_listr*   files_mtime_dictr   mtime
result_strr(   r7   r7   r8   files_mtime_md50  s   


z FilesAstScanning.files_mtime_md5r   r=   NFF)rY   r   r   rD   rU   r   r   r>   rO   r   r   r   r   r   r   r  r   SCAN_SUB_FOLDERSr  r  r7   r7   r7   r8   r   {  s4    





3r   objr;   c                 C   sd   t j|}|rt j|st j|dd t|d}||  W d   dS 1 s+w   Y  dS )a  Write data to a given ``filepath`` with 'wb' mode.

    Note:
        ``write`` will create a directory if the directory of ``filepath``
        does not exist.

    Args:
        obj (bytes): Data to be written.
        filepath (str or Path): Path to write data.
    T)exist_okwbN)r   r   dirnameexistsmakedirsr   write)r#  r&   r&  fr7   r7   r8   ensure_writeG  s   "r+  Fc                 C   s   dd | t   D | t < ddlm} || t< tj|d\| t< | t< t	
 | t< t| }|r8|t	
 t}t| | dd | t   D | t < d S )Nc                 S   s   i | ]	\}}t ||qS r7   r  .0kvr7   r7   r8   
<dictcomp>\  s    z_save_index.<locals>.<dictcomp>r   __version__r  c                 S      i | ]
\}}t ||qS r7   rH   literal_evalr,  r7   r7   r8   r0  g      
)r	  r   modelscope.versionr2  VERSION_KEYfile_scannerr  MD5_KEYFILES_MTIME_KEYr   as_posixMODELSCOPE_PATH_KEYjsondumpsr  r1   r+  r  )r)   	file_pathr  with_templater2  
json_indexr7   r7   r8   _save_indexZ  s    


rD  c                 C   sr   t | d}| }W d    n1 sw   Y  |r%| tt }t|}dd |t	 
 D |t	< |S )Nrbc                 S   r4  r7   r5  r,  r7   r7   r8   r0  u  r7  z_load_index.<locals>.<dictcomp>)r   readdecoder  r1   r   r=  r?  loadsr	  r   )rA  rB  r*  bytes_indexwrapped_indexr7   r7   r8   _load_indexm  s   




rK  c                 C   s0  | t  }tt|t| }tt|t| }g }|D ]}||vr/|| || kr/|| q|| || t|dkrg }g }| t D ]}	| t |	 t |v rd||	 || t |	 t  qH|D ]}	| t |	= qg|D ]}	|	| t	 v r~| t	 |	= qqt
|}
| t |
t  | t	 |
t	  d S )Nr   )r<  rO   r   rz   r|   ry   r	  r   r   r
  r:  r  update)r)   r*   origin_files_mtime	new_filesremoved_filesupdated_filesr   remove_index_keysremove_requirement_keysr   updated_indexr7   r7   r8   _update_index|  s<   





rT  c                  C   sF   t tttjd } d}t tt  }| || kr!dS dS )Nz%Y-%m-%d %H:%M:%Si3TF)introundr   strptimer   __release_datetime__	timestampnow)release_timestampSECONDS_PER_YEARcurrent_timestampr7   r7   r8   __is_develop_model  s   r^  c              
   C   s:  t d|}t d|}t j||}d}|r#td t| }|S t rtd|  t j	|rkt
|}tj| d\}	}
|}ddlm} |t |krT|t |	ksZ|t |krjtd	 t||
 t|||  ntd
| d t| }t|||  td|t  d|t  dt|t  d |S t }|S )a  get the index from scan results or cache

    Args:
        file_list: load indexer only from the file lists if provided, default as None
        force_rebuild: If set true, rebuild and load index, default as False,
        indexer_file_dir: The dir where the indexer file saved, default as INDEXER_FILE_DIR
        indexer_file: The indexer file name, default as INDEXER_FILE
    Returns:
        dict: the index information for all registered modules, including key:
        index, requirements, files last modified time, modelscope home path,
        version and md5, the detail is shown below example: {
            'index': {
                ('MODELS', 'nlp', 'bert'):{
                    'filepath' : 'path/to/the/registered/model', 'imports':
                    ['os', 'torch', 'typing'] 'module':
                    'modelscope.models.nlp.bert'
                },
                ...
            }, 'requirements': {
                'modelscope.models.nlp.bert': ['os', 'torch', 'typing'],
                'modelscope.models.nlp.structbert': ['os', 'torch', 'typing'],
                ...
            }, 'files_mtime' : {
                '/User/Path/To/Your/Modelscope/modelscope/preprocessors/nlp/text_generation_preprocessor.py':
                16554565445, ...
            },'version': '0.2.3', 'md5': '8616924970fe6bc119d1562832625612',
            'modelscope_path': '/User/Path/To/Your/Modelscope'
        }
    MODELSCOPE_CACHEMODELSCOPE_INDEX_FILENz4Force rebuilding ast index from scanning every file!zLoading ast index from r3  r   r1  z}Updating the files for the changes of local files, first time updating will take longer time! Please wait till updating done!zNo valid ast index found from z$, generating ast index from scratch!z,Loading done! Current index file version is z, with md5 z and a total number of z components indexed)r   getenvr   rw   r  r  r:  r  r^  r'  rK  r  r8  r2  r9  r;  rT  rD  ry   r	  load_from_prebuilt)r  force_rebuildindexer_file_dirindexer_file	cache_dir
index_filerA  r)   rJ  r(   r*   r2  r7   r7   r8   
load_index  sV   $





rh  c                 C   sH   | d u rt  jd }tj|t} tj| r t| dd}|S d }|S )Nr   TrB  )	presolveparentsr   r   rw   TEMPLATE_FILEr'  rK  )rA  
local_pathr)   r7   r7   r8   rb    s   rb  c                 C   sT   t |d}| d u rt jd }tj|t} t|| dd tj	| s(t
d|S )Nrc  r   Tri  z;The index file is not create correctly, please double check)rh  rj  rk  rl  r   r   rw   rm  rD  r'  r   )rA  rc  r)   rn  r7   r7   r8   generate_ast_template  s   
rp  __main__ro  r   r!  r=   )NT)VrH   r  r2   r   os.pathr   r  r  r   r   	functoolsr   pathlibr   typingr   r?  r   r   modelscope.metainfor   r   r	   r
   r   r   r   r   r   r   r   modelscope.utils.constantr   r   modelscope.utils.file_utilsr   modelscope.utils.registryr   __file__rj  rW   rk  rl  r   INDEXER_FILE_DIRr   r   r"  INDEXER_FILEr   r   r~   r}   r   r>  r9  r;  r	  r<  r
  r   r{   r   MODULE_NAMEr   r1   rm  r9   r  r   r:   r   r:  bytesrU   r+  rD  rK  rT  r^  rh  rb  rp  rY   r)   printr7   r7   r7   r8   <module>   s   4  9 J

"

Q


