a
    a                     @   sD  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	Z	ddl
Z
ddlZddl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ZddlZddlZddlmZ ddlZddlmZmZmZmZ dd	lmZ dd
l m!Z!m"Z"m#Z# ddl$m%Z% ddl&m'Z' e(e)e*Z+G dd de,Z-dSddZ.dd Z/dd Z0dd Z1dd Z2dd Z3dTddZ4dd Z5dd  Z6d!d" Z7d#d$ Z8d%d& Z9d'd( Z:d)d* Z;d+d, Z<d-d. Z=d/d0 Z>d1d2 Z?dUd3d4Z@ddg g fd5d6ZAd7d8 ZBd9d: ZCdVd;d<ZDd=d> ZEd?d@ ZFdAdB ZGdWdCdDZHdEdF ZIdGdH ZJdIdJ ZKdKdL ZLdMdN ZMdOdP ZNdQdR ZOdS )XzRunning programs utilities.    )print_function)literal_eval)getuser)dedentN)parse_version)is_stable_versionrunning_under_pytestget_home_dirrunning_in_mac_app)is_anaconda)PY2is_text_stringto_text_string)encoding)get_python_executablec                   @   s   e Zd ZdS )ProgramErrorN)__name__
__module____qualname__ r   r   4lib/python3.9/site-packages/spyder/utils/programs.pyr   +   s   r   c                 C   sn   t  g}tjdkr |d ntt }|d|  | durL||  tj	| }t
|sjt| |S )zP
    Return temporary Spyder directory, checking previously that it exists.
    ntspyderzspyder-N)tempfileZ
gettempdirosnameappendr   Zto_unicode_from_fsr   ospjoinisdirmkdir)suffixZto_joinusernameZtempdirr   r   r   get_temp_dir/   s    





r#   c           	      C   s  t  }g }tjdkr| dr,t| r,| S tdddt|ddg}t|ddg}g d	}d
d t||D }|	||  ntj
drtdddt|ddg}|dg}g d	}dd t||D }|	||  n\tjdkr@t|dddg}|dtddg}g d}dd t||D }|	||  tjd tj| D ]&}t|| }t|rV|  S qVdS )a  
    Return program absolute path if installed in PATH.
    Otherwise, return None.

    Also searches specific platform dependent paths that are not already in
    PATH. This permits general use without assuming user profiles are
    sourced (e.g. .bash_Profile), such as when login shells are not used to
    launch Spyder.

    On macOS systems, a .app is considered installed if it exists.
    darwin.appz/usrZlocalbinz.pyenvZoptz/opt)ZanacondaZ	minicondaZ	anaconda3Z
