
    e4                       d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	m
Z
mZ ddlZddlmZ ddlmZ ddlmZ e
e
egej&                  f   eegeej&                     f   Z	 d	 	 	 	 	 	 	 dd
Z G d d      Z G d d      Z G d deej2                        Z G d de      Z G d de      Z G d de      Z G d de      Zedej>                  d	f	 	 	 	 	 	 	 	 	 	 	 ddZ y)z|Visitor doing some post-processing on the astroid tree.

Try to resolve definitions (namespace) dictionary, relationship...
    )annotationsN)ABCabstractmethod)CallableOptional)nodes)	constants)utilsFc                    |rt        d| d       	  | |      S # t        j                  j                  $ r}t        |       Y d }~y d }~wt        $ r t        j                          Y y w xY w)Nzparsing z...)printastroid
exceptionsAstroidBuildingException	Exception	traceback	print_exc)funcmodnameverboseexcs       </usr/lib/python3/dist-packages/pylint/pyreverse/inspector.py_astroid_wrapperr      sj    
 	%&G}66 c

   s    A+A A+*A+c                  ,    e Zd ZdZdddZdddZddZy)	IdGeneratorMixInz1Mixin adding the ability to generate integer uid.c                    || _         y Nid_countselfstart_values     r   __init__zIdGeneratorMixIn.__init__0   s	    #    c                    || _         y)zInit the id counter.Nr   r   s     r   init_counterzIdGeneratorMixIn.init_counter3   s	    #r#   c                D    | xj                   dz  c_         | j                   S )zGenerate a new identifier.   r   r    s    r   generate_idzIdGeneratorMixIn.generate_id7   s    }}r#   N)r   )r!   intreturnNone)r+   r*   )__name__
__module____qualname____doc__r"   r%   r)    r#   r   r   r   -   s    ;$$r#   r   c                  :    e Zd ZdZdd	dZd
dZddZddZddZy)Projectz-A project handle a set of modules / packages.c                X   || _         d | _        d| _        g | _        i | _        | j                  j
                  | _        | j                  j                  | _        | j                  j                  | _        | j                  j                  | _        | j                  j                  | _	        y )N )
nameuidpathmoduleslocals__getitem____iter__valueskeysitemsr    r6   s     r   r"   zProject.__init__@   s{    	#	+-/1;;22,,kk((KK$$	[[&&
r#   c                l    || j                   |j                  <   | j                  j                  |       y r   )r:   r6   r9   appendr    nodes     r   
add_modulezProject.add_moduleL   s&    !%DIID!r#   c                     | j                   |   S r   )r:   r@   s     r   
get_modulezProject.get_moduleP   s    {{4  r#   c                    | j                   S r   )r9   r(   s    r   get_childrenzProject.get_childrenS   s    ||r#   c                f    d| j                   dt        |        dt        | j                         dS )Nz	<Project z at z (z
 modules)>)r6   idlenr9   r(   s    r   __repr__zProject.__repr__V   s/    499-tBtH:RDLL8I7J*UUr#   N)r5   )r6   strrD   nodes.Moduler+   r,   )r6   rN   r+   rP   )r+   zlist[nodes.Module])r+   rN   )	r-   r.   r/   r0   r"   rE   rG   rI   rM   r1   r#   r   r3   r3   =   s    7
'"!Vr#   r3   c                      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
dd       Zdd	Zdd
ZddZ	 	 	 	 	 	 	 	 ddZy)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)

    * associations_type
      as instance_attrs_type but for association relationships

    * aggregations_type
      as instance_attrs_type but for aggregations relationships
    c                    t         j                  |        t        j                  j                  |        || _        || _        t               | _        | j                  j                  t                      y r   )
r   r"   r
   LocalsVisitortagprojectAggregationsHandlerassociations_handlerset_nextOtherAssociationsHandler)r    rV   rU   s      r   r"   zLinker.__init__t   sU    !!$'$$T*$7$9!!!**+C+EFr#   c                    | j                   r| j                         |_        |j                  D ]  }| j	                  |        y)zbVisit a pyreverse.utils.Project node.

        * optionally tag the node with a unique id
        N)rU   r)   r7   r9   visit)r    rD   modules      r   visit_projectzLinker.visit_project~   s:    
 88'')DHll 	FJJv	r#   c                    t        |d      ryt        j                  t              |_        g |_        g |_        | j                  r| j                         |_	        yy)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`   dependstype_dependsrU   r)   r7   rC   s     r   visit_modulezLinker.visit_module   sO     4'&224888'')DH r#   c                   t        |d      ryt        j                  t              |_        | j
                  r| j                         |_        |j                  d      D ]'  }t        |dg       }|j                  |       ||_        ) t        j                  t              |_        t        j                  t              |_        t        j                  t              |_        t        |j                   j#                               D ]R  }|D ]K  }t%        |t&        j(                        r| j*                  j-                  ||       | j/                  ||       M T y)zVisit an astroid.Class node.

        * set the locals_type and instance_attrs_type mappings
        * optionally tag the node with a unique id
        r`   NF)recursspecializations)ra   rb   rc   rd   r`   rU   r)   r7   	ancestorsgetattrrB   rj   instance_attrs_typeaggregations_typeassociations_typetupleinstance_attrsr=   
