B
    nôb\fA  ã               @   sF  d Z ddlmZ ddl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mZ ddl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 ddlmZmZ ddlm Z  ddl!m"Z" ddl#m$Z$ ddl%m&Z&m'Z'm(Z( ddl)m*Z* e$e_$dd„ Z+G dd„ deƒZ,G dd„ de-ƒZ.G dd„ deƒZ/G dd„ de"ƒZ0dS )z7Internal shell widget : PythonShellWidget + Interpreteré    )ÚtimeN)Ú
QEventLoopÚQObjectÚSignalÚSlot)ÚQMessageBox)Ú	getargtxtÚgetdocÚ	getobjdirÚ	getsource)Úget_versions)ÚInterpreter)ÚbuiltinsÚto_binary_stringÚto_text_string)Úicon_manager)Úprograms)Úget_error_matchÚgetcwd_or_home)Úcreate_action)ÚPythonShellWidget)Úoedit)Ú_ÚDEBUGÚget_conf_path)ÚCONFc             C   s0   | dkr(t ƒ }d|d |d |d f S | S dS )zCreate internal shell bannerNzPython %s %dbits [%s]ZpythonZbitnessÚsystem)r   )ÚmessageZversions© r   ú;lib/python3.7/site-packages/spyder/widgets/internalshell.pyÚcreate_banner0   s
    r    c               @   sB   e Zd ZdZeƒ Zdd„ Zdd„ Zdd„ Zdd	„ Z	e
d
d„ ƒZdS )Ú	SysOutputzHandle standard I/O queuec             C   s   t  | ¡ g | _t ¡ | _d S )N)r   Ú__init__ÚqueueÚ	threadingZLockÚlock)Úselfr   r   r   r"   >   s    
zSysOutput.__init__c             C   s.   | j  ¡  | j |¡ | j  ¡  | j ¡  d S )N)r%   Úacquirer#   ÚappendÚreleaseÚ
data_availÚemit)r&   Úvalr   r   r   ÚwriteC   s    

zSysOutput.writec             C   s*   | j  ¡  d | j¡}g | _| j  ¡  |S )NÚ )r%   r'   Újoinr#   r)   )r&   Úsr   r   r   Úempty_queueI   s
    

zSysOutput.empty_queuec             C   s   d S )Nr   )r&   r   r   r   ÚflushQ   s    zSysOutput.flushc             C   s   dS )NFr   )r&   r   r   r   ÚclosedU   s    zSysOutput.closedN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r*   r"   r-   r1   r2   Úpropertyr3   r   r   r   r   r!   :   s   r!   c               @   s   e Zd ZdS )ÚWidgetProxyDataN)r4   r5   r6   r   r   r   r   r9   Y   s   r9   c               @   sn   e Zd ZdZeeƒZeeƒZeeeƒZ	eeƒZ
dd„ Zdd„ Zdd„ Zdd	d
„Zdd„ Zddd„Zdd„ ZdS )ÚWidgetProxyz"Handle Shell widget refresh signalc             C   s   t  | ¡ d | _|| _d S )N)r   r"   Ú
input_dataÚinput_condition)r&   r<   r   r   r   r"   d   s    
zWidgetProxy.__init__c             C   s   | j  |¡ d S )N)Úsig_new_promptr+   )r&   Úpromptr   r   r   Ú
new_prompti   s    zWidgetProxy.new_promptc             C   s   | j  |¡ d S )N)Úsig_set_readonlyr+   )r&   Ústater   r   r   Úset_readonlyl   s    zWidgetProxy.set_readonlyFc             C   s   | j  ||¡ d S )N)Úsig_editr+   )r&   ÚfilenameÚexternal_editorr   r   r   Úedito   s    zWidgetProxy.editc             C   s
   | j tk	S )z&Return True if input data is available)r;   r9   )r&   r   r   r   Údata_availabler   s    zWidgetProxy.data_availabler.   c             C   s   t | _| j |¡ d S )N)r9   r;   Úsig_wait_inputr+   )r&   r>   r   r   r   Ú
wait_inputv   s    zWidgetProxy.wait_inputc             C   s(   | j  ¡  || _| j  ¡  | j  ¡  d S )N)r<   r'   r;   Znotifyr)   )r&   Úcmdr   r   r   Ú	end_inputz   s    

zWidgetProxy.end_inputN)F)r.   )r4   r5   r6   r7   r   Ústrr=   Úboolr@   rC   rH   r"   r?   rB   rF   rG   rI   rK   r   r   r   r   r:   \   s   


