B
    S\1                 @   s^   d 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 Z	G d	d
 d
Z
dS )zastroid manager: avoid multiple astroid build of a same module when
possible by providing a class responsible to get astroid representation
from various source and using a cache of built modules)
    N)
exceptions)spec)modutils)
transformsc             C   s"   yt | S  tk
r   dS X d S )Nz???)repr	Exception)obj r	   .lib/python3.7/site-packages/astroid/manager.py	safe_repr   s    r   c               @   s   e Zd ZdZdZi Zdd Zedd Zdd Z	d(ddZ
dd Zdd Zdd Zd)ddZdd Zdd Zd*ddZd+ddZd,ddZd d! Zd"d# Zd$d% Zd&d' Zd	S )-AstroidManagerzmthe astroid manager, responsible to build astroid from files
     or modules.

    Use the Borg pattern.
    zastroid loaderc             C   s\   t j| _| jsXi | _i | _g | _d| _d| _t | _	t
 | _| jj| _| jj| _d| _d S )NFd   )r   brain__dict__astroid_cache_mod_file_cache_failed_import_hooksalways_load_extensionsZoptimize_astsetextension_package_whitelistr   ZTransformVisitor
_transformZregister_transformZunregister_transformZmax_inferable_values)selfr	   r	   r
   __init__.   s    


zAstroidManager.__init__c             C   s
   | j d S )Nbuiltins)r   )r   r	   r	   r
   builtins_module?   s    zAstroidManager.builtins_modulec             C   s   | j |S )z8Visit the transforms and apply them to the given *node*.)r   Zvisit)r   Znoder	   r	   r
   visit_transformsC   s    zAstroidManager.visit_transformsNTFc             C   s   yt j|dd}d}W n t jk
r,   Y nX |dkrdydt |}W n tk
rb   |}Y nX || jkr| j| j|kr| j| S |rddlm	} || 
||S |r|r| |S tjd|ddS )	z.given a module name, return the astroid objectT)Zinclude_no_extN.r   )AstroidBuilderz"Unable to build an AST for {path}.)path)r   Zget_source_fileZNoSourceFilejoinZmodpath_from_fileImportErrorr   fileastroid.builderr   Z
file_buildast_from_module_namer   AstroidBuildingError)r   filepathmodnamefallbacksourcer   r	   r	   r
   ast_from_fileG   s(    



zAstroidManager.ast_from_filec             C   s   ddl m} || d|S )Nr   )r    )r"   r   string_build)r   r&   r   r	   r	   r
   _build_stub_moduleb   s    z!AstroidManager._build_stub_modulec             C   s   ddl m} |||S )Nr   )build_namespace_package_module)r"   r-   )r   r&   r   r-   r	   r	   r
   _build_namespace_moduleg   s    z&AstroidManager._build_namespace_modulec                sH   j r
dS t|rdS |d t fddtdt d D S )NTr   c             3   s&   | ]}d   d| jkV  qdS )r   N)r   r   ).0x)partsr   r	   r
   	<genexpr>s   s   z5AstroidManager._can_load_extension.<locals>.<genexpr>   )r   r   Zis_standard_modulesplitanyrangelen)r   r&   r	   )r1   r   r
   _can_load_extensionl   s    

z"AstroidManager._can_load_extensionc       	      C   s  || j kr| j | S |dkr&| |S t }|rDttj| zy.| ||}|jt	j
jkr| |j}|dk	r~|S n|jt	j
jt	j
jfkr|jt	j
jkr| |s| |S yt|}W n6 tk
r } ztjd||jd|W dd}~X Y nX | ||S |jt	j
jkr0tjd||jdn|jt	j
jkrN| ||jS |jdkrhtjd|d| j|j|dd	S  tjk
r } z<x2| jD ](}y||S  tjk
r   Y nX qW |W dd}~X Y nX W dt| X dS )
z.given a module name, return the astroid object__main__Nz&Loading {modname} failed with:
{error})r&   r   z)Unable to load compiled module {modname}.z'Can't find a file for module {modname}.)r&   F)r'   )r   r,   osgetcwdchdirr   dirnamefile_from_module_nametyper   
ModuleTypeZPY_ZIPMODULEzip_import_datalocationZ	C_BUILTINC_EXTENSIONr8   r   Zload_module_from_namer   r   AstroidImportErrorast_from_modulePY_COMPILEDZPY_NAMESPACEr.   submodule_search_locationsr)   r$   r   )	r   r&   context_fileZold_cwdZ
found_specmoduleexehookr	   r	   r
   r#   w   s`    






