o
    g/                     @   s   d Z ddlZddlZddlZddlZddlmZ ddlmZ dd Zdd Z	d	efd
dZ
G dd dZG dd dZG dd deejZe	ddfddZdS )z{
Visitor doing some postprocessing on the astroid tree.
Try to resolve definitions (namespace) dictionary, relationship...
    N)nodes)utilsc                 C   s   dS )z@Handler used by interfaces to handle suspicious interface nodes.T )_r   r   X/home/ubuntu/cloudmapper/venv/lib/python3.10/site-packages/pylint/pyreverse/inspector.py_iface_hdlr   s   r   c              
   C   sh   t d| d z| |W S  tjjy& } zt | W Y d }~d S d }~w ty3   t  Y d S w )Nzparsing z...)printastroid
exceptionsAstroidBuildingException	Exception	traceback	print_exc)funcmodnameexcr   r   r   _astroid_wrapper$   s   

r   Tc                 c   s    zt j| dd }W n t jjy   Y dS w |s%| | ur%dS t }d}t	|D ]}|t j
u r9d}q/||vrI||rI|| |V  q/|rQt j dS )zEReturn an iterator on interfaces implemented by the given class node.__implements__r   NFT)r	   basesInstancegetattrr
   NotFoundErrorframesetr   unpack_inferUninferableaddInferenceError)nodeheritedhandler_func
implementsfoundmissingifacer   r   r   
interfaces/   s*   


r%   c                   @   s,   e Zd ZdZd
ddZd
ddZdd Zd	S )IdGeneratorMixInz1Mixin adding the ability to generate integer uid.r   c                 C   s
   || _ d S Nid_countselfstart_valuer   r   r   __init__G      
zIdGeneratorMixIn.__init__c                 C   s
   || _ dS )zinit the id counterNr(   r*   r   r   r   init_counterJ   s   
zIdGeneratorMixIn.init_counterc                 C   s   |  j d7  _ | j S )zgenerate a new identifier   r(   r+   r   r   r   generate_idN   s   zIdGeneratorMixIn.generate_idN)r   )__name__
__module____qualname____doc__r-   r/   r2   r   r   r   r   r&   D   s
    

r&   c                   @   s:   e Zd ZdZdddZdd Zdd Zd	d
 Zdd ZdS )Projectz,a project handle a set of modules / packages c                 C   sT   || _ d | _d | _g | _i | _| jj| _| jj| _| jj| _| jj| _| jj	| _	d S r'   )
nameuidpathmoduleslocals__getitem____iter__valueskeysitemsr+   r9   r   r   r   r-   W   s   



zProject.__init__c                 C   s   || j |j< | j| d S r'   )r=   r9   r<   appendr+   r   r   r   r   
add_modulec   s   zProject.add_modulec                 C   s
   | j | S r'   )r=   rC   r   r   r   
get_moduleg   r.   zProject.get_modulec                 C   s   | j S r'   )r<   r1   r   r   r   get_childrenj   s   zProject.get_childrenc                 C   s$   d| j dt|  dt| j dS )Nz	<Project z at z (z
 modules)>)r9   idlenr<   r1   r   r   r   __repr__m   s   $zProject.__repr__N)r8   )	r3   r4   r5   r6   r-   rF   rG   rH   rK   r   r   r   r   r7   T   s    
r7   c                   @   s   e Zd ZdZdddZdeddfd	d
ZdejddfddZ	dej
ddfddZdejddfddZeZe	ZeZeZdejddfddZedd ZdejddfddZdejddfddZdd Zdd ZdS )Linkera  Walk on the project tree and resolve relationships.

    According to options the following attributes may be
    added to visited nodes:

    * uid,
      a unique identifier for the node (on astroid.Project, astroid.Module,
      astroid.Class and astroid.locals_type). Only if the linker
      has been instantiated with tag=True parameter (False by default).

    * Function
      a mapping from locals names to their bounded value, which may be a
      constant like a string or an integer, or an astroid node
      (on astroid.Module, astroid.Class and astroid.Function).

    * instance_attrs_type
      as locals_type but for klass member attributes (only on astroid.Class)

    * implements,
      list of implemented interface _objects_ (only on astroid.Class nodes)
    r   Fc                 C   s,   t |  tj|  || _|| _|| _d S r'   )r&   r-   r   LocalsVisitorinherited_interfacestagproject)r+   rP   rN   rO   r   r   r   r-      s
   

zLinker.__init__r   returnNc                 C   s*   | j r|  |_|jD ]}| | qdS )zavisit a pyreverse.utils.Project node

        * optionally tag the node with a unique id
        N)rO   r2   r:   r<   visit)r+   r   moduler   r   r   visit_project   s
   