miniconda3c                 S   s    g | ]}t jg |d R  qS Zcondabinr   r   .0pr   r   r   
<listcomp>`       z(is_program_installed.<locals>.<listcomp>linuxc                 S   s    g | ]}t jg |d R  qS r'   r(   r)   r   r   r   r,   l   r-   r   z	pyenv-winzC:\ZProgramData)ZAnacondaZ	MinicondaZ	Anaconda3Z
Miniconda3c                 S   s    g | ]}t jg |d R  qS r'   r(   r)   r   r   r   r,   u   r-   PATHN)r	   sysplatformendswithr   existsr   	itertoolsproductextend
startswithr   r   environsplitpathsepisfile)	basenamehomeZ	req_pathsZpyenvabZcondapathabspathr   r   r   is_program_installedF   s<    
rB   c                    sX    g}t jdkr6d} |s6 fdd|D  g }|D ]}t|}|r:|  S q:dS )z
    Find program in PATH and return absolute path

    Try adding .exe or .bat to basename on Windows platforms
    (return None if not found)
    r   ).exe.bat.cmdc                    s   g | ]} | qS r   r   )r*   Zextr<   r   r   r,      r-   z find_program.<locals>.<listcomp>N)r   r   r2   rB   )r<   names
extensionsr   r@   r   rF   r   find_program   s    

rI   c                 C   s$   t jdkr| drdd| gS | gS )aq  
    Return the list of tokens necessary to open the program
    at a given path.

    On macOS systems, this function prefixes .app paths with
    'open -a', which is necessary to run the application.

    On all other OS's, this function has no effect.

    :str path: The path of the program to run.
    :return: The list of tokens necessary to run the program.
    r$   r%   open-a)r0   r1   r2   r@   r   r   r   get_full_command_for_program   s    
rM   c                  K   s   |  dtjdk tjdkrd}d}||O }|  d| | ddurd	D ]R}|ttj| d  vrJtj	 D ]*\}}|| krp| d 
||i  qJqpqJn.| ddurd
| d vr| d 
d
t i | S )aR  
    Given a dict, populate kwargs to create a generally
    useful default setup for running subprocess processes
    on different platforms. For example, `close_fds` is
    set on posix and creation of a new console window is
    disabled on Windows.

    This function will alter the given kwargs and return
    the modified dict.
    Z	close_fdsposixr   r   i   ZcreationflagsenvN)Z
SYSTEMROOTZSYSTEMDRIVEHOME)
setdefaultr   r   getmapstrupperkeysr8   itemsupdater	   )kwargsZCONSOLE_CREATION_FLAGSZCREATE_NO_WINDOWZenv_varkvr   r   r   #alter_subprocess_kwargs_by_platform   s"    

r\   c                 K   sz   d|v r|d st dnd|d< tjdksBd|vrBtd|d< dD ]}||tj qFtf i |}tj| fi |S )aF  
    Execute the given shell command.

    Note that *args and **kwargs will be passed to the subprocess call.

    If 'shell' is given in subprocess_kwargs it must be True,
    otherwise ProgramError will be raised.
    .
    If 'executable' is not given in subprocess_kwargs, it will
    be set to the value of the SHELL environment variable.

    Note that stdin, stdout and stderr will be set by default
    to PIPE unless specified in subprocess_kwargs.

    :str cmdstr: The string run as a shell command.
    :subprocess_kwargs: These will be passed to subprocess.Popen.
    shellzBThe "shell" kwarg may be omitted, but if provided it must be True.Tr   
executableZSHELLstdinstdoutstderr)	r   r   r   getenvrQ   
subprocessPIPEr\   Popen)Zcmdstrsubprocess_kwargsstreamr   r   r   run_shell_command   s    
ri   c                 K   sx   d|v r|d rt dt| }|s0t d|  t||p<g  }dD ]}||tj qDtf i |}tj|fi |S )a  
    Run program in a separate process.

    NOTE: returns the process object created by
    `subprocess.Popen()`. This can be used with
    `proc.communicate()` for example.

    If 'shell' appears in the kwargs, it must be False,
    otherwise ProgramError will be raised.

    If only the program name is given and not the full path,
    a lookup will be performed to find the program. If the
    lookup fails, ProgramError will be raised.

    Note that stdin, stdout and stderr will be set by default
    to PIPE unless specified in subprocess_kwargs.

    :str program: The name of the program to run.
    :list args: The program arguments.
    :subprocess_kwargs: These will be passed to subprocess.Popen.
    r]   zNThis function is only for non-shell programs, use run_shell_command() instead.zProgram %s was not foundr_   )r   rI   rM   rQ   rd   re   r\   rf   )programargsrg   Zfullcmdrh   r   r   r   run_program   s    rl   c              
   C   s   ddl m} zT|| }i }| |d< | |d< | |d< | |d< | |d< | |d< W n$ ty   d	d	d	d	d	| d
}Y n0 |S )z4Load data from desktop entry with xdg specification.r   )DesktopEntryr   	icon_pathexectypehiddenfpath )r   rn   rq   ro   rp   rr   )Zxdg.DesktopEntryrm   ZgetNameZgetIconZgetExecZgetTypeZ	getHidden	Exception)rr   rm   entry
entry_datar   r   r   parse_linux_desktop_entry  s&    	rw   c                 C   s   ddl }tj| d }}tj|d}i }tj|rZz||}W n tyX   Y n0 |d}d}|rtj|d|}|ds|d }tj|sd}|S )z=Parse mac application bundle and return path for *.icns file.r   NZContentsz
Info.plistZCFBundleIconFileZ	Resourcesz.icns)	plistlibr   r@   r   r;   Z	readPlistrt   rR   r2   )Zapp_bundle_pathrx   Zcontents_pathZ	info_pathZplZ	icon_filern   r   r   r   _get_mac_application_icon_path2  s$    

ry   c                  C   s2   t jdkrt  } nddl}|t  d } | S )z Return current session username.r   r   N)r   r   getloginpwdgetpwuidgetuid)r"   r{   r   r   r   get_usernameO  s
    

r~   c              
   C   s  ddl }|d|}g }z||| d|j|B }||d }t|D ]}	i }
z|||	}|drp|ds||
d< |||}|D ]<}z|	||d }||
|< W q t
y   d|
|< Y q0 q||
 W qF t
y   Y qFY qF0 qFW n ty   Y n0 |S )z3
    See: https://stackoverflow.com/q/53132434
    r   N{}keyrs   )winregZConnectRegistryOpenKeyZKEY_READZQueryInfoKeyrangeZEnumKeyr7   r2   ZQueryValueExEnvironmentErrorr   rt   )key_pathZhiveflagsubkeysr   Zregsoftware_listr   Zcount_subkeyindexsoftwareZsubkey_nameZsubkeypropertyvaluer   r   r   _get_win_reg_infoZ  s6    
r   c                 C   s4   |  dd } | d dkr0| d dkr0t| } | S )z/Normalize windows path and remove extra quotes.\/r   ")replacelowerr   rL   r   r   r   _clean_win_application_path}  s    r   c                     s<  ddl } d | j| jf| j| jf| jdfg}dgdi } fdd|D }tj| }t|fddd	D ]@}|d rl|d  	d
d}t
j|d }t|}|||< qld g ddi } fdd|D }tj| }t|fddd	D ]}|d |d }	|d }
|d }|	r|
r|
	dd}
|
dd }
dkrX|
rXt
j|
t
j|
sjd}
rt
jrfddt
D }|r|D ]`}| }|d}|r|dst
j|}t
j|}t|}|||	d | d < qqtt|  d }| D ]\}	}||vr|||	< q|S )z1Return all system installed windows applications.r   Nz3SOFTWARE\Microsoft\Windows\CurrentVersion\App Pathsr   c                    s"   g | ]}t  |d  |d qS r      r   r*   Zhfr   r   r   r   r,     r-   z)_get_win_applications.<locals>.<listcomp>c                    s   |   S Nr   xsort_keyr   r   <lambda>  r-   z'_get_win_applications.<locals>.<lambda>r   rC   rs   z3SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall)DisplayNameInstallLocationDisplayIconr   c                    s"   g | ]}t  |d  |d qS r   r   r   r   r   r   r,     r-   c                    s   |   S r   r   r   r   r   r   r     r-   r   r   r   ,c                    s&   g | ]}t jt j |r|qS r   )r   r@   r;   r   )r*   f)locationr   r   r,     s   )rC   .comrD   Zuninsz ()r   )r   HKEY_LOCAL_MACHINEZKEY_WOW64_32KEYZKEY_WOW64_64KEYHKEY_CURRENT_USERr4   chainsorted
capitalizer   r   r@   
expandvarsr   r9   dirnamer;   r   listdirr   r2   r7   r   listzipvaluesrW   )r   ZhfsZ	app_pathsZ_appsr   r   r   Zexpanded_fpathappsr   iconfilesfnameZfn_lowZ
valid_filerr   r   r   )r   r   r   r   r   _get_win_applications  sj    






