B
    :Ra\L@  ã               @   s(  d dl Z d dlZd dlZd dlZd dlZd dlm  mZ d dl	m  m
  mZ d dlmZmZmZmZmZm
Z
 d dlmZ d dlmZmZmZ yd dlZW n ek
rº   d dlZY nX G dd„ deƒZG dd„ deƒZG d	d
„ d
eƒZdd„ ZG dd„ deƒZ G dd„ deƒZ!dd„ Z"dd„ Z#dS )é    N)Ú
exceptionsÚ
taskhandleÚprefsÚhistoryÚpycoreÚutils)ÚModuleNotFoundError)ÚFileÚFolderÚ_ResourceMatcherc               @   sâ   e Zd Zdd„ Zdd„ Zd/dd„Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
e ¡ fdd„Zd0dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd1d!d"„Zd#d$„ Zd%d&„ Zd'd(„ Zeejd)d*„ ƒƒZeejd+d,„ ƒƒZd-d.„ ZdZdS )2Ú_Projectc             C   s*   g | _ || _t ¡ | _t| ƒ| _g | _d S )N)Ú	observersÚ
fscommandsr   ZPrefsÚ
_DataFilesÚ
data_filesÚ_custom_source_folders)Úselfr   © r   ú0lib/python3.7/site-packages/rope/base/project.pyÚ__init__   s
    

z_Project.__init__c             C   sd   |   |¡}tj |¡s&t d| ¡‚n:tj |¡r<t| |ƒS tj |¡rRt	| |ƒS t d| ¡‚dS )a§  Get a resource in a project.

        `resource_name` is the path of a resource in a project.  It is
        the path of a resource relative to project root.  Project root
        folder address is an empty string.  If the resource does not
        exist a `exceptions.ResourceNotFound` exception would be
        raised.  Use `get_file()` and `get_folder()` when you need to
        get nonexistent `Resource`\s.

        zResource <%s> does not existzUnknown resource N)
Ú_get_resource_pathÚosÚpathÚexistsr   ÚResourceNotFoundErrorÚisfiler	   Úisdirr
   )r   Úresource_namer   r   r   r   Úget_resource   s    


z_Project.get_resourceNc             C   sD   | j  |¡}|dk	r|S |  ||¡}|dkr8td| ƒ‚| j  |¡S )z-Returns a `PyObject` if the module was found.NzModule %s not found)r   Úbuiltin_moduleÚfind_moduler   Úresource_to_pyobject)r   ÚnameÚfolderZpymodÚmoduler   r   r   Ú
get_module3   s    z_Project.get_modulec          	   C   sX   g }xN| j  dg ¡tj D ]6}ytƒ  |¡}| |¡ W q tjk
rN   Y qX qW |S )NZpython_path)	r   ÚgetÚsysr   Úget_no_projectr   Úappendr   r   )r   ÚresultÚsrcZ
src_folderr   r   r   Úget_python_path_folders>   s    
z _Project.get_python_path_foldersc             C   s0   | j dkrg S t| jƒ}| | j | j ¡¡ |S )zReturns project source foldersN)ÚrootÚlistr   Úextendr   Z_find_source_folders)r   r*   r   r   r   Úget_source_foldersM   s
    

z_Project.get_source_foldersc             C   s"   xt | jƒD ]}| |¡ qW dS )z»Validate files and folders contained in this folder

        It validates all of the files and folders contained in this
        folder if some observers are interested in them.

        N)r.   r   Úvalidate)r   r#   Úobserverr   r   r   r1   U   s    z_Project.validatec             C   s   | j  |¡ dS )zORegister a `ResourceObserver`

        See `FilteredResourceObserver`.
        N)r   r)   )r   r2   r   r   r   Úadd_observer_   s    z_Project.add_observerc             C   s   || j kr| j  |¡ dS )z&Remove a registered `ResourceObserver`N)r   Úremove)r   r2   r   r   r   Úremove_observerf   s    