isinstancer   UnknownrX   handlehandle_assignattr_type)r    rD   baseobjrj   assignattrs
assignattrs         r   visit_classdefzLinker.visit_classdef   s    4'&224888'')DH~~U~3 	6G%g/@"EO""4(&5G#	6
 $/#:#:4#@ !,!8!8!>!,!8!8!> !4!4!;!;!=> 	BK) B
!*emm<--44ZF//
DAB	Br#   c                    t        |d      ryt        j                  t              |_        | j
                  r| j                         |_        yy)zVisit an astroid.Function node.

        * set the locals_type mapping
        * optionally tag the node with a unique id
        r`   N)ra   rb   rc   rd   r`   rU   r)   r7   rC   s     r   visit_functiondefzLinker.visit_functiondef   s@     4'&224888'')DH r#   c                D   t        |d      ryd|_        |j                  |j                         v r|j                         }n|j	                         }t        |d      sit        |t        j                        r| j                  |       n=t        |t        j                        r| j                  |       n| j                  |       |j                  |j                     }t        t        |      t        j                   |      z        |j                  |j                  <   y)zFVisit an astroid.AssignName node.

        handle locals_type
        _handledNTr`   )ra   r}   r6   framerootrr   r   ClassDefry   FunctionDefr{   rg   r`   rd   setr
   
infer_node)r    rD   r~   currents       r   visit_assignnamezLinker.visit_assignname   s     4$99

$JJLE IIKEum, %0##E*E5#4#45&&u-!!%(##DII.'+CL5;K;KD;Q,Q'R$))$r#   c                    t        |j                  | j                           }t        |t	        j
                  |       z        |j                  | j                  <   y)zOHandle an astroid.assignattr node.

        handle instance_attrs_type
        N)r   rm   attrnamerd   r
   r   )rD   parentr   s      r   ru   zLinker.handle_assignattr_type   sI     f00?@48e&&t,,5
""4==1r#   c                    |j                         j                  }|j                  D ];  }t        j                  j                  |d   |      }| j                  ||d   |       = y)zKVisit an astroid.Import node.

        resolve module dependencies
        r   N)r   filenamesr   modutilsis_relative_imported_module)r    rD   context_filer6   relatives        r   visit_importzLinker.visit_import   sZ    
 yy{''JJ 	;D''33DG\JH!!$Q:	;r#   c                   |j                   }|j                         j                  }|!t        j                  j                  ||      }nd}|j                  D ]c  }|d   dk(  r| d|d    }|j                  d      dkD  r!	 t        j                  j                  ||      }||k7  sQ| j                  |||       e y# t        $ r Y rw xY w)zOVisit an astroid.ImportFrom node.

        resolve module dependencies
        NFr   *.)r   r   r   r   r   r   r   findget_module_partImportErrorr   )r    rD   basenamer   r   r6   fullnames          r   visit_importfromzLinker.visit_importfrom   s    
 <<yy{''#''33HlKHHJJ 	@DAw#~"1T!WI.H}}S!B&&//??,WH 8#%%dHh?	@ # s    B??	C
Cc                    t         j                  j                  | j                  j                        }||k(  ryt        j
                  j                  ||f      S )z,Should the module be added to dependencies ?F)osr8   dirnamerV   r   r   module_in_path)r    context_namemod_pathpackage_dirs       r   compute_modulezLinker.compute_module  sF    ggoodll&7&788# ..x+HHr#   c                    |j                         }|j                  }|r(dj                  |j                  d      dd        d| }| j	                  ||      r6t        |d      sg |_        |j                  }||vr|j                  |       yyy)z8Notify an imported module, used to analyze dependencies.r   Nr   re   )r   r6   joinsplitr   ra   re   rB   )r    rD   r   r   r]   r   	mod_pathss          r   r   zLinker._imported_module  s     {{((<#5#5c#:3B#?@A8*MH|X669-!#Iy(  * ) 7r#   NF)rV   r3   rU   boolr+   r,   )rD   r3   r+   r,   rO   )rD   nodes.ClassDefr+   r,   )rD   znodes.FunctionDefr+   r,   )rD   znodes.AssignNamer+   r,   rD   znodes.AssignAttrr   r   r+   r,   )rD   znodes.Importr+   r,   )rD   znodes.ImportFromr+   r,   )r   rN   r   rN   r+   r   )rD   znodes.Import | nodes.ImportFromr   rN   r   r   r+   r,   )r-   r.   r/   r0   r"   r^   rg   ry   r{   r   staticmethodru   r   r   r   r   r1   r#   r   rR   rR   Z   sr    2G*B4