r   c                  C   s~   i } ddg}g }|D ]*}t  |}|D ]}t|}|| q&qt|dd dD ](}|d sP|d dkrP|d	 | |d
 < qP| S )z/Return all system installed linux applications.z/usr/share/**/*.desktopz~/.local/share/**/*.desktopc                 S   s   | d S )Nr   r   r   r   r   r   r     r-   z)_get_linux_applications.<locals>.<lambda>r   rq   rp   ZApplicationrr   r   )globrw   r   r   )r   Zdesktop_app_pathsZall_entries_datar@   fpathsrr   rv   r   r   r   _get_linux_applications  s    
r   c                  C   sh   i } dd t g}g }|D ]}|t|7 }q|D ].}tj|r4tj|dd }|| |< q4| S )z-Return all system installed osx applications.z	/**/*.appz/Users/{}/**/*.appr%   r   )formatr~   r   r   r@   r   r<   r9   )r   Zapp_foldersr   r@   rr   r   r   r   r   _get_mac_applications  s    

r   c                 C   s   ddl m} ddlm} tj| s0tj| r|d}t	j
dkrft| }|rtj|r||}qtjdkrrqt| }|d }|rtj|r||}q||}n
|d}|S )	z5Return application icon or default icon if not found.r   )QIcon)imaZno_matchr$   r   rn   help)Z
qtpy.QtGuir   Zspyder.utils.icon_managerr   r   r@   r;   r   r   r0   r1   ry   r   rw   Z	fromTheme)rr   r   r   r   rn   rv   r   r   r   get_application_icon  s$    