r:   c            
   @   sJ  e Zd ZdZeeƒZeƒ ZeeƒZeƒ Z	ddg dddddddf
dd„Z
dd	„ Zd
d„ Zdd„ Zdd„ Zdd„ ZdFdd„Zdd„ Zdd„ Zeƒ dd„ ƒZdd„ ZdGdd„ZdHd d!„Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ ZdId0d1„Zd2d3„ Z d4d5„ Z!d6d7„ Z"d8d9„ Z#d:d;„ Z$d<d=„ Z%d>d?„ Z&d@dA„ Z'dBdC„ Z(dJdDdE„Z)dS )KÚInternalShellzAShell base widget: link between PythonShellWidget and InterpreterNi,  FTc             C   sÊ   t  | |tdƒ|¡ |  |
¡ |	| _|  |¡ |d k	r@|  |¡ d | _d| _d| _	| j
 | j¡ dd„ }|dƒ}|  |¡ g | _|| _|| _|| _d | _|  |¡ | j d¡ ttdƒrÆ| j | j¡ d S )Nzhistory_internal.pyFc             S   s   t  d| ¡S )NÚinternal_console)r   Úget)Zoptionr   r   r   Ú<lambda>    s    z(InternalShell.__init__.<locals>.<lambda>zcodecompletion/case_sensitiver.   Úopen_in_spyder)r   r"   r   Zset_light_backgroundÚmultithreadedZsetMaximumBlockCountZset_fontÚ
input_loopÚ
input_modeÚinterruptedZsig_keyboard_interruptÚconnectÚkeyboard_interruptZset_codecompletion_caseÚ
eventqueueÚexitfuncÚcommandsr   ÚinterpreterÚstart_interpreterÚstatusr+   Úhasattrr   Úgo_to_errorÚopen_with_external_spyder)r&   ÚparentÚ	namespacer[   r   Zmax_line_countZfontrZ   ÚprofilerS   Zlight_backgroundZgetcfgZcase_sensitiver   r   r   r"   ‰   s0    





zInternalShell.__init__c             C   s  |   ¡  | jdk	r| j ¡  t|| jtttƒ| _| jjj	 
| j¡ | jjj	 
| j¡ | jjj 
| j¡ | jjj 
| j¡ | jjj 
| j¡ | jjj 
| j¡ | jr¬| j ¡  t| jƒ}| j|dd x| jD ]}| j|ddd qÌW |  | jj¡ | j  ¡  | jS )zStart Python interpreterNT)r>   F)Úhistoryr?   )!Úclearr\   Úclosingr   rZ   r!   r:   r   Ústdout_writer*   rW   Ústdout_availÚstderr_writeÚstderr_availÚwidget_proxyr@   ZsetReadOnlyr=   r?   rC   Úedit_scriptrH   rI   rS   Ústartr    r   r-   r[   Úrun_commandÚp1Úrefreshr+   )r&   rc   ZbannerrJ   r   r   r   r]   ·   s(    




zInternalShell.start_interpreterc             C   s.   d| j _| jr | j j tdƒ¡ | j  ¡  dS )zExit interpreterTÚ
N)r\   Z	exit_flagrS   Ústdin_writer-   r   Zrestore_stds)r&   r   r   r   Úexit_interpreterÖ   s    zInternalShell.exit_interpreterc             C   s*   t |ƒ}|r|  |¡ n|  ¡  |¡ d S )N)r   rE   rb   rm   )r&   rD   rE   r   r   r   rm   Ý   s    zInternalShell.edit_scriptc             C   s   | j j ¡ }|r|  |¡ dS )z@Data is available in stdout, let's empty the queue and write it!N)r\   rh   r1   r-   )r&   Údatar   r   r   ri   ä   s    zInternalShell.stdout_availc             C   s.   | j j ¡ }|r*| j|dd | jdd dS )z@Data is available in stderr, let's empty the queue and write it!T)ÚerrorN)r\   rj   r1   r-   r2   )r&   ru   r   r   r   rk   ê   s    zInternalShell.stderr_availr.   c             C   s4   |   |¡ |  ¡  d| _tƒ | _| j ¡  d| _dS )z"Wait for input (raw_input support)TN)r?   ZsetFocusrU   r   rT   Zexec_)r&   r>   r   r   r   rI   ó   s    

