
    e+                        d 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
mZ ddlmZ erddlmZ  G d	 d
e
      ZddZy)z8Check for imports on private external modules and names.    )annotations)Path)TYPE_CHECKING)nodes)BaseCheckerutils)HIGH)PyLinterc                  *   e Zd ZdZddiZddZ ej                  d      dd       Z ej                  d      dd       Z	ddZ
edd       Z	 	 	 	 	 	 dd	Z	 	 	 	 	 	 dd
Z	 	 	 	 	 	 ddZ	 	 	 	 	 	 ddZe	 	 	 	 	 	 dd       Ze	 	 	 	 	 	 dd       Zy)PrivateImportCheckerimport-private-nameC2701)zImported private %s (%s)r   zUsed when a private module or object prefixed with _ is imported. PEP8 guidance on Naming Conventions states that public attributes with leading underscores should be considered private.c                L    t        j                  | |       i | _        d| _        y )NF)r   __init__all_used_type_annotationspopulated_annotations)selflinters     B/usr/lib/python3/dist-packages/pylint/extensions/private_import.pyr   zPrivateImportChecker.__init__!   s$    T6* ;=&%*"    c                :   t        j                  |      ry |j                  D cg c]  }|d   	 }}| j                  |      }| j	                  ||      }|r?t        |      dkD  rdnd}dj                  |      }| j                  d|||ft               y y c c}w )Nr      modulesmodule, r   nodeargs
confidence)	r   in_type_checking_blocknames_get_private_imports_get_type_annotation_nameslenjoinadd_messager	   )r   r   namer!   private_namesimported_identifierprivate_name_strings          r   visit_importz!PrivateImportChecker.visit_import(   s    ''-%)ZZ0Ta0011%877mL/2=/AA/E)8"&))M":%)+>?	    1s   Bc                   t        j                  |      ry | j                  ||j                        ry |j                  D cg c]  }|d   	 }}| j                  ||      }|sy | j                  |j                  g      }| j                  ||      }|r| j                  d|d|d   ft               y | j                  |      }|r?t        |      dkD  rdnd}dj                  |      }| j                  d|||ft               y y c c}w )	Nr   r   r   r   r   objectsobjectr   )r   r    same_root_dirmodnamer!   r#   r"   r&   r	   r$   r%   )r   r   nr!   r(   private_module_importsr)   r*   s           r   visit_importfromz%PrivateImportChecker.visit_importfrom9   s(   ''-dDLL1#zz*!1** 77eD "&!:!:DLL>!J!%!@!@("
 "% 6q 9:	   11-@/2=/AA/E)8"&))M":%)+>?	   1 +s   Dc                P    |D cg c]  }| j                  |      s| c}S c c}w )zDReturns the private names from input names by a simple string check.)_name_is_private)r   r!   r'   s      r   r"   z)PrivateImportChecker._get_private_importsc   s#    !&F$*?*?*EFFFs   ##c                t    t        |       xr, | d   dk(  xr" t        |       dk  xs | d   dk7  xs | dd dk7  S )zReturns true if the name exists, starts with `_`, and if len(name) > 4
        it is not a dunder, i.e. it does not begin and end with two underscores.
        r   _   r   N__)boolr$   )r'   s    r   r5   z%PrivateImportChecker._name_is_privateg   sO     J HQ3HTaF47c>FT"#Y$5F	
r   c                    |r=| j                   s1| j                  |j                         | j                         d| _         |D cg c]/  }|| j                  vs|| j                  v r| j                  |   s|1 c}S c c}w )zmRemoves from names any names that are used as type annotations with no other
        illegal usages.
        T)r   _populate_type_annotationsrootr   )r   r   r!   r1   s       r   r#   z/PrivateImportChecker._get_type_annotation_namesr   s     33++DIIK9W9WX)-D& 
666T33366q9 
 	
 
s   4A;c                   |j                   D ]g  }d}g }|j                   |   D ]4  }t        |t        j                        rt        |j                  t        j
                  t        j                  f      r|j                  }t        |t        j
                        r8|j                  |       | j                  |j                  j                  |      }n+t        |t        j                        r|j                  |       t        |t        j                        r| j                  ||       t        |t        j                        s#| j                  ||       7 |S| j                  ||      ||<   j y)zAdds to `all_used_type_annotations` all names ever used as a type annotation
        in the node's (nested) scopes and whether they are only used as annotation.
        N)locals