r   c                  C   sb   i } t jdkrt } ntjdkr(t } nt } t jdkrLdd |  D } ndd |  D } | S )z
    Return all system installed applications.

    The return value is a list of tuples where the first item is the icon path
    and the second item is the program executable path.
    r$   r   c                 S   s    i | ]\}}t |r||qS r   )r   r   r*   r   valr   r   r   
<dictcomp>%  r-   z.get_installed_applications.<locals>.<dictcomp>c                 S   s    i | ]\}}t |r||qS r   )r   r;   r   r   r   r   r   '  r-   )r0   r1   r   r   r   r   r   rW   )r   r   r   r   get_installed_applications  s    


r   c           	   	   C   s  i }t jdkrdd |D }tjdkr| dr<t j| sDtddd| g| }zt	|}W n t
yv   d	}Y n0 ||d
|< nLt jdkr| drt j| std| g| }zt	|}W n ty   d	}Y n0 ||d
|< n| drt j| stdt| }|d } g }g }t|d	kr|d }d| v r\| d|}nPd| v rt| d|}n8d| v r| d|}n d| v r| d|}n| }|}nt|d	krRd| v r| dd
|}nd| v r| dd
|}d| v r |D ]}|| d| qn2d| v rJ|D ]}|| d| q.n| }|}|r|D ]<}ztj	|gdd}W n t
y   d	}Y n0 |||< q\n:ztj	|g| dd}W n t
y   d	}Y n0 |||< |S )z
    Generalized method for opening files with a specific application.

    Returns a dictionary of the command used and the return code.
    A code equal to 0 means the application executed successfully.
    r   c                 S   s   g | ]}| d dqS )r   r   )r   )r*   r   r   r   r   r,   6  r-   z/open_files_with_application.<locals>.<listcomp>r$   r%   z2`app_path`  must point to a valid OSX application!rJ   rK   r    )rC   rD   r   rE   z5`app_path`  must point to a valid Windows executable!z.desktopz3`app_path` must point to a valid Linux application!ro   r   z%uz%fz%Uz%FT)r]   )r   r   r0   r1   r2   r@   r   
ValueErrorrd   Zcallrt   r   r;   OSErrorrw   lenr   r   )	Zapp_pathfnamesZreturn_codescmdZreturn_coderu   ZmultiZextrar   r   r   r   open_files_with_application,  s    

















r   c                 C   s   |dusJ | du r2t j|}|r,|j}qZd}n(t j| }|rVt|j|d }nd}|r~t|sp|d7 }t|r~|S dS )z
    Return absolute path if Python script exists (otherwise, return None)
    package=None -> module is in sys.path (standard library modules)
    Nz.pyw)	importlibutil	find_specoriginr   r   r;   )packagemodulespecr@   r   r   r   python_script_exists  s    

r   c                 C   sP   |dusJ t |ttfr(t |ttfs,J t| |}ttj||g |  dS )zv
    Run Python script in a separate process
    package=None -> module is in sys.path (standard library modules)
    N)
isinstancetupler   r   rl   r0   r^   )r   r   rk   p_argsr@   r   r   r   run_python_script  s     
r   c                 C   sH   t | sJ d}g }t|| D ]"}| r ||dd q |S )ac  
    Split the string `text` using shell-like syntax

    This avoids breaking single/double-quoted strings (e.g. containing
    strings with spaces). This function is almost equivalent to the shlex.split
    function (see standard library `shlex`) except that it is supporting
    unicode strings (shlex does not support unicode until Python 2.7.3).
    z/(\s+|(?<!\\)".*?(?<!\\)"|(?<!\\)\'.*?(?<!\\)\')r   ')r   rer9   stripr   )textpatternouttokenr   r   r   shell_split  s    	r   c                 C   s   g }|dur||  7 }|r&|d |r8|ddg | durttjdkrj|rj|t| tjd n
||  |r|t	| |S )z&Construct Python interpreter argumentsNz-iz-mZpdbr   r   )
r9   r   r6   r   r   r   normpathr   sepr   )r   python_argsinteractdebugZend_argsr   r   r   r   get_python_args  s    