zInternalShell.wait_inputc             C   s"   d| _ | j ¡  | jj |¡ dS )zEnd of wait_input modeFN)rU   rT   Úexitr\   rl   rK   )r&   rJ   r   r   r   rK   ü   s    
zInternalShell.end_inputc             C   s:   t  | ¡ t| tdƒt d¡| jd| _| j 	| j¡ dS )z$Reimplement PythonShellWidget methodzHelp...ZDialogHelpButton)ÚiconZ	triggeredN)
r   Úsetup_context_menur   r   Úimarx   ÚhelpZhelp_actionZmenuZ	addAction)r&   r   r   r   ry     s
    

z InternalShell.setup_context_menuc             C   sJ   t  | tdƒdtdƒtdƒtdƒtdƒtdƒtdƒtd	ƒtd
ƒf ¡ dS )zHelp on Spyder consoleZHelpaÁ  <b>%s</b>
                          <p><i>%s</i><br>    edit foobar.py
                          <p><i>%s</i><br>    xedit foobar.py
                          <p><i>%s</i><br>    run foobar.py
                          <p><i>%s</i><br>    clear x, y
                          <p><i>%s</i><br>    !ls
                          <p><i>%s</i><br>    object?
                          <p><i>%s</i><br>    result = oedit(object)
                          zShell special commands:zInternal editor:zExternal editor:zRun script:zRemove references:zSystem commands:zPython help:zGUI-based editor:N)r   Zaboutr   )r&   r   r   r   r{     s    	zInternalShell.helpc             C   s0   t t|ƒƒ}|r,| ¡ \}}t |t|ƒ¡ dS )z¶Load file in external Spyder's editor, if available
        This method is used only for embedded consoles
        (could also be useful if we ever implement the magic %edit command)N)r   r   Úgroupsr   rR   Úint)r&   ÚtextÚmatchÚfnameZlnbr   r   r   ra   #  s    z'InternalShell.open_with_external_spyderéÿÿÿÿc             C   st   t  dd¡}t  dd¡}y4|g}|dkr>|r>| d ||¡¡ t ||¡ W n" tk
rn   |  d| ¡ Y nX dS )zcEdit in an external editor
        Recommended: SciTE (e.g. to go to line where an error did occur)rO   zexternal_editor/pathzexternal_editor/gotoliner   z%s%dz"External editor was not found: %s
N)r   rP   r(   Úformatr   Zrun_programÚOSErrorÚwrite_error)r&   rD   ZgotoZeditor_pathZgoto_optionÚargsr   r   r   rE   ,  s    zInternalShell.external_editorc             C   s$   t j| ||d | jr d| _t‚dS )z"Reimplement ShellBaseWidget method)rv   r>   FN)r   r2   rV   ÚKeyboardInterrupt)r&   rv   r>   r   r   r   r2   <  s    zInternalShell.flushc             C   s*   |   ¡  |  | jjr| jjn| jj¡ dS )z"Reimplement ShellBaseWidget methodN)rf   r?   r\   ÚmoreZp2rp   )r&   r   r   r   Úclear_terminalE  s    zInternalShell.clear_terminalc             C   sf   | j rPtƒ }xtdƒD ]}|  |¡ qW |  ddtƒ |   ¡ |  | jj¡ n
|  |¡ |  ¡  dS )Úon_enteré
   u   
<Î”t>=%dms
g      Y@N)	rd   r   ÚrangeÚexecute_commandZinsert_textr?   r\   rp   Ú _InternalShell__flush_eventqueue)r&   ZcommandZt0r   r   r   r   r‰   L  s    
zInternalShell.on_enterc             C   s   |   |¡rdS |  |¡ dS )zO
        Reimplement Qt Method
        Enhanced keypress event handler
        N)Zpreprocess_keyeventÚpostprocess_keyevent)r&   Zeventr   r   r   ÚkeyPressEventY  s    
zInternalShell.keyPressEventc             C   s&   x | j r | j  d¡}|  |¡ qW dS )zFlush keyboard event queuer   N)rY   ÚpoprŽ   )r&   Z
past_eventr   r   r   Z__flush_eventqueuec  s    z InternalShell.__flush_eventqueuec             C   sP   | j r| j ¡  n:| jjrF|  d¡ d| j_|  | jj¡ | j ¡  nd| _dS )zSimulate keyboard interruptz
KeyboardInterrupt
FTN)	rS   r\   Zraise_keyboard_interruptr‡   r„   r?   rp   ZresetbufferrV   )r&   r   r   r   rX   j  s    
z InternalShell.keyboard_interruptc             C   sT   xN|  ¡ D ]B}| ¡ }| d¡r"q
| j|tj dd |  |d ¡ |  ¡  q
W dS )z„
        Execute a set of lines as multiple command
        lines: multiple lines of text to be executed as single commands
        ú#T)r2   rr   N)Ú