isinstancer   
AssignNameparent	AnnAssignAssignappend%_populate_type_annotations_annotation
annotationFunctionDef#_populate_type_annotations_functionLocalsDictNodeNGr=   _assignments_call_private_name)r   r   r   r'   private_namename_assignments
usage_nodeassign_parents           r   r=   z/PrivateImportChecker._populate_type_annotations   sI    KK 	XDL  ""kk$/ 
j%*:*:;
%%'FA %/$5$5M!-A(//>'+'Q'Q&--88:S( $M5<<@(//>j%*;*;<<<"$= j%*@*@A33"$=%* ' 778H,W * ;	Xr   c                    |j                   rC|j                   j                  r-|j                   j                  D ]  }| j                  ||        |j                  r| j                  |j                  |       yy)zAdds all names used as type annotation in the arguments and return type of
        the function node into the dict `all_used_type_annotations`.
        N)r   r   rG   returns)r   r   r   rH   s       r   rJ   z8PrivateImportChecker._populate_type_annotations_function   sj     99.."ii33 
:: 9 <<667 r   c                   t        |t        j                        r)|j                  |vrd||j                  <   |j                  S t        |t        j                        r8| j                  |j                  |       | j                  |j                  |      S t        |t        j                        r| j                  |j                  |      S y)zHandles the possibility of an annotation either being a Name, i.e. just type,
        or a Subscript e.g. `Optional[type]` or an Attribute, e.g. `pylint.lint.linter`.
        TN)
rA   r   Namer'   	SubscriptrG   slicevalue	Attributeexpr)r   r   r   s      r   rG   z:PrivateImportChecker._populate_type_annotations_annotation   s     dEJJ'DII=V,V37%dii099dEOO,66

5 ==

5  dEOO, ==		4  r   c                .   t        d | D              ry| D ]|  }d}t        |j                  t        j                        r|j                  j
                  }nkt        |j                  t        j                        r|j                  }n:t        |j                  t        j                        r|j                  j                  }|st        |t        j                  t        j                  f      rwt        |t        j                        r|j
                  }t        |t        j                        s|j                  }t        |t        j                  t        j                  f      rwt        |t        j                        sl|j                  |k(  s} y y)z@Returns True if no assignments involve accessing `private_name`.c              3  6   K   | ]  }|j                      y wN)rW   ).0
assignments     r   	<genexpr>zFPrivateImportChecker._assignments_call_private_name.<locals>.<genexpr>   s     B
:###Bs   FNT)
allrA   rW   r   CallfuncrX   rT   r'   rY   )assignmentsrM   r^   current_attributes       r   rL   z3PrivateImportChecker._assignments_call_private_name   s-   
 BkBB % 	J $***EJJ7$.$4$4$9$9!J,,eoo>$.$4$4!J,,ejj9$.$4$4$9$9!$.%**0MN/<(9(>(>%!"3UZZ@(9(>(>%	 .%**0MN ,ejj9%**l:'	( r   c                    |sy| j                   ry|j                  d      d   }|t        | j                         j                        j
                  j                  v S )zGDoes the node's file's path contain the base name of `import_mod_name`?T.r   )levelsplitr   r>   filerC   parts)r   import_mod_namebase_import_packages      r   r/   z"PrivateImportChecker.same_root_dir   sR    
 ::-33C8;"d499;+;+;&<&C&C&I&IIIr   Nr   r
   returnNone)r   znodes.Importrn   ro   )r   znodes.ImportFromrn   ro   )r!   	list[str]rn   rp   )r'   strrn   r;   )r   nodes.Import | nodes.ImportFromr!   rp   rn   rp   )r   znodes.LocalsDictNodeNGr   dict[str, bool]rn   ro   )r   znodes.FunctionDefr   rs   rn   ro   )r   z5nodes.Attribute | nodes.Subscript | nodes.Name | Noner   rs   rn   z
str | None)rc   z$list[nodes.AnnAssign | nodes.Assign]rM   rq   rn   r;   )r   rr   rk   rq   rn   r;   )__name__
__module____qualname__r'   msgsr   r   only_required_for_messagesr+   r3   r"   staticmethodr5   r#   r=   rJ   rG   rL   r/    r   r   r   r      sT    D 
D+ &U%%&;< =  &U%%&;<' ='RG 
 

3
<E
	
(%X*%XGV%X	%XN%BQ	 C $3 
	8 9IL	 < J-J@CJ	J Jr   r   c                8    | j                  t        |              y r\   )register_checkerr   )r   s    r   registerr}     s    
089r   Nrm   )__doc__
__future__r   pathlibr   typingr   astroidr   pylint.checkersr   r   pylint.interfacesr	   pylint.lint.pylinterr
   r   r}   rz   r   r   <module>r      s8   
 ? "     . "-oJ; oJd:r   