r   c              	      sz  |du rt  }tjdkr<d|  d } |dd}d| d }|g}|t| ||||7 }tjdkrd}|rz|d| d 7 }|d	|d d
 7 }trt|}t|}z|rt	||d nt	| W nF t
y   ddlm}	 ddlm}
 |	d|
d|
d|	j Y n0 ndtjdrddddddddddddddddg}|D ]|}t|d rPg }|d r|r||d |g7 }||d  ||7 }|rt|d ||d nt|d |  dS qPntjdkrrtjdd d!t d"d# |r d$| t|r* d%tjd&  d'  d	|    t jd(  fd)d*}t j!|d+}|"  nt#dS ),zl
    Run Python script in an external system terminal.

    :str wdir: working directory, may be empty.
    Nr   r   r   r   zstart cmd.exe /K "zcd z && r   z
 ^&^& exit)cwdr   )QMessageBox)_ZRunz<It was not possible to run this file in an external terminalr.   zgnome-terminalz--working-directoryz-x)r   wdir-optionexecute-optionZkonsolez	--workdirz-ezxfce4-terminalZxtermr   r   r   r$   ZwtZrun_spyder_z.shF)prefixr!   dirdeletezcd {}
zexport PYTHONHOME=Z
PYTHONPATH
i  c                     s4   t d j i d} td |   t j d S )Nzopen -a Terminal.app rO      )ri   r   timesleepwaitr   removeprocr   r   r   run_terminal_thread"  s    
z:run_python_script_in_terminal.<locals>.run_terminal_thread)target)$r   r   r   r   r   r   r   r   Zto_fs_from_unicoderi   ZWindowsErrorZqtpy.QtWidgetsr   spyder.config.baser   ZcriticalZOkr0   r1   r7   rB   r   rl   r   ZNamedTemporaryFiler#   writer   r
   r8   closechmod	threadingZThreadstartNotImplementedError)r   Zwdirrk   r   r   r   r^   r   r   r   r   Zprogramsrj   Zarglistr   threadr   r   r   run_python_script_in_terminal  s    




r  c                 C   s   t | trddd | D } z|dkr:t| t|kW S |dkrTt| t|kW S |dkrnt| t|kW S |dkrt| t|k W S |dkrt| t|kW S W d	S W n ty   Y d
S 0 dS )a  
    Check version string of an active module against a required version.

    If dev/prerelease tags result in TypeError for string-number comparison,
    it is assumed that the dependency is satisfied.
    Users on dev branches are responsible for keeping their own packages up to
    date.

    Copyright (C) 2013  The IPython Development Team

    Distributed under the terms of the BSD License.
    .c                 S   s   g | ]}t |qS r   )rT   )r*   ir   r   r   r,   =  r-   z!check_version.<locals>.<listcomp>>>==<<=FTN)r   r   r   r   	TypeError)ZactverversionZcmp_opr   r   r   check_version/  s     