splitlinesÚstripÚ
startswithr-   ÚosÚlineseprŒ   r2   )r&   ÚlinesÚlineZstripped_liner   r   r   Úexecute_linesw  s    
zInternalShell.execute_linesc             C   sL   | j r|  |¡ dS | d¡r*|dd… }|dkr>|  ¡  dS |  |¡ dS )z[
        Execute a command
        cmd: one-line command only, with '
' at the end
        Nrr   r   Úcls)rU   rK   Úendswithrˆ   ro   )r&   rJ   r   r   r   rŒ   „  s    

zInternalShell.execute_commandc             C   s€   |s
d}n|r|   |¡ | jsfd|krR| jj t|d ƒ¡ | j ¡  | j ¡  q|| jt	dƒdd n| jj t|d ƒ¡ dS )zRun command in interpreterr.   Úinputrr   z‚In order to use commands like "raw_input" or "input" run Spyder with the multithread option (--multithread) from a system terminalT)rv   N)
Zadd_to_historyrS   r\   rs   r-   r   Zrun_linerq   r+   r   )r&   rJ   re   r?   r   r   r   ro   ”  s    



zInternalShell.run_commandc             C   s   | j  |¡S )zIs text a valid object?)r\   Úeval)r&   r~   r   r   r   Ú_eval«  s    zInternalShell._evalc             C   s   |   |¡\}}|rt|ƒS dS )zReturn dir(object)N)rž   r
   )r&   ÚobjtxtÚobjÚvalidr   r   r   Úget_dir¯  s    zInternalShell.get_dirc             C   s   t | jj ¡ ƒS )zReturn shell globals() keys)Úlistr\   rc   Úkeys)r&   r   r   r   Úget_globals_keysµ  s    zInternalShell.get_globals_keysc             C   s   t  tƒ ¡S )z'Return shell current directory list dir)r•   Úlistdirr   )r&   r   r   r   Úget_cdlistdir¹  s    zInternalShell.get_cdlistdirc             C   s   |   |¡\}}|rt|ƒS dS )zIs object callable?N)rž   Úcallable)r&   rŸ   r    r¡   r   r   r   Ú
iscallable½  s    zInternalShell.iscallablec             C   s   |   |¡\}}|rt|ƒS dS )zGet func/method argument listN)rž   r   )r&   rŸ   r    r¡   r   r   r   Úget_arglistÃ  s    zInternalShell.get_arglistc             C   s   |   |¡\}}|r|jS dS )zGet object __doc__N)rž   r7   )r&   rŸ   r    r¡   r   r   r   Ú
get__doc__É  s    zInternalShell.get__doc__c             C   s   |   |¡\}}|rt|ƒS dS )z#Get object documentation dictionaryN)rž   r	   )r&   rŸ   r    r¡   r   r   r   Úget_docÏ  s    zInternalShell.get_docc             C   s   |   |¡\}}|rt|ƒS dS )zGet object sourceN)rž   r   )r&   rŸ   r    r¡   r   r   r   Ú
get_sourceÕ  s    zInternalShell.get_sourcec             C   s   | j  ||¡S )z Return True if object is defined)r\   Ú
is_defined)r&   rŸ   Zforce_importr   r   r   r®   Û  s    zInternalShell.is_defined)r.   )r   )FF)TT)F)*r4   r5   r6   r7   r   rL   r^   rq   r`   Zfocus_changedr"   r]   rt   rm   ri   rk   rI   rK   ry   r   r{   ra   rE   r2   rˆ   r‰   r   r   rX   r™   rŒ   ro   rž   r¢   r¥   r§   r©   rª   r«   r¬   r­   r®   r   r   r   r   rN      sL   ,	
		

	

rN   )1r7   r   r•   r$   Zqtpy.QtCorer   r   r   r   Zqtpy.QtWidgetsr   Zspyder_kernels.utils.dochelpersr   r	   r
   r   Zspyderr   Zspyder.interpreterr   Zspyder.py3compatr   r   r   Zspyder.utilsr   rz   r   Zspyder.utils.miscr   r   Zspyder.utils.qthelpersr   Zspyder.widgets.shellr   Z,spyder.widgets.variableexplorer.objecteditorr   Zspyder.config.baser   r   r   Zspyder.config.mainr   r    r!   Úobjectr9   r:   rN   r   r   r   r   Ú<module>   s.   

%