o
    b@0                     @   s   d Z ddlm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lm	Z	 ddlm
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eejZG dd d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...
    )print_functionN)bases)
exceptions)manager)modutils)node_classes)utilsc                 C   s   dS )z@Handler used by interfaces to handle suspicious interface nodes.T )_r	   r	   Y/var/www/secure340b-portal/env/lib/python3.10/site-packages/pylint/pyreverse/inspector.py_iface_hdlr   s   r   c              
   C   st   t d|  z| |W S  tjy# } zt | W Y d }~d S d }~w ty9 } zt  W Y d }~d S d }~ww )Nzparsing %s...)printr   ZAstroidBuildingException	Exception	traceback	print_exc)funcmodnameexcr	   r	   r   _astroid_wrapper$   s   
r   Tc                 c   s    zt | dd }W n tjy   Y dS w |s#| | ur#dS t }d}t|D ]}|t	j
u r7d}q-||vrG||rG|| |V  q-|rNt dS )zEReturn an iterator on interfaces implemented by the given class node.Z__implements__r   NFT)r   Instancegetattrr   ZNotFoundErrorframesetr   Zunpack_inferastroidZUninferableaddInferenceError)nodeZheritedZhandler_func
implementsfoundmissingZ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Zid_countselfZstart_valuer	   r	   r   __init__G      
zIdGeneratorMixIn.__init__c                 C   s
   || _ dS )zinit the id counter
        Nr#   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_idO   s   zIdGeneratorMixIn.generate_idN)r   )__name__
__module____qualname____doc__r&   r(   r+   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d Z	eZ
eZeZe	Zdd Zedd Zdd Z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%   r4   r2   r3   r	   r	   r   r&   m   s
   

zLinker.__init__c                 C   s*   | j r|  |_|jD ]}| | qdS )zbvisit a pyreverse.utils.Project node

         * optionally tag the node with a unique id
        N)r3   r+   uidmodulesvisit)r%   r   moduler	   r	   r   visit_projectw   s
   

zLinker.visit_projectc                 C   s,   | j r|  |_| D ]}| | qdS )z[visit an astroid.Package node

         * optionally tag the node with a unique id
        N)r3   r+   r5   valuesr7   )r%   r   Zsubelmtr	   r	   r   visit_package   s
   
zLinker.visit_packagec                 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listr<   dependsr3   r+   r5   r%   r   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 ]}| || q;q7ztt|| j|_W dS  tjy_   d|_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
        r<   NF)Zrecursspecializationsr	   )r=   r>   r?   r@   r<   r3   r+   r5   Z	ancestorsr   appendrD   instance_attrs_typeZinstance_attrsr:   handle_assignattr_typer    r2   r   r   r   )r%   r   ZbaseobjrD   ZassignattrsZ
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
        r<   N)r=   r>   r?   r@   r<   r3   r+   r5   rB   r	   r	   r   visit_functiondef   s   
zLinker.visit_functiondefc                 C   s   t |drdS d|_|j| v r| }n| }z=t |ds=t|tjr,| | nt|tj	r8| 
| n| | |j|j }t| }tt||B |j|j< W dS  tjyb   Y dS w )zEvisit an astroid.AssignName node

        handle locals_type
        _handledNTr<   )r=   rJ   namer   root
isinstancer   ClassDefrH   FunctionDefrI   rC   r<   r   inferr@   r   )r%   r   r   currentr:   r	   r	   r   visit_assignname   s&   



zLinker.visit_assignnamec                 C   sN   zt |  }t |j| j }t||B |j| j< W dS  tjy&   Y dS w )zNhandle an astroid.assignattr node

        handle instance_attrs_type
        N)r   rP   rF   attrnamer@   r   r   )r   parentr:   rQ   r	   r	   r   rG      s   zLinker.handle_assignattr_typec                 C   s<   |  j}|jD ]}t|d |}| ||d | qdS )zJvisit an astroid.Import node

        resolve module dependencies
        r   N)rL   filenamesr   is_relative_imported_module)r%   r   context_filerK   relativer	   r	   r   visit_import   s
   

zLinker.visit_importc              	   C   s   |j }| j}|durt||}nd}|jD ]5}|d dkr!qd||d f }|ddkrBzt||}W n	 tyA   Y qw ||krM| 	||| qdS )zNvisit an astroid.ImportFrom node

        resolve module dependencies
        NFr   *%s.%s.)
r   rL   rU   r   rW   rV   findZget_module_partImportErrorrX   )r%   r   basenamerY   rZ   rK   fullnamer	   r	   r   visit_importfrom   s&   

zLinker.visit_importfromc                 C   s2   t j| jj}||krdS t||frdS dS )z9return true if the module should be added to dependenciesr   r)   )ospathdirnamer4   r   Zis_standard_module)r%   context_namemod_pathpackage_dirr	   r	   r   compute_module  s   zLinker.compute_modulec                 C   sr   |  }|j}|rdd|ddd |f }| ||r5t|ds'g |_|j}||vr7|| dS dS dS )z7Notify an imported module, used to analyze dependenciesr]   r^   Nr_   rA   )rL   rK   joinsplitrk   r=   rA   rE   )r%   r   ri   rZ   r8   rh   Z	mod_pathsr	   r	   r   rX   "  s    
zLinker._imported_moduleN)r   F)r,   r-   r.   r/   r&   r9   r;   rC   rH   rI   Zlink_projectZlink_moduleZ
link_classZlink_functionrR   staticmethodrG   r[   rd   rk   rX   r	   r	   r	   r   r0   V   s&    



"

	r0   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   sN   || _ d | _g | _i | _| jj| _| jj| _| jj| _| jj| _| jj| _d S r"   )	rK   rf   r6   locals__getitem____iter__r:   keysitemsr%   rK   r	   r	   r   r&   4  s   



zProject.__init__c                 C   s   || j |j< | j| d S r"   )rq   rK   r6   rE   rB   r	   r	   r   
add_module?  s   zProject.add_modulec                 C   s
   | j | S r"   )rq   rv   r	   r	   r   
get_moduleC  r'   zProject.get_modulec                 C   s   | j S r"   )r6   r*   r	   r	   r   get_childrenF  s   zProject.get_childrenc                 C   s   d| j t| t| jf S )Nz<Project %r at %s (%s modules)>)rK   idlenr6   r*   r	   r	   r   __repr__I  s
   zProject.__repr__N)rp   )	r,   r-   r.   r/   r&   rw   rx   ry   r|   r	   r	   r	   r   ro   1  s    
ro   zno name)CVSc           
      C   s   t  }t|}| D ]h}tj|st|d}ntj	|r)tj
|d}n|}||j|}|du r6q
|jp;|j|_|| |j}	|jrr|ddkrrttj|j|D ]}||j|}|du sk|j|	krlqZ|| qZq
|S )z0return a Project from a list of files or modulesr^   z__init__.pyNr&   r_   )r   ZAstroidManagerro   re   rf   existsr   Zfile_from_modpathrm   isdirrl   Zast_from_filerU   rw   rK   packager`   Zget_module_filesrg   )
filesfunc_wrapperproject_nameZ
black_listZastroid_managerr4   Z	somethingZfpathast	base_namer	   r	   r   project_from_filesQ  s0   
r   )r/   
__future__r   r>   re   r   r   r   r   r   r   r   Zpylint.pyreverser   r   r   r    r!   r1   r0   ro   r   r	   r	   r	   r   <module>   s*   	
 \!