r  c                 C   sH   d}z t | }t|dt|dd}W n ty6   Y n0 |sDt| }|S )z<Return module version or None if version can't be retrieved.N__version__ZVERSION)
__import__getattrModuleNotFoundErrorget_package_version)module_namevermodr   r   r   get_module_versionP  s    r  c                 C   s.   zt | j}|W S  t jy(   Y dS 0 dS )z=Return package version or None if version can't be retrieved.N)pkg_resourcesZget_distributionr  ZDistributionNotFound)Zpackage_namer  r   r   r   r  ]  s
    r  c                 C   s  |durt |rtd| }z.t|d|gi d}| \}}|  }W n ty`   Y dS 0 d|v rndS |dkr||}qd}qdS nTzt| }W n ty   Y dS 0 zt	| }t
|d	dsW dS W n ty   Y n0 |du rdS d
|v  r|d
}	n|g}	d}
|	D ]v}td|}|dus.J d|d|  }|sHd}|dv s^J d| || d }|
o~t|||}
q|
S dS )a<  
    Return True if module ``module_name`` is installed

    If ``version`` is not None, checks that the module's installed version is
    consistent with ``version``. The module must have an attribute named
    '__version__' or 'VERSION'.

    version may start with =, >=, > or < to specify the exact requirement ;
    multiple conditions may be separated by ';' (e.g. '>=0.13;<1.0')

    If ``interpreter`` is not None, checks if a module is installed with a
    given ``version`` in the ``interpreter``'s environment. Otherwise checks
    in Spyder's environment.
    Na  
                try:
                    import {} as mod
                except Exception:
                    print('No Module')  # spyder: test-skip
                print(getattr(mod, '__version__', getattr(mod, 'VERSION', None)))  # spyder: test-skip
                -cr   Fz	No ModuleNoneT__file__;z[0-9]zInvalid version numberr
  )r	  r  r
  r  r  zInvalid version condition '%s')is_python_interpreterr   r   rl   communicatedecoder   rt   r  r  r  r9   r   searchr  r  )r  r  Zinterpreterr   r   ra   rb   Zmodule_versionr  ZversionsoutputZ_vermatchZsymbr  r   r   r   is_module_installedi  sZ    

r$  c                 C   s&   d}t j|| t jddu rdS dS dS )z8Check that the python interpreter file has a valid name.z.*python(\d\.?\d*)?(w)?(.exe)?$flagsNFTr   r#  Ifilenamer   r   r   r    is_python_interpreter_valid_name  s    r+  c                 C   s   t j| }t|rt| s"dS t| rt jdkrHt	|sBdS dS qt
jdkrzt rft	|rfdS t	|stdS dS qdS nt	|rdS t| S dS )z7Evaluate whether a file is a python interpreter or not.Fr   Tr$   N)r   r@   realpathr   r;   r+  
is_pythonwr   r   Zis_text_filer0   r1   r   check_python_help)r*  Zreal_filenamer   r   r   r    s(    





r  c                 C   s&   d}t j|| t jddu rdS dS dS )z0Check that the python interpreter has 'pythonw'.z.*python(\d\.?\d*)?w(.exe)?$r%  NFTr'  r)  r   r   r   r-    s    r-  c                    sn   zTt | ddgi d}| \ }t  g d}t fdd|D rLW dS W dS W n tyh   Y dS 0 d	S )
zBCheck that the python interpreter can compile and provide the zen.r  zimport thisr   )zBeautiful is better than ugly.z!Explicit is better than implicit.zSimple is better than complex.z#Complex is better than complicated.c                 3   s   | ]}| v V  qd S r   r   )r*   linera   r   r   	<genexpr>  r-   z$check_python_help.<locals>.<genexpr>TFN)rl   r  r   allrt   )r*  r   r   Zvalid_linesr   r0  r   r.    s    
r.  c              	   C   s~   z\t t| }tg d}t r,|d tdd | dd D }||@ g}t|W S  t jt j	fyx   Y dS 0 dS )aT  
    Test whether given PID belongs to a Spyder process.

    This is checked by testing the first three command line arguments. This
    function returns a bool. If there is no process with this PID or its
    command line cannot be accessed (perhaps because the process is owned by
    another user), then the function returns False.
    )r   Zspyder3z
spyder.exezspyder3.exezbootstrap.pyzspyder-script.pyzSpyder.launch.pywzruntests.pyc                 s   s   | ]}t j|V  qd S r   )r   r@   r<   )r*   argr   r   r   r1    r-   z$is_spyder_process.<locals>.<genexpr>Nr   F)
psutilZProcessintsetr   addZcmdlineanyZNoSuchProcessZAccessDenied)pidr+   rG   Z	argumentsZ
conditionsr   r   r   is_spyder_process   s    	


r:  c                 C   s@   z t | dg \}}| }W n ty6   d}Y n0 | S )z>Return version information of the selected Python interpreter.z-Vrs   )rl   r  r   rt   r   )r@   r   __r   r   r   get_interpreter_info  s    
r<  c                  C   sB   t jdkr6tjttddd} | jdkr.dS tdS tdS dS )z"Find git executable in the system.r$   zcheck-git.shT)Zcapture_outputr   NZgit)	r0   r1   rd   runr   r   HERE
returncoderI   r   r   r   r   find_git$  s    

r@  )N)N)NN)N)NN)P__doc__Z
__future__r   astr   Zgetpassr   textwrapr   r   r   r4   r   os.pathr@   r   r   rd   r0   r   r  r   r  r   r4  r   r   r   r	   r
   Zspyder.config.utilsr   Zspyder.py3compatr   r   r   Zspyder.utilsr   Zspyder.utils.miscr   rA   r   r  r>  rt   r   r#   rB   rI   rM   r\   ri   rl   rw   ry   r~   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r$  r+  r  r-  r.  r:  r<  r@  r   r   r   r   <module>   sx   
9''
&#	HW
 
`!
Q	 	