z_Project.remove_observerc             C   s   | j j||d dS )z’Apply the changes in a `ChangeSet`

        Most of the time you call this function for committing the
        changes for a refactoring.
        )Útask_handleN)r   Údo)r   Zchangesr6   r   r   r   r7   k   s    z_Project.doFc             C   s   | j  ||¡S )N)r   r!   )r   ÚresourceZforce_errorsr   r   r   Úget_pymodules   s    z_Project.get_pymodulec             C   s   | j S )N)r   )r   r   r   r   Ú
get_pycorev   s    z_Project.get_pycorec             C   s
   t | |ƒS )z+Get the file with `path` (it may not exist))r	   )r   r   r   r   r   Úget_filey   s    z_Project.get_filec             C   s
   t | |ƒS )z-Get the folder with `path` (it may not exist))r
   )r   r   r   r   r   Ú
get_folder}   s    z_Project.get_folderc             C   s   | j S )N)r   )r   r   r   r   Ú	get_prefs   s    z_Project.get_prefsc             C   s.   |   |||¡}|d kr"td| ƒ‚| j |¡S )NzModule %s not found)Úfind_relative_moduler   r   r!   )r   r"   r#   Úlevelr$   r   r   r   Úget_relative_module„   s    z_Project.get_relative_modulec             C   sr   x&|   ¡ D ]}t||ƒ}|dk	r
|S q
W x&|  ¡ D ]}t||ƒ}|dk	r2|S q2W |dk	rnt||ƒ}|dk	rn|S dS )zjReturns a resource corresponding to the given module

        returns None if it can not be found
        N)r0   Ú_find_module_in_folderr,   )r   Úmodnamer#   r+   r$   r   r   r   r    Š   s    


z_Project.find_modulec             C   s6   xt |d ƒD ]
}|j}qW |dkr(|S t||ƒS d S )Né   Ú )ÚrangeÚparentrA   )r   rB   r#   r?   Úir   r   r   r>      s
    
z_Project.find_relative_modulec             C   s   dS )NFr   )r   r8   r   r   r   Ú
is_ignored¥   s    z_Project.is_ignoredc             C   s   d S )Nr   )r   r"   r   r   r   r   ¨   s    z_Project._get_resource_pathc             C   s
   t  | ¡S )N)r   ZHistory)r   r   r   r   r   «   s    z_Project.historyc             C   s
   t  | ¡S )N)r   ZPyCore)r   r   r   r   r   °   s    z_Project.pycorec             C   s   t jdtdd d S )NzCannot close a NoProjecté   )Ú
stacklevel)ÚwarningsÚwarnÚDeprecationWarning)r   r   r   r   Úcloseµ   s    z_Project.close)N)F)N)Ú__name__Ú
__module__Ú__qualname__r   r   r%   r,   r0   r1   r3   r5   r   ZNullTaskHandler7   r9   r:   r;   r<   r=   r@   r    r>   rH   r   Úpropertyr   Zsaveitr   r   rN   Ú
ropefolderr   r   r   r   r      s2   



r   c                   sÆ   e Zd ZdZd(‡ fdd„	Ze d¡dd„ ƒZd	d
„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zed!d"„ ƒZd)‡ fd#d$„	Zed%d&„ ƒZed'd&„ ƒZ‡  ZS )*ÚProjectz&A Project containing files and foldersNú.ropeprojectc                sÌ   |dkrt |ƒ d¡}|| _|| _tj | j¡s>t | j¡ ntj | j¡sVt	 
d¡‚|dkrntjj | j¡}tt| ƒ |¡ tƒ | _t| ƒ| _| j d| jj¡ |dk	r¶|g| jd< |  |¡ |  ¡  dS )a&  A rope project

        :parameters:
            - `projectroot`: The address of the root folder of the project
            - `fscommands`: Implements the file system operations used
              by rope; have a look at `rope.base.fscommands`
            - `ropefolder`: The name of the folder in which rope stores
              project configurations and data.  Pass `None` for not using
              such a folder at all.
            - `prefs`: Specify project preferences.  These values
              overwrite config file preferences.

        ú/z/\z*Project root exists and is not a directoryNZignored_resources)Ú	_realpathÚrstripÚ_addressÚ_ropefolder_namer   r   r   Úmkdirr   r   Z	RopeErrorÚropeÚbaser   Zcreate_fscommandsÚsuperrT   r   r   ÚignoredÚ_FileListCacherÚ	file_listr   Zadd_callbackZset_patternsÚ_init_prefsÚ_init_source_folders)r   Zprojectrootr   rS   r   )Ú	__class__r   r   r   ¿   s$    