z#AstroidManager.ast_from_module_namec       
   	   C   s   t d krd S ddlm} || }xdD ]}y||tjj d\}}W n tk
r\   w&Y nX yHt || }|	tjjd}|
|r|d }|||||}	|	S  tk
r   w&Y q&X q&W d S )Nr   )r   )z.zipz.eggr3   r   z	.__init__)	zipimportr"   r   rsplitr:   r   sep
ValueErrorzipimporterreplace
is_packager+   
get_sourcer   )
r   r%   r   ZbuilderZextZeggpathresourceimporterZzmodnamerI   r	   r	   r
   rA      s(    

zAstroidManager.zip_import_datac             C   s   y| j ||f }W nn tk
r   ytj|d|d}W n2 tk
rl } ztjd||d}W d d }~X Y nX || j ||f< Y nX t|tj	r||S )Nr   )rH   z6Failed to import module {modname} with error:
{error}.)r&   error)
r   KeyErrorr   Zfile_info_from_modpathr4   r    r   rD   
isinstancer$   )r   r&   ZcontextfilevaluerJ   r	   r	   r
   r>      s    z$AstroidManager.file_from_module_namec             C   sp   |p|j }|| jkr| j| S y |j}t|r<| ||S W n tk
rR   Y nX ddlm} || 	||S )z3given an imported module, return the astroid objectr   )r   )
__name__r   __file__r   Zis_python_sourcer)   AttributeErrorr"   r   Zmodule_build)r   rI   r&   r%   r   r	   r	   r
   rE      s    



zAstroidManager.ast_from_modulec          
   C   sh   |dkrNy
|j }W n: tk
rL } ztjd|t||d|W dd}~X Y nX | |}||jd S )zget astroid for the given classNz,Unable to get module for class {class_name}.)cls
class_reprr&   r   )
__module__r]   r   r$   r   r#   getattrr[   )r   klassr&   exc
modastroidr	   r	   r
   ast_from_class   s    

zAstroidManager.ast_from_classc       	   
   c   sp  t |drt|ts|j}n|}y
|j}W nn tk
rb } ztjd|t|d|W dd}~X Y n8 t	k
r } ztj
d|t|d|W dd}~X Y nX y
|j}W np tk
r } ztjd|t|d|W dd}~X Y n: t	k
r } ztj
d|t|d|W dd}~X Y nX | |}||krJx@|||D ]}|V  q8W n"x |||D ]}| V  qXW dS )z!infer astroid for the given class	__class__z&Unable to get module for {class_repr}.)r^   r_   NzBUnexpected error while retrieving module for {class_repr}:
{error}z%Unable to get name for {class_repr}:
z@Unexpected error while retrieving name for {class_repr}:
{error})hasattrrY   r?   rf   r`   r]   r   r$   r   r   rD   r[   r#   ZigetattrZinstantiate_class)	r   r   contextrb   r&   rc   namerd   Zinferredr	   r	   r
   infer_ast_from_something   sJ    







z'AstroidManager.infer_ast_from_somethingc             C   s   | j | dS )a}  Registers a hook to resolve imports that cannot be found otherwise.

        `hook` must be a function that accepts a single argument `modname` which
        contains the name of the module or package that could not be imported.
        If `hook` can resolve the import, must return a node of type `astroid.Module`,
        otherwise, it must raise `AstroidBuildingError`.
        N)r   append)r   rL   r	   r	   r
   register_failed_import_hook,  s    z*AstroidManager.register_failed_import_hookc             C   s   | j |j| dS )z<Cache a module if no module with the same name is known yet.N)r   
setdefaultri   )r   rI   r	   r	   r
   cache_module6  s    zAstroidManager.cache_modulec             C   s   ddl }|j  dS )zBootstrap the required AST modules needed for the manager to work

        The bootstrap usually involves building the AST for the builtins
        module, which is required by the rest of astroid to work correctly.
        r   N)Zastroid.raw_buildingZraw_buildingZ_astroid_bootstrapping)r   astroidr	   r	   r
   	bootstrap:  s    zAstroidManager.bootstrapc             C   s   | j   |   dS )z@Clear the underlying cache. Also bootstraps the builtins module.N)r   clearrp   )r   r	   r	   r
   clear_cacheD  s    
zAstroidManager.clear_cache)NTF)N)N)N)N)r[   r`   __qualname____doc__ri   r   r   propertyr   r   r)   r,   r.   r8   r#   rA   r>   rE   re   rj   rl   rn   rp   rr   r	   r	   r	   r
   r   $   s(   

?


,

r   )rt   r:   rM   ro   r   Zastroid.interpreter._importr   r   r   r   r   r	   r	   r	   r
   <module>   s   