zLinker.visit_projectc                 C   s8   t |drdS tt|_g |_| jr|  |_dS dS )zvisit an astroid.Module node

        * set the locals_type mapping
        * set the depends mapping
        * optionally tag the node with a unique id
        locals_typeN)	hasattrcollectionsdefaultdictlistrU   dependsrO   r2   r:   rE   r   r   r   visit_module   s   
zLinker.visit_modulec                 C   s   t |drdS tt|_| jr|  |_|jddD ]}t	|dg }|
| ||_qtt|_|j D ]}|D ]}t|tjsI| || q;q7ztt|| j|_W dS  tjye   g |_Y dS w )zvisit an astroid.Class node

        * set the locals_type and instance_attrs_type mappings
        * set the implements list and build it
        * optionally tag the node with a unique id
        rU   NF)recursspecializations)rV   rW   rX   rY   rU   rO   r2   r:   	ancestorsr   rD   r]   instance_attrs_typeinstance_attrsr@   
isinstancer   Unknownhandle_assignattr_typer%   rN   r!   r	   r   )r+   r   baseobjr]   assignattrs
assignattrr   r   r   visit_classdef   s*   


zLinker.visit_classdefc                 C   s2   t |drdS tt|_| jr|  |_dS dS )zvisit an astroid.Function node

        * set the locals_type mapping
        * optionally tag the node with a unique id
        rU   N)rV   rW   rX   rY   rU   rO   r2   r:   rE   r   r   r   visit_functiondef   s   
zLinker.visit_functiondefc                 C   s   t |drdS d|_|j| v r| }n| }t |ds<t|tjr+| | nt|tj	r7| 
| n| | |j|j }tt|t|B |j|j< dS )zEvisit an astroid.AssignName node

        handle locals_type
        _handledNTrU   )rV   ri   r9   r   rootra   r   ClassDefrg   FunctionDefrh   r[   rU   rY   r   r   
infer_node)r+   r   r   currentr   r   r   visit_assignname   s   



"zLinker.visit_assignnamec                 C   s.   t |j| j }t|t| B |j| j< dS )zNhandle an astroid.assignattr node

        handle instance_attrs_type
        N)r   r_   attrnamerY   r   rm   )r   parentrn   r   r   r   rc      s   zLinker.handle_assignattr_typec                 C   s>   |  j}|jD ]}tj|d |}| ||d | qdS )zJvisit an astroid.Import node

        resolve module dependencies
        r   N)rj   filenamesr	   modutilsis_relative_imported_module)r+   r   context_filer9   relativer   r   r   visit_import  s
   

zLinker.visit_importc              	   C   s   |j }| j}|durtj||}nd}|jD ]7}|d dkr"q| d|d  }|ddkrEz	tj||}W n	 t	yD   Y qw ||krP| 
||| qdS )zNvisit an astroid.ImportFrom node

        resolve module dependencies
        NFr   *.)r   rj   rr   r	   rt   ru   rs   findget_module_partImportErrorrv   )r+   r   basenamerw   rx   r9   fullnamer   r   r   visit_importfrom  s&   

zLinker.visit_importfromc                 C   s4   t j| jj}||krdS tj||frdS dS )z9return true if the module should be added to dependenciesr   r0   )osr;   dirnamerP   r	   rt   is_standard_module)r+   context_namemod_pathpackage_dirr   r   r   compute_module#  s   zLinker.compute_modulec                 C   st   |  }|j}|rd|ddd  d| }| ||r6t|ds(g |_|j}||vr8|| dS dS dS )z7Notify an imported module, used to analyze dependenciesr{   Nr|   rZ   )rj   r9   joinsplitr   rV   rZ   rD   )r+   r   r   rx   rS   r   	mod_pathsr   r   r   rv   ,  s   "
zLinker._imported_module)r   F)r3   r4   r5   r6   r-   r7   rT   r   Moduler[   rk   rg   rl   rh   link_projectlink_module
link_classlink_function
AssignNamero   staticmethodrc   Importry   
ImportFromr   r   rv   r   r   r   r   rL   q   s$    





	rL   zno name)CVSc           
      C   s   t j }t|}| D ]j}tj|st j|	d}ntj
|r+tj|d}n|}||j|}|du r8q|jp=|j|_|| |j}	|jru|ddkrut jtj|j|D ]}||j|}|du sn|j|	kroq]|| q]q|S )z0return a Project from a list of files or modulesr{   z__init__.pyNr-   r|   )r	   managerAstroidManagerr7   r   r;   existsrt   file_from_modpathr   isdirr   ast_from_filerr   rF   r9   packager}   get_module_filesr   )
filesfunc_wrapperproject_name
black_listastroid_managerrP   	somethingfpathast	base_namer   r   r   project_from_files;  s0   

r   )r6   rW   r   r   r	   r   pylint.pyreverser   r   r   r%   r&   r7   rM   rL   r   r   r   r   r   <module>   s     L