zProject.__init__z)Delete once deprecated functions are gonec             C   s2   x,| j  dg ¡D ]}|  |¡}| j |¡ qW d S )NZsource_folders)r   r&   r   r   r)   )r   r   r#   r   r   r   rc   â   s    
zProject._init_source_foldersc             C   s
   | j  ¡ S )N)ra   Ú	get_files)r   r   r   r   re   è   s    zProject.get_filesc                s   ‡ fdd„ˆ   ¡ D ƒS )z1Returns all python files available in the projectc                s   g | ]}ˆ j  |¡r|‘qS r   )r   Zis_python_file)Ú.0r8   )r   r   r   ú
<listcomp>í   s    z,Project.get_python_files.<locals>.<listcomp>)re   )r   r   )r   r   Úget_python_filesë   s    zProject.get_python_filesc             C   s   t jj| jf| d¡žŽ S )NrV   )r   r   ÚjoinrY   Úsplit)r   r"   r   r   r   r   ð   s    zProject._get_resource_pathc             C   sJ   | j d k	rF| j  ¡ s |  | j ¡ | j  d¡sF| j  d¡}| |  ¡ ¡ d S )Nz	config.py)rS   r   Ú_create_recursivelyÚ	has_childZcreate_fileÚwriteÚ_default_config)r   Úconfigr   r   r   Ú_init_ropefolderó   s    

zProject._init_ropefolderc             C   s.   |j | jkr"|j  ¡ s"|  |j ¡ | ¡  d S )N)rF   r-   r   rk   Zcreate)r   r#   r   r   r   rk   û   s    zProject._create_recursivelyc             C   sÄ   i }| j d k	r||  | j jd ¡}| dt|jdœ¡ | ¡ rX| j  d¡}t 	|j|¡ nt
|  ¡ |ƒ d|kr||d | jƒ x| ¡ D ]\}}|| j|< q†W |  ¡  |  ¡  d|krÀ|d | ƒ d S )Nz
/config.pyÚ__main__)rO   Ú__builtins__Ú__file__z	config.pyZ	set_prefsZproject_opened)rS   r;   r   Úupdaterr   Ú	real_pathr   Ú	get_childÚpycompatZexecfileÚexecrn   r   ÚitemsÚ_init_other_partsrp   )r   r   Úrun_globalsro   ÚkeyÚvaluer   r   r   rb      s$    
zProject._init_prefsc             C   s   dd l }dd l}| |jj¡S )Nr   )Zrope.base.default_configÚinspectZ	getsourcer]   Zdefault_config)r   r\   r~   r   r   r   rn     s    zProject._default_configc             C   s
   | j  d S )N)r   )r   r   r   r   rz     s    zProject._init_other_partsc             C   s   | j  |¡S )N)r_   Z