*S< 
 
;@0I+3+?B+NR+	+r#   rR   c                  8    e Zd Ze	 	 	 	 dd       Zedd       Zy)AssociationHandlerInterfacec                     y r   r1   r    handlers     r   rY   z$AssociationHandlerInterface.set_next#  s     	r#   c                     y r   r1   r    rD   r   s      r   rt   z"AssociationHandlerInterface.handle)  s    r#   Nr   r   r+   r   r   )r-   r.   r/   r   rY   rt   r1   r#   r   r   r   "  s8    2	$ 
  r#   r   c                  >    e Zd ZU dZded<   	 	 	 	 ddZedd       Zy)	AbstractAssociationHandlera  
    Chain of Responsibility for handling types of association, useful
    to expand in the future if we want to add more distinct associations.

    Every link of the chain checks if it's a certain type of association.
    If no association is found it's set as a generic association in `associations_type`.

    The default chaining behavior is implemented inside the base handler
    class.
    r   _next_handlerc                    || _         |S r   )r   r   s     r   rY   z#AbstractAssociationHandler.set_next<  s     %r#   c                V    | j                   r| j                   j                  ||       y y r   )r   rt   r   s      r   rt   z!AbstractAssociationHandler.handleB  s&    %%dF3 r#   Nr   r   )r-   r.   r/   r0   __annotations__rY   r   rt   r1   r#   r   r   r   .  s8    	 /.2	$ 4 4r#   r   c                        e Zd Zd fdZ xZS )rW   c                   t        |j                  t        j                  t        j                  f      rt        |j                  j
                  t        j                  j                        r[t        |j                  |j                           }t        |t        j                  |      z        |j                  |j                  <   y t        | A  ||       y r   )rr   r   r   	AnnAssignAssignvaluer   node_classesNamer   rn   r   rd   r
   r   superrt   )r    rD   r   r   	__class__s       r   rt   zAggregationsHandler.handleI  s    dkkEOOU\\#BC
KKw3388I
 &224==ABG6:%**4007F$$T]]3 GN4(r#   r   )r-   r.   r/   rt   __classcell__)r   s   @r   rW   rW   H  s    	) 	)r#   rW   c                      e Zd ZddZy)rZ   c                    t        |j                  |j                           }t        |t	        j
                  |      z        |j                  |j                  <   y r   )r   ro   r   rd   r
   r   )r    rD   r   r   s       r   rt   zOtherAssociationsHandler.handleV  sE    f..t}}=>26wAQAQRVAW7W2X  /r#   Nr   )r-   r.   r/   rt   r1   r#   r   rZ   rZ   U  s    Yr#   rZ   zno namec                `   t         j                  }t        |      }| D ]  }t        j                  j                  |      s/t         j                  j                  |j                  d            }nBt        j                  j                  |      r!t        j                  j                  |d      }n|} ||j                  ||      }	|	|j                  xs |	j                  |_        |j                  |	       |	j                  }
|	j                  s|j!                  d      dk(  s
t         j                  j#                  t        j                  j%                  |	j                        |      D ]9  } ||j                  ||      }	|	|	j                  |
k(  r)|j                  |	       ;  |S )z1Return a Project from a list of files or modules.r   z__init__.pyr"   r   )r   MANAGERr3   r   r8   existsr   file_from_modpathr   isdirr   ast_from_filer   rE   r6   packager   get_module_filesr   )filesfunc_wrapperproject_name
black_listr   astroid_managerrV   	somethingfpathast	base_names              r   project_from_filesr   [  sP    ooOl#G (	ww~~i($$66ys7KLEWW]]9%GGLLM:EE?88%I;||/sxx3HH	;;9>>*5; ))::): ( #?#@#@%Q;#((i"7""3'(!(. Nr#   r   )r   zCallable[[str], nodes.Module]r   rN   r   r   r+   znodes.Module | None)r   z	list[str]r   _WrapperFuncTr   rN   r   ztuple[str, ...]r   r   r+   r3   )!r0   
__future__r   rb   r   r   abcr   r   typingr   r   r   r   pylintr	   pylint.pyreverser
   rN   Moduler   r   r   r   r3   rT   rR   r   r   rW   rZ   DEFAULT_IGNORE_LISTr   r1   r#   r   <module>r      s>  

 #  	  # %    "seU\\!"C.0FF 
'  	   V V:E+u22 E+P	# 	4!< 44
)4 
)Y9 Y #3!"+"?"?""" "  	"
 " "r#   