does_match)r   r8   r   r   r   rH     s    zProject.is_ignoredc             C   s   |   ¡  dS )zCloses project open resourcesN)rN   )r   r   r   r   Úsync!  s    zProject.syncc             C   s   | j  ¡  dS )zCloses project open resourcesN)r   rm   )r   r   r   r   rN   %  s    zProject.closec             C   s   | j  ||¡ dS )z#Set the `key` preference to `value`N)r   Úset)r   r|   r}   r   r   r   r€   )  s    zProject.setc             C   s   | j d k	r|  | j ¡S d S )N)rZ   r<   )r   r   r   r   rS   -  s    
zProject.ropefolderc                s"   |d kr| j }tt| ƒ |¡ d S )N)r-   r^   rT   r1   )r   r#   )rd   r   r   r1   2  s    zProject.validatec             C   s
   |   d¡S )NrD   )r   )r   r   r   r   Ú<lambda>7  s    zProject.<lambda>c             C   s   | j S )N)rY   )r   r   r   r   r   8  s    )NrU   )N)rO   rP   rQ   Ú__doc__r   r   Z
deprecatedrc   re   rh   r   rp   rk   rb   rn   rz   rH   r   rN   r€   rR   rS   r1   r-   ZaddressÚ__classcell__r   r   )rd   r   rT   ¼   s(    "rT   c                   sH   e Zd ZdZ‡ fdd„Zdd„ Z‡ fdd„Zdd	„ Zd
d„ ZdZ	‡  Z
S )Ú	NoProjectzvA null object for holding out of project files.

    This class is singleton use `get_no_project` global function
    c                s    t jj ¡ }tt| ƒ |¡ d S )N)r\   r]   r   ZFileSystemCommandsr^   r„   r   )r   r   )rd   r   r   r   A  s    zNoProject.__init__c             C   s   |  dtjj¡}t|ƒS )NrV   )Úreplacer   r   ÚseprW   )r   r"   Z	real_namer   r   r   r   E  s    zNoProject._get_resource_pathc                s$   t |ƒ tjjd¡}tt| ƒ |¡S )NrV   )rW   r…   r   r   r†   r^   r„   r   )r   r"   Zuniversal_name)rd   r   r   r   I  s    zNoProject.get_resourcec             C   s   g S )Nr   )r   r   r   r   re   M  s    zNoProject.get_filesc             C   s   g S )Nr   )r   r   r   r   rh   P  s    zNoProject.get_python_filesN)rO   rP   rQ   r‚   r   r   r   re   rh   Ú_no_projectrƒ   r   r   )rd   r   r„   ;  s   r„   c               C   s   t jd krt ƒ t _t jS )N)r„   r‡   r   r   r   r   r(   V  s    
r(   c               @   s6   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zdd
d„Zd	S )r`   c             C   s8   || _ d | _t | j| j| j| j| j¡}| j  |¡ d S )N)ÚprojectÚfilesÚresourceobserverZResourceObserverÚ_changedÚ_invalidr3   )r   rˆ   Zrawobserverr   r   r   r   ^  s    z_FileListCacher.__init__c             C   s&   | j d kr tƒ | _ |  | jj¡ | j S )N)r‰   r€   Ú
_add_filesrˆ   r-   )r   r   r   r   re   f  s    
z_FileListCacher.get_filesc             C   sB   x<|  ¡ D ]0}| ¡ r"|  |¡ q
| j |¡s
| j |¡ q
W d S )N)Zget_childrenÚ	is_folderr   rˆ   rH   r‰   Úadd)r   r#   Zchildr   r   r   r   l  s
    z_FileListCacher._add_filesc             C   s   |  ¡ rd | _d S )N)rŽ   r‰   )r   r8   r   r   r   r‹   s  s    z_FileListCacher._changedNc             C   s
   d | _ d S )N)r‰   )r   r8   Znew_resourcer   r   r   rŒ   w  s    z_FileListCacher._invalid)N)rO   rP   rQ   r   re   r   r‹   rŒ   r   r   r   r   r`   \  s
   r`   c               @   sX   e Zd Zdd„ Zddd„Zddd„Zdd	„ Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ ZdS )r   c             C   s   || _ g | _d S )N)rˆ   Úhooks)r   rˆ   r   r   r   r   }  s    z_DataFiles.__init__Fc             C   sÄ   | j jd krd S |o|  ¡ }|  |¡}|  ||¡}|sD|rD|  |¡ | ¡ rÀ||jdƒ}z\g }yx| t	 
|¡¡ qbW W n tk
rŒ   Y nX t|ƒdkr¢|d S t|ƒdkr²|S W d | ¡  X d S )NÚrbrC   r   )rˆ   rS   Ú_can_compressÚ_get_openerÚ	_get_fileÚ_import_old_filesr   ru   r)   ÚpickleÚloadÚEOFErrorÚlenrN   )r   r"   ÚcompressÚimport_ÚopenerÚfileÚinputr*   r   r   r   Ú	read_data  s*    

z_DataFiles.read_datac             C   s\   | j jd k	rX|o|  ¡ }|  ||¡}|  |¡}||jdƒ}zt ||d¡ W d | ¡  X d S )NÚwbrI   )	rˆ   rS   r’   r”   r“   ru   r–   ÚdumprN   )r   r"   Údatarš   r   rœ   Úoutputr   r   r   Ú
write_data™  s    
z_DataFiles.write_datac             C   s   | j  |¡ d S )N)r   r)   )r   Úhookr   r   r   Úadd_write_hook¤  s    z_DataFiles.add_write_hookc             C   s   x| j D ]
}|ƒ  qW d S )N)r   )r   r¥   r   r   r   rm   §  s    z_DataFiles.writec             C   s&   ydd l }dS  tk
r    dS X d S )Nr   TF)ÚgzipÚImportError)r   r§   r   r   r   r’   «  s
    z_DataFiles._can_compressc             C   s@   |   |d d¡}|   |d¡}| ¡ r<| ¡ s<t |j|j¡ d S )Nz.pickleF)r”   r   ÚshutilZmoveru   )r   r"   ÚoldÚnewr   r   r   r•   ²  s    z_DataFiles._import_old_filesc             C   s,   |r(ydd l }|jS  tk
r&   Y nX tS )Nr   )r§   Úopenr¨   )r   rš   r§   r   r   r   r“   ¸  s    z_DataFiles._get_openerc             C   s*   | j jjd | }|r|d7 }| j  |¡S )NrV   z.gz)rˆ   rS   r   r;   )r   r"   rš   r   r   r   r   r”   Á  s    z_DataFiles._get_fileN)FF)F)rO   rP   rQ   r   rŸ   r¤   r¦   rm   r’   r•   r“   r”   r   r   r   r   r   {  s   

	r   c             C   sv   t jdkrZ| dd… dkr| S | dd… dkrFd| d  | dd	…  } tj tj | ¡¡S tj tj tj | ¡¡¡S )
a^  Return the real path of `path`

    Is equivalent to ``realpath(abspath(expanduser(path)))``.

    Of the particular notice is the hack dealing with the unfortunate
    sitaution of running native-Windows python (os.name == 'nt') inside
    of Cygwin (abspath starts with '/'), which apparently normal
    os.path.realpath completely messes up.

    ÚcygwinrC   é   z:\z:/z
/cygdrive/r   rI   N)r'   Úplatformr   r   ÚabspathÚ
expanduserÚrealpath)r   r   r   r   rW   È  s    
rW   c             C   sº   | }|  d¡}x6|d d… D ]&}| ¡ r>| |¡r>| |¡}qd S qW | ¡ r¶| |d ¡r|| |d ¡ ¡ r|| |d ¡S | |d d ¡r¶| |d d ¡ ¡ s¶| |d d ¡S d S )NÚ.éÿÿÿÿz.py)rj   rŽ   rl   rv   )r#   rB   r$   ZpackagesÚpkgr   r   r   rA   Ý  s    
rA   )$r   r©   r'   rK   Zrope.base.fscommandsr\   Zrope.base.resourceobserverr]   rŠ   Zrope.base.utils.pycompatr   rw   Z	rope.baser   r   r   r   r   Zrope.base.exceptionsr   Zrope.base.resourcesr	   r
   r   ZcPickler–   r¨   Úobjectr   rT   r„   r(   r`   r   rW   rA   r   r   r   r   Ú<module>   s,     *M