B
    nôb\«< ã               @   sÎ  d 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	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 dd	lmZmZmZ dd
lmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z) ddl*m+Z+m,Z, ddl-m.Z/ yddl0Z0W n e1k
r   dZ0Y nX ddl2m3Z3 ddl4m5Z5m6Z6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z?m@Z@mAZA ddlBmCZC ddlDmEZE ddlFmGZGmHZH ddlImJZK ddlImLZLmMZMmNZN ddlOmPZP ddlQmRZRmSZS ddlTmUZU ddlVmWZW ddlXmYZY dZZe3j[de5dƒeZd d! d"Z\e3j[d#e5d$ƒe\d d! d%Z]e3j[d&e5d'ƒe]d( e@rVd)nd*Z^e3j[d+e5d,ƒe^d( d-Z_e3j[d.e5d/ƒe_d d! d0d1„ Z`d<d4d5„ZaG d6d7„ d7eƒZbG d8d9„ d9e=ƒZcG d:d;„ d;e;ƒZddS )=z+
IPython Console plugin based on QtConsole
é    N)Úfind_connection_file)Újupyter_config_dirÚjupyter_runtime_dir)ÚQtKernelClient)ÚQtKernelManager)ÚPYQT5)Úgetopenfilename)ÚQtÚSignalÚSlot)ÚQApplicationÚ	QCheckBoxÚQDialogÚQDialogButtonBoxÚQFormLayoutÚQGridLayoutÚ	QGroupBoxÚQHBoxLayoutÚQLabelÚ	QLineEditÚQMessageBoxÚQPushButtonÚ
QTabWidgetÚQVBoxLayoutÚQWidget)ÚConfigÚload_pyconfig_files)Útunnel)Údependencies)Ú_Úget_conf_pathÚget_home_dir)ÚCONF)ÚSpyderPluginWidget)ÚPluginConfigPage)Ú	is_stringÚPY2Úto_text_string)ÚSpyderKernelSpec)Úcreate_qss_style)Úcreate_actionÚMENU_SEPARATOR)Úicon_manager)ÚencodingÚprogramsÚ
sourcecode)Úget_temp_dir)Úget_error_matchÚremove_backslashes)ÚFindReplace)ÚClientWidget)ÚTabsz>=0.7.3Úsympyz+Symbolic mathematics in the IPython ConsoleT)Úrequired_versionZoptionalz>=0.21Zcythonz'Run Cython files in the IPython Consolez>=4.2.0Z	qtconsolezIntegrate the IPython console)r7   z
>=4.0;<6.0z>=4.0ÚIPythonz&IPython interactive python environmentz>=2.0.0Z
matplotlibz*Display 2D graphics in the IPython Consolec             C   s   t  | ¡ d S )N)ÚpexpectÚrun)Úcmd© r<   ú<lib/python3.7/site-packages/spyder/plugins/ipythonconsole.pyÚ_stop_tunnelY   s    r>   ú	127.0.0.1çš™™™™™Ù?c             C   s@  t d krtdƒ‚d}|r$|d| 7 }d|krF| d¡\}}	|d|	 7 }d||f }
t j|
dd\}}|sÊt|| d	¡d
 | d¡… ƒ}d|||||f }
t j|
dd\}}|sÊt t|
 	ddd¡¡ |S d||||||f }
t
j ¡ }| dd ¡ d}t j|
|d}d}x.yª|j|dgdd}|dkr˜| d¡d }tdƒ| }t | tdƒ|tjtjB tj¡}|tjkr‚| d¡ wn| d¡ ttdƒƒ‚|dkr¶|d k	r¶| |¡ W nR t jk
rÔ   wY nb t jk
r
   |jr ttd ƒ|
 ƒ‚n|jS Y n,X |s|d kr(ttd!ƒƒ‚| |¡ d}qW d S )"Nz(pexpect unavailable, use paramiko_tunnelzssh z-i ú:z -p %sz%s -O check %sT)Zwithexitstatusz(pid=é   ú)z&%s -O forward -L 127.0.0.1:%i:%s:%i %sz
-O forwardz	-O cancelé   z/%s -f -S none -L 127.0.0.1:%i:%s:%i %s sleep %iZSSH_ASKPASSz,Are you sure you want to continue connecting)ÚenvFz[Pp]assword:gš™™™™™¹?)Útimeoutr   ú@éÿÿÿÿzfThe authenticity of host <b>%s</b> can't be established. Are you sure you want to continue connecting?ÚWarningZyesZnoz1The authenticity of the host can't be establishedzTunnel '%s' failed to startz Could not connect to remote host)r9   ÚImportErrorÚsplitr:   ÚintÚfindÚatexitÚregisterr>   ÚreplaceÚosÚenvironÚcopyÚpopZspawnZexpectr   r   ÚquestionÚYesÚNoZsendlineÚRuntimeErrorZTIMEOUTZEOFÚ
exitstatusÚpid)ÚselfZlportZrportZserverZremoteipZkeyfileÚpasswordrF   ZsshZportr;   ÚoutputrY   rZ   rE   Z
ssh_newkeyr   ZfailedÚiZhostrU   Zreplyr<   r<   r=   Úopenssh_tunnel\   sn     






r_   c                   s@   e Zd ZdZd‡ fdd„	Zdd„ Zdd„ Zedd	d
„ƒZ‡  Z	S )ÚKernelConnectionDialogz?Dialog to connect to existing kernels (either local or remote).Nc       	         sL  t tˆƒ |¡ ˆ tdƒ¡ ttdƒƒ}| d¡ | tj	¡ ttdƒƒ}t
ƒ ˆ_ˆj tdƒ¡ ˆj d¡ ttdƒƒ}|j ˆj¡ tƒ }| |¡ | ˆj¡ | |¡ ttdƒƒˆ_ttd	ƒƒ‰ ˆ  d¡ t
ƒ ˆ_ˆj td
ƒ¡ t
ƒ ˆ_ˆj tdƒ¡ ˆj t
j¡ t
ƒ ˆ_ˆj tdƒ¡ ttdƒƒ‰ˆj ˆj¡ tƒ }| ˆj¡ | ˆ¡ tƒ ‰ˆ tdƒˆj¡ ˆ tdƒˆj¡ ˆ tdƒ|¡ ttjtj B tj!ˆƒˆ_"ˆj"j# ˆj$¡ ˆj"j% ˆj&¡ t'ˆƒ}| |¡ | (|¡ | ˆj¡ | ˆ ¡ | (ˆ¡ | ˆj"¡ ‡ ‡‡‡fdd„}|ˆj )¡ ƒ ˆjj* |¡ d S )NzConnect to an existing kernelzèPlease select the JSON connection file (<i>e.g.</i> <tt>kernel-3764.json</tt>) or enter the 4-digit ID (<i>e.g.</i> <tt>3764</tt>) of the existing kernel to connect to, and enter the SSH host name and credentials if a remote kernel.TzKernel ID/Connection file:z$ID number or path to connection fileéú   ZBrowsez!This is a remote kernel (via SSH)z©<b>Note:</b> If connecting to a remote kernel, only the SSH keyfile <i>or</i> the Password field need to be completed, unless the keyfile is protected with a passphrase.zusername@hostname:portz.Remote user password or SSH keyfile passphrasezPath to SSH keyfile (optional)z
Host name:z	Password:zSSH keyfile:c                sZ   x&ˆ ˆj ˆjˆjˆgD ]}| | ¡ qW x,tˆ ¡ ƒD ]}ˆ d| ¡ ¡  | ¡ q6W d S )Né   )ÚhnÚpwÚkfÚ
setEnabledÚrangeZrowCountZitemAtÚwidget)ÚstateZwidr^   )Úcredential_labelÚkf_open_btnr[   Ússh_formr<   r=   Ússh_set_enabledö   s
    z8KernelConnectionDialog.__init__.<locals>.ssh_set_enabled)+Úsuperr`   Ú__init__ZsetWindowTitler   r   ÚsetWordWrapZsetAlignmentr	   ZAlignJustifyr   ÚcfZsetPlaceholderTextZsetMinimumWidthr   ZclickedÚconnectÚselect_connection_filer   Ú	addWidgetr   Úrm_cbrc   rd   ZsetEchoModeZPasswordre   Úselect_ssh_keyr   ZaddRowr   ÚOkZCancelÚ
HorizontalZaccept_btnsÚacceptedZacceptZrejectedZrejectr   Ú	addLayoutÚ
checkStateZstateChanged)	r[   ÚparentZ
main_labelZcf_labelZcf_open_btnZ	cf_layoutZ	kf_layoutÚlayoutrm   )Ú	__class__)rj   rk   r[   rl   r=   ro   ª   sf    









zKernelConnectionDialog.__init__c             C   s(   t | tdƒtƒ dƒd }| j |¡ d S )NzSelect kernel connection filez*.json;;*.*r   )r   r   r   rq   ÚsetText)r[   rq   r<   r<   r=   rs      s    
z-KernelConnectionDialog.select_connection_filec             C   s(   t | tdƒtƒ dƒd }| j |¡ d S )NzSelect SSH keyfilez
*.pem;;*.*r   )r   r   r!   re   r   )r[   re   r<   r<   r=   rv     s    
z%KernelConnectionDialog.select_ssh_keyc       	      C   sÄ   |st | ƒ}| ¡ }t|j ¡ ƒ}|tjk}|rjdd„ }|j ¡ ||j	 ¡ ƒ||j
 ¡ ƒ||j ¡ ƒ|fS |j ¡ }t |¡t |¡ }}|dkr²| d¡s²t tƒ d| d ¡}|d d d |fS d S )Nc             S   s   | r| S d S )Nr<   )Úargr<   r<   r=   Ú<lambda>  s    zBKernelConnectionDialog.get_connection_parameters.<locals>.<lambda>Ú z.jsonzkernel-)r`   Zexec_Úboolru   r{   r   ZAcceptedrq   Útextrc   re   rd   ÚospÚdirnameÚbasenameÚendswithÚjoinr   )	r|   ZdialogÚresultZ	is_remotery   Zfalsy_to_noneÚpathZ_dirÚfilenamer<   r<   r=   Úget_connection_parameters
  s"    

z0KernelConnectionDialog.get_connection_parameters)N)NN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ro   rs   rv   Ústaticmethodr   Ú__classcell__r<   r<   )r~   r=   r`   §   s   Vr`   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚIPythonConsoleConfigPagec             C   s   t  | ||¡ dd„ | _d S )Nc               S   s   t dƒS )NzIPython console)r   r<   r<   r<   r=   r   '  s    z3IPythonConsoleConfigPage.__init__.<locals>.<lambda>)r$   ro   Úget_name)r[   Zpluginr|   r<   r<   r=   ro   %  s    z!IPythonConsoleConfigPage.__init__c       M   	   C   s	  | j }ttdƒƒ}|tdƒdtdƒd}|tdƒdtdƒd}|td	ƒd
ƒ}|tdƒdƒ}|tdƒdtdƒd}|tdƒdƒ}|tdƒdtdƒd}	tƒ }
|
 |¡ |
 |¡ |
 |¡ |
 |¡ |
 |¡ |
 |¡ |
 |	¡ | |
¡ ttdƒƒ}ttdƒƒ}| d¡ tdƒdftdƒdftdƒdfg}|  tdƒd |d ¡}tƒ }| |¡ | |¡ | |¡ ttd!ƒƒ}| j	td"ƒtd#ƒd$d%d&d'td(ƒd)}tƒ }| |¡ | |¡ ttd*ƒƒ}|td+ƒd,ƒ}|td-ƒd.td/ƒd}| 
|  d,¡¡ |j |j
¡ tƒ }| |¡ | |¡ | |¡ td0ƒ}td1ƒ}ttd2ƒƒ}ttd3ƒ||f ƒ}| d¡ |df|dfd4d5g}tjd6krˆ| d7¡ tj d8¡rª| d9¡ | d:¡ trº| d;¡ | d<¡ t|ƒ}| jtd=ƒd |d>dtd?ƒd@}tƒ }| |¡ | |¡ | |¡ | 
|  d,¡¡ |j |j
¡ ttdAƒƒ}ttdBƒƒ}| d¡ dC} | jtdDƒd | dEddF}!| j	tdGƒdH dItdJƒ dKdLdMdNtdOƒd)}"| j	tdPƒdH dItdQƒ dRddSdtdTƒd)}#| j	tdUƒdH dItdQƒ dVddSdtdWƒd)}$|tdXƒdYtdZƒd}%tƒ }&|& |¡ tƒ }'|' |!jdd¡ |' |!jdd¡ |' |"jdd¡ |' |"jdd¡ |' |"jdd¡ |' |#jd[d¡ |' |#jd[d¡ |' |#jd[d¡ |' |$jd\d¡ |' |$jd\d¡ |' |$jd\d¡ |' |%d]ddd\¡ tƒ }(|( |'¡ |( d¡ |& |(¡ | |&¡ | 
|  d,¡¡ |j |j
¡ ttd^ƒƒ})ttd_ƒƒ}*|* d¡ | jtd`ƒdadbtjdc}+tƒ },|, |*¡ |, |+¡ |) |,¡ ttddƒƒ}-ttdeƒƒ}.|. d¡ |tdfƒdgdhƒ}/|   dbdidb¡}0|0 
dh¡ |/j |0j
¡ tƒ }1|1 |.¡ |1 |/¡ |1 |0¡ |- |1¡ ttdjƒƒ}2ttdkƒƒ}3|3 d¡ |tdlƒdmdnd}4tƒ }5|5 |3¡ |5 |4¡ |2 |5¡ ttdoƒƒ}6ttdpƒƒ}7|7 d¡ |tdqƒdrdsd}8tƒ }9|9 |7¡ |9 |8¡ |6 |9¡ ttdtƒƒ}:ttduƒƒ};|; d¡ tdvƒ}<tdwƒ}=tdxƒdf|<df|=dff}>| jtdyƒ|>dzdtd{ƒ|<|=f d@}?tƒ }@|@ |;¡ |@ |?¡ |: |@¡ ttd|ƒƒ}Attd}ƒƒ}B|B d¡ |td~ƒdtd€ƒd}Ctƒ }D|D |B¡ |D |C¡ |A |D¡ ttdƒƒ}Ettd‚ƒƒ}F|F d¡ | jtdƒƒd„dbtd…ƒtjdc}G| jtd†ƒd‡dbtdˆƒtjdc}Htƒ }I|I |F¡ tƒ }J|J |Gjdd¡ |J |Gj!dd¡ |J |Hjdd¡ |J |Hj!dd¡ |I |J¡ |E |I¡ t"ƒ }K|K #|  $|||¡td‰ƒ¡ |K #|  $|||¡tdŠƒ¡ |K #|  $|)|-¡td‹ƒ¡ |K #|  $|2|6|:|A|E¡tdŒƒ¡ tƒ }L|L |K¡ |  |L¡ d S )NZ	InterfacezDisplay initial bannerÚshow_bannerzWThis option lets you hide the message shown at
the top of the console when it's opened.)Útipz9Use a pager to display additional text inside the consoleÚ	use_pagerz}Useful if you don't want to fill the console with long help or completion texts.
Note: Use the Q key to get out of the pager.zDisplay balloon tipsÚshow_calltipsz#Ask for confirmation before closingÚask_before_closingz?Ask for confirmation before removing all user-defined variablesÚshow_reset_namespace_warningz]This option lets you hide the warning message shown
when resetting the namespace from Spyder.zShow elapsed timeÚshow_elapsed_timez&Ask for confirmation before restartingÚask_before_restartzOThis option lets you hide the warning message shown
when restarting the kernel.zCompletion Typez%Decide what type of completion to useTZ	Graphicalr   ZTerminalrD   ZPlainrb   zCompletion:z   Úcompletion_typezSource codez	Buffer:  z linesÚbuffer_sizerH   i@B éd   z|Set the maximum number of lines of text shown in the
console before truncation. Specifying -1 disables it
(not recommended!))Zmin_Zmax_Ústepr—   z!Support for graphics (Matplotlib)zActivate supportÚpylabz*Automatically load Pylab and NumPy moduleszpylab/autoloadz¶This lets you load graphics support without importing 
the commands to do plots. Useful to work with other
plotting libraries different to Matplotlib or to develop 
GUIs with Spyder.ZInlineZ	AutomaticzGraphics backendzÚDecide how graphics are going to be displayed in the console. If unsure, please select <b>%s</b> to put graphics inside the console or <b>%s</b> to interact with them (through zooming and panning) in a separate window.)ZQt5rb   )ZQt4é   Údarwin)zOS Xé   Zlinux)ZGtk3rB   )ZGtké   )ZWxé   )ZTkinteré   zBackend:zpylab/backendz>This option will be applied the next time a console is opened.)Údefaultr—   zInline backendz8Decide how to render the figures created by this backend))ZPNGr   )ZSVGrD   zFormat:zpylab/inline/figure_format)r©   zResolution:z  ú Zdpizpylab/inline/resolutioné2   iç  gš™™™™™¹?z/Only used when the format is PNG. Default is 72zWidth:Zincheszpylab/inline/widthé   zDefault is 6zHeight:zpylab/inline/heightzDefault is 4z#Use a tight layout for inline plotszpylab/inline/bbox_incheszªSets bbox_inches to "tight" when
plotting inline with matplotlib.
When enabled, can cause discrepancies
between the image displayed inline and
that created using savefig.r£   r¥   rB   zRun codez˜You can run several lines of code when a console is started. Please introduce each one separated by commas, for example:<br><i>import os, import sys</i>zLines:zstartup/run_linesr‚   )Z	alignmentz
Run a filezsYou can also run a whole file at startup instead of just some lines (This is similar to have a PYTHONSTARTUP file).zUse the following file:zstartup/use_run_fileFzstartup/run_filezJedi completionzÒEnable Jedi-based <tt>Tab</tt> completion in the IPython console; similar to the greedy completer, but without evaluating the code.<br><b>Warning:</b> Slows down your console when working with large dataframes!z*Use Jedi completion in the IPython consoleZjedi_completerzu<b>Warning</b>: Slows down your console when working with large dataframes!<br>Allows completion of nested lists etc.zGreedy completiona¨  Enable <tt>Tab</tt> completion on elements of lists, results of function calls, etc, <i>without</i> assigning them to a variable, like <tt>li[0].&lt;Tab&gt;</tt> or <tt>ins.meth().&lt;Tab&gt;</tt> <br><b>Warning:</b> Due to a bug, IPython's greedy completer requires a leading <tt>&lt;Space&gt;</tt> for some completions; e.g.  <tt>np.sin(&lt;Space&gt;np.&lt;Tab&gt;</tt> works while <tt>np.sin(np.&lt;Tab&gt; </tt> doesn't.z,Use greedy completion in the IPython consoleZgreedy_completerzd<b>Warning</b>: It can be unsafe because the code is actually evaluated when you press <tt>Tab</tt>.ZAutocallz¾Autocall makes IPython automatically call any callable object even if you didn't type explicit parentheses.<br>For example, if you type <i>str 43</i> it becomes <i>str(43)</i> automatically.ZSmartZFullZOffzAutocall:  Zautocallz½On <b>%s</b> mode, Autocall is not applied if there are no arguments after the callable. On <b>%s</b> mode, all callable objects are automatically called (even if no arguments are present).zSymbolic Mathematicsz°Perfom symbolic operations in the console (e.g. integrals, derivatives, vector calculus, etc) and get the outputs in a beautifully printed style (it requires the Sympy module).zUse symbolic mathÚsymbolic_mathznThis option loads the Sympy library to work with.<br>Please refer to its documentation to learn how to use it.ZPromptsz=Modify how Input and Output prompts are shown in the console.zInput prompt:Ú	in_promptzHDefault is<br>In [&lt;span class="in-prompt-number"&gt;%i&lt;/span&gt;]:zOutput prompt:Ú
out_promptzIDefault is<br>Out[&lt;span class="out-prompt-number"&gt;%i&lt;/span&gt;]:ZDisplayZGraphicsZStartupzAdvanced Settings)%Zcreate_checkboxr   r   r   rt   Ú	setLayoutr   rp   Zcreate_comboboxZcreate_spinboxrf   Ú
get_optionZtoggledrr   ÚsysÚplatformÚappendÚ
startswithr&   Útupler   ZlabelZcomboboxZplabelZspinboxZslabelr   rz   Z
addStretchZcreate_lineeditr	   rx   Zcreate_browsefileZtextboxr   ÚaddTabZ
create_tab)Mr[   ZnewcbZinterface_groupZ
banner_boxZ	pager_boxZcalltips_boxZask_boxZreset_namespace_boxZshow_time_boxZask_restart_boxZinterface_layoutZ
comp_groupZ
comp_labelZ
completersZcomp_boxZcomp_layoutZsource_code_groupZbuffer_spinZsource_code_layoutZpylab_groupZ	pylab_boxZautoload_pylab_boxZpylab_layoutZinlineZ	automaticZbackend_groupZ
bend_labelZbackendsZbackend_boxZbackend_layoutZinline_groupZinline_labelZformatsZ
format_boxZresolution_spinZ
width_spinZheight_spinZbbox_inches_boxZinline_v_layoutZinline_layoutZinline_h_layoutZrun_lines_groupZrun_lines_labelZrun_lines_editZrun_lines_layoutZrun_file_groupZrun_file_labelZ
file_radioZrun_file_browserZrun_file_layoutZ
jedi_groupZ
jedi_labelZjedi_boxZjedi_layoutZgreedy_groupZgreedy_labelZ
greedy_boxZgreedy_layoutZautocall_groupZautocall_labelZsmartZfullZautocall_optsZautocall_boxZautocall_layoutZsympy_groupZsympy_labelZ	sympy_boxZsympy_layoutZprompts_groupZprompts_labelZin_prompt_editZout_prompt_editZprompts_layoutZprompts_g_layoutZtabsZvlayoutr<   r<   r=   Ú
setup_page)  sÀ   









"




























































z#IPythonConsoleConfigPage.setup_pageN)rŽ   r   r   ro   r¸   r<   r<   r<   r=   r”   #  s   r”   c            	   @   sª  e Zd ZdZdZeZdZeƒ Z	ee
ee
fe
ee
efƒZe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†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-d.„Z#d/d0„ Z$e%ƒ e%eƒe%e
ƒe%ee
ƒe%eeƒe%ee
eƒdˆd2d3„ƒƒƒƒƒƒZ&e%ƒ d4d5„ ƒZ'd‰d6d7„Z(e%e)e)ƒd8d9„ ƒZ*d:d;„ Z+d<d=„ Z,d>d?„ Z-dŠd@dA„Z.d‹dBdC„Z/dDdE„ Z0dFdG„ Z1dHdI„ Z2dJdK„ Z3dLdM„ Z4dNdO„ Z5e%e
ƒdPdQ„ ƒZ6dŒdRdS„Z7dTdU„ Z8dVdW„ Z9dXdY„ Z:dd[d\„Z;dŽd]d^„Z<dd_d`„Z=dadb„ Z>dcdd„ Z?ddedf„Z@dgdh„ ZAdidj„ ZBdkdl„ ZCdmdn„ ZDdodp„ ZEdqdr„ ZFdsdt„ ZGe%ƒ dudv„ ƒZHe%ƒ dwdx„ ƒZIe%ƒ dydz„ ƒZJd{d|„ ZKd}d~„ ZLdd€„ ZMdd‚„ ZNdƒd„„ ZOdS )‘ÚIPythonConsoleza
    IPython Console plugin

    This is a widget with tabs where each one is a ClientWidget
    Úipython_consoleFzhThe directory {} is not writable and it is required to create IPython consoles. Please make it writable.Nc             C   sª  t rtj| ||d nt | |¡ d| _d| _d| _g | _g | _d| _d| _	|| _
|| _|  ¡  | j
dk	rŠt t |¡¡sŠt t |¡¡ tƒ }t| | jdddd| _t| jdƒrÈtjd	ksÈ| j d¡ | jj | j¡ | j ¡ j | j¡ | j ¡ j | j¡ | j  | j!¡ tjd	krZt"ƒ }| #d
¡ t$|ƒ}| %dddd¡ | &| j¡ | &|¡ n| &| j¡ t'| ƒ| _(| j( )¡  |  *| j(¡ | &| j(¡ |  +|¡ |  ,d¡ dS )zIpython Console constructor.)ÚmainNr   FTú/)Zrename_tabsZ
split_charZsplit_indexÚsetDocumentModer¤   ztab-container)-r   r#   ro   Ú	tabwidgetÚmenu_actionsÚmaster_clientsÚclientsÚ	filenamesÚmainwindow_closeÚcreate_new_client_if_emptyÚtest_dirÚtest_no_stderrZinitialize_pluginr…   Úisdirr‰   rQ   Úmakedirsr   r5   Úhasattrr²   r³   r½   ÚcurrentChangedrr   Úrefresh_pluginÚtabBarZtabMovedÚmove_tabZsig_change_nameÚrename_tabs_after_changeZset_close_functionÚclose_clientr   ZsetObjectNamer   ZsetContentsMarginsrt   r3   Úfind_widgetÚhideZregister_widget_shortcutsr°   ZsetAcceptDrops)r[   r|   rÅ   rÆ   r}   Ztab_containerZ
tab_layoutr<   r<   r=   ro   –  sR    






zIPythonConsole.__init__c             C   s&   |   ¡ }x| jD ]}| |¡ qW dS )zUpdate font from PreferencesN)Úget_plugin_fontrÁ   Úset_font)r[   ZfontÚclientr<   r<   r=   Úupdate_font×  s    zIPythonConsole.update_fontc             C   sê   d}|   ¡ }d}t dd¡}d}t dd¡}d}|  |¡}	d	}
|  |
¡}d
}|  |¡}xŽ| jD ]„}| ¡ }||kr|| |¡ ||kr–|dk	r–| |¡ ||kr¨| |¡ ||krÆ|j	 
|	¡ | |	¡ |
|krÔ||_||kr^||_q^W dS )z*Apply configuration file's plugin settingsZplugin_fontZconnect_to_oiÚhelpzconnect/ipython_consoleZcolor_scheme_nameÚcolor_schemesÚselectedrœ   r›   r   N)rÒ   r"   Úgetr±   rÁ   Úget_controlrÓ   Úset_help_enabledZset_color_schemeZshow_time_actionZ
setCheckedZset_elapsed_time_visibleÚreset_warningr   )r[   ÚoptionsZfont_nZfont_oZhelp_nZhelp_oZcolor_scheme_nZcolor_scheme_oZshow_time_nZshow_time_oZreset_namespace_nZreset_namespace_oZask_before_restart_nZask_before_restart_orÔ   Úcontrolr<   r<   r=   Úapply_plugin_settingsÝ  s6    






z$IPythonConsole.apply_plugin_settingsc             C   sP   |rB| j  ¡  | j  ¡  | jsL| jjr4| jdd qL| jdd n
| j  ¡  dS )zToggle viewF)Ú
give_focusTN)Ú
dockwidgetÚshowZraise_rÁ   r»   Úis_setting_upÚcreate_new_clientrÑ   )r[   Úcheckedr<   r<   r=   Útoggle_viewû  s    

zIPythonConsole.toggle_viewc             C   s   t dƒS )zReturn widget titlezIPython console)r   )r[   r<   r<   r=   Úget_plugin_title
  s    zIPythonConsole.get_plugin_titlec             C   s
   t  d¡S )zReturn widget iconrº   )ÚimaÚicon)r[   r<   r<   r=   Úget_plugin_icon  s    zIPythonConsole.get_plugin_iconc             C   s   | j  ¡ }|dk	r| ¡ S dS )zq
        Return the widget to give focus to when
        this plugin's dockwidget is raised on top-level
        N)r¾   ÚcurrentWidgetrÚ   )r[   rÔ   r<   r<   r=   Úget_focus_widget  s    
zIPythonConsole.get_focus_widgetc             C   s2   d| _ x&| jD ]}| ¡  | ¡  | ¡  qW dS )z3Perform actions before parent main window is closedT)rÃ   rÁ   ÚshutdownÚremove_stderr_fileÚclose)r[   Z
cancelablerÔ   r<   r<   r=   Úclosing_plugin  s    zIPythonConsole.closing_pluginc             C   sÂ   d}| j  ¡ r\| j  ¡ }| ¡ }| ¡  dd„ | ¡ D ƒ}t|g ƒdd… }| ¡ g| }nd}g }| j 	|¡ | j  
tj|i¡ |r¬|j}| jj t|ƒ¡ | jj |¡ |  ¡  | j ¡  dS )zRefresh tabwidgetNc             S   s   g | ]}|d g‘qS )iùÿÿÿr<   )Ú.0Úbr<   r<   r=   ú
<listcomp>,  s    z1IPythonConsole.refresh_plugin.<locals>.<listcomp>rH   )r¾   Úcountrë   rÚ   ÚsetFocusZget_toolbar_buttonsÚsumÚcreate_time_labelrÐ   Ú
set_editorZset_corner_widgetsr	   ZTopRightCornerÚshellwidgetr»   ÚvariableexplorerZset_shellwidget_from_idÚidrÖ   Ú	set_shellÚupdate_tabs_textÚupdate_plugin_titleÚemit)r[   rÔ   rÞ   ZbuttonsZwidgetsÚswr<   r<   r=   rË   $  s$    

zIPythonConsole.refresh_pluginc             C   sÔ   t | tdƒt d¡| jtjd}| j|ddd t | tdƒt d¡| jtjd}| j|ddd t | tdƒd	d	td
ƒ| j	d}t | tdƒt d¡| j
d}| jj}| d|¡ |t||g7 }|t||t|g| _| jS )z+Return a list of actions related to plugin.zOpen an &IPython consolerº   )ré   Ú	triggeredÚcontextzNew tab)r  ÚnamezRestart kernelÚrestartzConnect to an existing kernelNz:Open a new IPython console connected to an existing kernel)r  z
Rename tabÚrename)ré   r  r   )r*   r   rè   ré   rä   r	   ZWidgetWithChildrenShortcutZregister_shortcutÚrestart_kernelÚcreate_client_for_kernelÚtab_name_editorr»   Zconsoles_menu_actionsÚinsertr+   r¿   )r[   Zcreate_client_actionZrestart_actionZconnect_to_kernel_actionZrename_tab_actionZmain_consoles_menur<   r<   r=   Úget_plugin_actions;  s:    







z!IPythonConsole.get_plugin_actionsc                sô   ˆ j  ˆ ¡ ˆ j ˆ j j¡ ˆ j ˆ j jj¡ ˆ jtt	tt
f  ‡ fdd„¡ ˆ j jj ˆ j¡ ˆ j jj ˆ j¡ ˆ j jj ˆ j¡ ˆ jj ˆ j¡ ˆ j jj ˆ j¡ ˆ j jj ‡ fdd„¡ ˆ j jj ˆ j¡ ˆ j jj ‡ fdd„¡ ˆ  ¡  dS )z'Register plugin in Spyder's main windowc                s   ˆ j jj| |||dS )N)Úprocessevents)r»   ÚeditorÚload)ÚfnameÚlinenoZwordr  )r[   r<   r=   r   j  s    z0IPythonConsole.register_plugin.<locals>.<lambda>c          	      s   ˆ   | t | ¡ddddd¡S )Nr‚   FT)Ú
run_scriptr…   r†   )r  )r[   r<   r=   r   v  s   c          	      s   ˆ   | t | ¡ddddd¡S )Nr‚   FT)r  r…   r†   )r  )r[   r<   r=   r   z  s   N)r»   Zadd_dockwidgetÚfocus_changedrr   Zplugin_focus_changedÚ	edit_gotor  r  ÚstrrL   rƒ   Zbreakpoints_savedÚset_spyder_breakpointsZrun_in_current_ipyclientr  ÚworkingdirectoryZset_current_console_wdÚ$set_current_client_working_directoryr¾   rÊ   Úupdate_working_directoryZexplorerZopen_interpreterÚcreate_client_from_pathr:   ÚprojectsÚ_remove_old_stderr_files)r[   r<   )r[   r=   Úregister_pluginc  s"    


zIPythonConsole.register_pluginc             C   s   dd„ | j D ƒS )zReturn clients listc             S   s   g | ]}t |tƒr|‘qS r<   )Ú
isinstancer4   )rñ   Úclr<   r<   r=   ró   ‚  s    z.IPythonConsole.get_clients.<locals>.<listcomp>)rÁ   )r[   r<   r<   r=   Úget_clients€  s    zIPythonConsole.get_clientsc             C   s6   t  ¡ }x(|  ¡ D ]}||ks*|| ¡ kr|S qW dS )z(Return current client with focus, if anyN)r   ZfocusWidgetr  rÚ   )r[   rh   rÔ   r<   r<   r=   Úget_focus_client„  s    zIPythonConsole.get_focus_clientc             C   s   | j  ¡ }|dk	r|S dS )z$Return the currently selected clientN)r¾   rë   )r[   rÔ   r<   r<   r=   Úget_current_client‹  s    
z!IPythonConsole.get_current_clientc             C   s   |   ¡ }|dk	r|jS dS )z,Return the shellwidget of the current clientN)r   rù   )r[   rÔ   r<   r<   r=   Úget_current_shellwidget‘  s    z&IPythonConsole.get_current_shellwidgetc                sÐ  dd„ }t  |¡d dk}	|	r"d‰d}
ˆr4ˆ ¡ }n,ˆ |¡}|dkr`ˆj||	d ˆ ¡ }d}
|dk	r¨| ¡ dk	rÌd	|r€d
nd||ƒf ‰|r¢ˆd||ƒ 7 ‰|r¶ˆd||ƒ 7 ‰|rÂˆd7 ‰ˆd7 ‰n6d‰|rÜˆd7 ‰ˆdt|ƒ 7 ‰|rˆd||ƒ 7 ‰y„|jjrnt|jj	r2|jj
tdƒdd dS ˆrHˆ ˆˆˆ ¡ n<|
r\|j d¡ n|j d¡ |jj ‡ ‡‡‡fdd„¡ W n tk
rœ   Y nX ˆ ¡  n$t ˆtdƒtdƒt  |¡ tj¡ dS )z)Run script in current or dedicated clientc             S   s   t t| ƒƒS )N)r2   r'   )r„   r<   r<   r=   r   š  s    z+IPythonConsole.run_script.<locals>.<lambda>rD   z.pyxFN)Ú	is_cythonTz%s('%s'Z	debugfileZrunfilez, args='%s'z, wdir='%s'z, post_mortem=TruerC   z%run z-d z"%s"z %sz[<br><b>Please exit from debugging before trying to run a file in this console.</b>
<hr><br>)Zbefore_promptz%clearc                  s   ˆ  ˆˆˆ ¡S )N)Úexecute_coder<   )Úclear_variablesÚcurrent_clientÚliner[   r<   r=   r   Ô  s   rI   zgNo IPython console is currently available to run <b>%s</b>.<br><br>Please open a new one and try again.)r…   Úsplitextr   Úget_client_for_fileÚcreate_client_for_fileÚ
get_kernelr'   rù   Z
_executingÚ_readingZ_append_htmlr   r#  Zsilent_executeÚexecuteÚsig_prompt_readyrr   ÚAttributeErrorÚswitch_to_pluginr   Úwarningr‡   rw   )r[   rŒ   ZwdirÚargsÚdebugZpost_mortemr%  r$  Znormr"  Zis_new_clientrÔ   r<   )r$  r%  r&  r[   r=   r  —  sd    






zIPythonConsole.run_scriptc             C   s   |   ¡ }|dk	r| |¡ dS )z%Set current client working directory.N)r!  Úset_cwd)r[   Z	directoryrù   r<   r<   r=   r  à  s    z3IPythonConsole.set_current_client_working_directoryc             C   s   |r| j jj|ddd dS )z]Set current working directory.
        In the workingdirectory and explorer plugins.
        TF)Zrefresh_explorerZrefresh_consoleN)r»   r  Úchdir)r[   r†   r<   r<   r=   Úset_working_directoryæ  s    z$IPythonConsole.set_working_directoryc             C   s   |   ¡ }|dk	r| ¡  dS )z(Update working directory to console cwd.N)r!  Úget_cwd)r[   rù   r<   r<   r=   r  î  s    z'IPythonConsole.update_working_directoryTc             C   sª   |   ¡ }|dk	r¦|jrnv|sPy|j ¡  W n tk
r>   Y nX |jddd n|rf|rf|jddd y| t|ƒ¡ W n tk
rŒ   Y nX |  	¡  |  
¡  ¡  ¡  dS )zExecute code instructions.NFT)r0  Zsilent)r!  r+  r-  Ú
disconnectÚ	TypeErrorZreset_namespacer,  r'   r.  ÚactivateWindowr   rÚ   rõ   )r[   Úlinesr%  r$  r   r<   r<   r=   r#  ô  s$    zIPythonConsole.execute_codec             C   s8   |   ¡ }|d k	r4y| |¡ W n tk
r2   Y nX d S )N)r!  Úwrite_to_stdinr.  )r[   r&  r   r<   r<   r=   r;    s    zIPythonConsole.write_to_stdinr‚   c             C   s,  |  j d7  _ tt| j ƒdd}|  ¡ }|  d¡}|  d¡}|  d¡}t| |tdƒ|  ¡ |  ¡ |  	¡ || j
|||d}	| jd	k	rˆ| j|	_| j|	|	 ¡ |d
 |d	krÀ| j tƒ ¡}
|	 |
¡ d	S t dd¡sþt dd¡}tjd|dd}|sþ|	 tdƒ¡ d	S | j|	|d |	jjd	krd	S |  |	¡ d	S )zCreate a new clientrD   ÚA)Úint_idÚstr_idrœ   r›   r   z
history.py)
Úid_Úhistory_filenameÚconfig_optionsÚadditional_optionsÚinterpreter_versionsÚconnection_filer¿   rœ   rÜ   r   N)r  rŒ   Úmain_interpreterr©   Ú
executableZspyder_kernelsz<1.0.0)ZinterpreterÚversionao  Your Python environment or installation doesn't have the <tt>spyder-kernels</tt> module or the right version of it installed. Without this module is not possible for Spyder to create a console for you.<br><br>You can install it by running in a system terminal:<br><br><tt>conda install spyder-kernels=0.*</tt><br><br>or<br><br><tt>pip install spyder-kernels==0.*</tt>)r"  )rÀ   Údictr'   Ú_new_connection_filer±   r4   r    rA  rB  rC  r¿   rÅ   Ú
stderr_dirÚadd_tabr•   Úpermission_error_msgÚformatr   Úshow_kernel_errorr"   rÙ   r.   Zis_module_installedr   Úconnect_client_to_kernelrù   Úkernel_managerÚregister_client)r[   rà   rŒ   r"  Ú	client_idrq   rœ   rÜ   r   rÔ   Ú	error_msgÚpyexecZhas_spyder_kernelsr<   r<   r=   rä     sL    







z IPythonConsole.create_new_clientc             C   s4   t  | ¡}|\}}}}}|s dS |  ||||¡ dS )z/Create a client connected to an existing kernelN)r`   r   Ú_create_client_for_kernel)r[   Zconnect_outputrD  ÚhostnameÚsshkeyr\   Úokr<   r<   r=   r  Y  s    

z'IPythonConsole.create_client_for_kernelc                s¤   |j }ˆ jrdn|j}ˆ j|||d\}}t|ƒrP|dkrPd|j_| |¡ dS |j 	|f‡ fdd„	¡ |j
 	|f‡ fdd„	¡ |jddd |j}||_||_dS )zConnect a client to its kernelN)r"  c                s
   ˆ   | ¡S )N)Úprocess_started)Úc)r[   r<   r=   r   s  s    z9IPythonConsole.connect_client_to_kernel.<locals>.<lambda>c                s
   ˆ   | ¡S )N)Úprocess_finished)rZ  )r[   r<   r=   r   t  s    T)ÚshellZiopub)rD  rÆ   Ústderr_handleÚ'create_kernel_manager_and_kernel_clientr%   rù   rP  rN  Zstarted_channelsrr   Ústopped_channelsÚstart_channelsÚkernel_client)r[   rÔ   r"  rD  r]  ZkmÚkcrù   r<   )r[   r=   rO  d  s     
z'IPythonConsole.connect_client_to_kernelc             C   s   t  |¡r| j |dd¡ dS )zHandle %edit magic petitions.rD   r‚   N)r-   Zis_text_filer  rÿ   )r[   rŒ   r&  r<   r<   r=   Ú	edit_file{  s    
zIPythonConsole.edit_filec             C   s
  y t dgtƒ ƒ}td|jiƒ}W n   tƒ }Y nX tƒ }d|j_|  d¡}ddddœ}|| |j_|  d	¡}|r|d
|j_nd|j_|  d¡}||j_|  d¡}||j_	|  d¡}	|  d¡}
|	rÈ|	|j_
|
rÔ|
|j_t dd¡}t|ƒd }||j_||j_| |¡ |S )z¤
        Generate a Trailets Config instance for shell widgets using our
        config system

        This lets us create each widget with its own config
        zjupyter_qtconsole_config.pyÚJupyterWidgetZrichrž   ZdroplistZncursesZplain)r   rD   rb   r˜   ZinsideZnoner™   rŸ   r®   r¯   r×   rØ   r   )r   r   r   rd  Zkindr±   Zgui_completionZpagingZenable_calltipsrŸ   r®   r¯   r"   rÙ   r)   Ústyle_sheetZsyntax_styleZ_merge)r[   Zfull_cfgZcfgZspy_cfgZcompletion_type_oZcompletionsZpager_oZ
calltips_oZbuffer_size_oZin_prompt_oZout_prompt_oZcolor_schemere  r<   r<   r=   rA  ƒ  s>    







zIPythonConsole.config_optionsc          	   C   sÜ   t  dd¡r8ddlm} ttj d¡d  ¡ |jd}n ddl	}i }t  dd¡}d	| }d
| }xv||gD ]j}yt
 |¡}| ¡ \}	}
W n |jk
r¢   d}	Y nX |	 ¡  d¡d  ¡ }	d|krÌ|	|d< qj|	|d< qjW |S )z+Python and IPython versions used by clientsrE  r©   r   )ÚreleaseÚ
)Úpython_versionÚipython_versionNrF  z5%s -c 'import sys; print(sys.version.split("\n")[0])'z:%s -c 'import IPython.core.release as r; print(r.version)'r‚   r8   ri  rh  )r"   rÙ   ZIPython.corerf  rH  r²   rG  rK   ÚstripÚ
subprocessr.   Zrun_shell_commandZcommunicateZCalledProcessErrorÚdecode)r[   rf  Zversionsrk  rT  Zpy_cmdZipy_cmdr;   Úprocr]   Z_errr<   r<   r=   rC  Â  s.    


z#IPythonConsole.interpreter_versionsc             C   s,   t |  d¡|  d¡|  d¡|  d¡d}|S )zs
        Additional options for shell widgets that are not defined
        in JupyterWidget config options
        r¢   zpylab/autoloadr­   r–   )r¢   Zautoload_pylabr6   r–   )rH  r±   )r[   rÝ   r<   r<   r=   rB  à  s    z!IPythonConsole.additional_optionsc                sÆ  |j |d |j}|j}|j}|j ˆ j¡ |j ˆ j¡ |j |f‡ fdd„	¡ |j	 ˆ j
¡ d}t dd¡r tƒ }ˆ jjdk	r¸ˆ jj ¡ dk	r¸ˆ jj ¡ }nt dd¡r¸t dd	¡}t |¡râˆ jdk	râ| |¡ |râ| ¡  ˆ jjdk	r| ˆ jj¡ | t d
d¡¡ ˆ jjdk	r@ˆ jj |j¡ |j ˆ jjj¡ | ˆ  ¡ ¡ |j ‡ fdd„¡ |j  ˆ j!¡ ˆ j" #|¡ |rÂ|j ‡ fdd„¡ |j$ ˆ j%¡ |j$ ˆ j%¡ |j& ˆ j"j'¡ dS )zRegister new client)rà   c                s   ˆ   | ||¡S )N)Úpdb_has_stopped)r  r  rù   )r[   r<   r=   r   þ  s    z0IPythonConsole.register_client.<locals>.<lambda>r‚   Z
workingdirz%console/use_project_or_home_directoryNzconsole/use_fixed_directoryzconsole/fixed_directoryrÖ   zconnect/ipython_consolec                  s
   ˆ j  ¡ S )N)r  rÿ   r<   )r[   r<   r=   r   #  s    c                  s
   ˆ j  ¡ S )N)r  rÿ   r<   )r[   r<   r=   r   +  s    )(Zconfigure_shellwidgetrù   Ú_controlZ_page_controlZ
new_clientrr   rä   Úgo_to_errorZsig_pdb_stepZcustom_edit_requestedrc  r"   rÙ   r!   r»   r  Zget_active_projectZget_active_project_pathr…   rÇ   r3  r6  rÖ   Zset_helprÛ   Z
historylogZadd_historyr@  Zappend_to_historyrÓ   rÒ   r  Zsig_change_cwdr5  rÐ   rø   Zvisibility_changedrË   Zshow_find_widgetrâ   )r[   rÔ   rà   rù   rÞ   Zpage_controlZcwd_pathr<   )r[   r=   rQ  î  sJ    
zIPythonConsole.register_clientc          	   C   sø  | j  ¡ sdS |dk	r.| j  |¡}|dkr.dS |dkrH|dkrH| j  ¡ }|dk	r\| j  |¡}y| ¡  W n tk
r|   Y nX y|jj 	|j
¡ W n ttfk
rª   Y nX | jsH|sHd}|  d¡röt | |  ¡ tdƒtjtjB ¡}|tjkrödS t|  |¡ƒdkr*t | |  ¡ tdƒtjtjB ¡}| ¡  |tjkrH|  |¡ |  |¡}t|ƒdkrvt |j¡rv| ¡  | ¡  | j  | j  |¡¡ | j |¡ y| j  !|¡ W n t"k
rÄ   Y nX |  #¡  | j  ¡ sê| j$rê|  %¡  | j& '¡  dS )z<Close client tab from index or widget (or close current tab)NrH   Trš   z"Do you want to close this console?r   zQDo you want to close all other consoles connected to the same kernel as this one?)(r¾   rô   ÚindexOfÚcurrentIndexrh   Zstop_button_click_handlerrX   ÚtimerrF   r7  Ú	show_timer8  rÃ   r±   r   rU   rç   r   rV   rW   ÚlenÚget_related_clientsrí   Úclose_related_clientsr…   ÚexistsZstderr_filerî   rï   Z	removeTabrÁ   ÚremoverÂ   rT   Ú
IndexErrorrý   rÄ   rä   rþ   rÿ   )r[   ÚindexrÔ   ÚforceZ	close_allrï   Úrelated_clientsr<   r<   r=   rÏ   0  s^    





zIPythonConsole.close_clientc             C   s,   x&t | jƒD ]\}}t|ƒ|kr|S qW dS )zReturn client index from idN)Ú	enumeraterÁ   rû   )r[   rR  r{  rÔ   r<   r<   r=   Úget_client_index_from_idz  s    z'IPythonConsole.get_client_index_from_idc             C   s8   g }x.|   ¡ D ]"}|j|jkr||k	r| |¡ qW |S )zY
        Get all other clients that are connected to the same kernel as `client`
        )r  rD  r´   )r[   rÔ   r}  r  r<   r<   r=   rv  €  s    z"IPythonConsole.get_related_clientsc             C   s*   |   |¡}x|D ]}| j|dd qW dS )z4Close all clients related to *client*, except itselfT)rÔ   r|  N)rv  rÏ   )r[   rÔ   r}  r  r<   r<   r=   rw  ‹  s    

z$IPythonConsole.close_related_clientsc             C   s¢   d| _ d| _x~tt| jƒƒD ]l}| jd }y| ¡  W nB tk
rx } z$t | t	dƒt	dƒ 
|¡tj¡ W dd}~X Y nX | j|dd qW | jdd	 d| _dS )
z
        Restart the console

        This is needed when we switch projects to update PYTHONPATH
        and the selected interpreter
        r   FrH   rI   ztIt was not possible to restart the IPython console when switching to this project. The error was<br><br><tt>{0}</tt>NT)rÔ   r|  )rà   )rÀ   rÄ   rg   ru  rÁ   rí   Ú	Exceptionr   r0  r   rM  rw   rÏ   rä   )r[   r^   rÔ   Úer<   r<   r=   r  ‘  s    
zIPythonConsole.restartc             C   s4   | j ttttf  ||dd¡ |  ¡  |j ¡  dS )z9Python debugger has just stopped at frame (fname, lineno)r‚   FN)r  r  rL   rƒ   rÿ   r9  ro  rõ   )r[   r  r  rù   r<   r<   r=   rn  §  s    zIPythonConsole.pdb_has_stoppedc             C   s   x| j D ]}|j ¡  qW dS )z'Set Spyder breakpoints into all clientsN)rÁ   rù   r  )r[   r  r<   r<   r=   r  °  s    z%IPythonConsole.set_spyder_breakpointsc             C   s   |   ¡  |  ¡ }| |¡ dS )z.Create a client with its cwd pointing to path.N)rä   r!  r3  )r[   r‹   r   r<   r<   r=   r  µ  s    z&IPythonConsole.create_client_from_pathc             C   sD   | j ||d |  jd8  _|  ¡ }d|_|  |¡}|  ||¡ dS )z2Create a client to execute code related to a file.)rŒ   r"  rD   FN)rä   rÀ   r   Úallow_renameÚdisambiguate_fnameÚrename_client_tab)r[   rŒ   r"  rÔ   Ztab_textr<   r<   r=   r)  ¼  s    
z%IPythonConsole.create_client_for_filec             C   sB   d}x8t |  ¡ ƒD ](\}}| j| |kr| j |¡ |}P qW |S )z(Get client associated with a given file.N)r~  r  rÂ   r¾   ÚsetCurrentIndex)r[   rŒ   rÔ   Úidxr  r<   r<   r=   r(  Ê  s    z"IPythonConsole.get_client_for_filec             C   sT   |   |¡}xD|D ]<}|jdk	r| ¡  |j|_|jj |j¡ |j d¡ P qW dS )z#Set elapsed time for slave clients.Niè  )rv  rs  r÷   Zt0rF   rr   rt  Ústart)r[   rÔ   r}  r  r<   r<   r=   Úset_elapsed_timeÔ  s    


zIPythonConsole.set_elapsed_timec             O   s*   t jdkrtj||ŽS t| f|ž|ŽS d S )NÚnt)rQ   r  Ú	zmqtunnelZparamiko_tunnelr_   )r[   r1  Úkwargsr<   r<   r=   Ú
ssh_tunnelà  s    
zIPythonConsole.ssh_tunnelé
   c          
   C   sd   t  d¡}|d |d |d |d f}|d }x,t||ƒD ]\}	}
|  |	|
|||||¡ q:W t|ƒS )zx
        Tunnel connections to a kernel via ssh.

        Remote ports are specified in the connection info ci.
        r¥   Ú
shell_portÚ
iopub_portÚ
stdin_portÚhb_portÚip)rŠ  Zselect_random_portsÚziprŒ  r¶   )r[   Úconnection_inforV  rW  r\   rF   ZlportsZrportsZ	remote_ipZlpZrpr<   r<   r=   Útunnel_to_kernelæ  s    

zIPythonConsole.tunnel_to_kernelc             C   s   t  dd| j ¡ ¡ t|dS )z(Create a kernel spec for our own kernelsr»   Zspyder_pythonpath)r"  )r"   Úsetr»   Zget_spyder_pythonpathr(   )r[   r"  r<   r<   r=   Úcreate_kernel_specö  s    z!IPythonConsole.create_kernel_specc             C   s¤   | j |d}yt|ddd}W n* tk
rH   tdƒ t ¡ ¡}|dfS X ||_y|j|d W n* tk
rŠ   tdƒ t ¡ ¡}|dfS X | 	¡ }d|j
_||fS )z!Create kernel manager and client.)r"  NT)rD  ZconfigZautorestartz The error is:<br><br><tt>{}</tt>)Ústderrg      2@)r—  r   r€  r   rM  Ú	tracebackÚ
format_excZ_kernel_specZstart_kernelrÔ   Z
hb_channelZtime_to_dead)r[   rD  r]  r"  Zkernel_specrP  rS  ra  r<   r<   r=   r^  þ  s$    



z6IPythonConsole.create_kernel_manager_and_kernel_clientc             C   s$   |   ¡ }|dk	r |  ¡  | ¡  dS )z!Restart kernel of current client.N)r   r/  r  )r[   rÔ   r<   r<   r=   r  !  s    zIPythonConsole.restart_kernelc                sh   |‰|j }ˆ jjdk	r$ˆ jj ˆ¡ ˆ jjdk	rdˆ jj ˆ¡ ˆ ¡  ˆ ¡  |j 	‡ ‡fdd„¡ dS )zq
        Connect an external kernel to the Variable Explorer and Help, if
        it is a Spyder kernel.
        Nc                  s   ˆ j j tˆƒ¡S )N)r»   rú   Úremove_shellwidgetrû   r<   )r[   r   r<   r=   r   5  s    z8IPythonConsole.connect_external_kernel.<locals>.<lambda>)
ra  r»   rÖ   rü   rú   Úadd_shellwidgetZset_namespace_view_settingsZrefresh_namespacebrowserr_  rr   )r[   rù   rb  r<   )r[   r   r=   Úconnect_external_kernel(  s    z&IPythonConsole.connect_external_kernelc             C   sj   | j  |¡ | j ||¡}| j ||¡ | j |¡ | jrJ| jj	sJ|  
¡  |  ¡  | ¡  ¡  |  ¡  dS )zAdd tabN)rÁ   r´   r¾   r·   rÂ   r	  r…  rá   r»   rã   r/  r9  rÚ   rõ   rý   )r[   rh   r  rŒ   r{  r<   r<   r=   rK  9  s    zIPythonConsole.add_tabc             C   sJ   | j  |¡}| j |¡}| j  ||¡ | j ||¡ |  ¡  | j ¡  dS )zU
        Move tab (tabs themselves have already been moved by the tabwidget)
        N)rÂ   rT   rÁ   r	  rý   rþ   rÿ   )r[   Z
index_fromZindex_torŒ   rÔ   r<   r<   r=   rÍ   E  s    zIPythonConsole.move_tabc             C   s   dd„ | j D ƒ}t ||¡S )z)Generate a file name without ambiguation.c             S   s   g | ]}|r|‘qS r<   r<   )rñ   rŒ   r<   r<   r=   ró   R  s    z5IPythonConsole.disambiguate_fname.<locals>.<listcomp>)rÂ   r/   rƒ  )r[   r  Zfiles_path_listr<   r<   r=   rƒ  P  s    z!IPythonConsole.disambiguate_fnamec             C   sd   yJxDt | jƒD ]6\}}| j| }|r8|  ||  |¡¡ q|  |d¡ qW W n tk
r^   Y nX dS )zUpdate the text from the tabs.N)r~  rÂ   rÁ   r„  rƒ  rz  )r[   r{  r  rÔ   r<   r<   r=   rý   V  s    
zIPythonConsole.update_tabs_textc             C   s2   |   t|ƒ¡}|dk	r||_| j || ¡ ¡ dS )zRename client's tabN)r  rû   Ú
given_namer¾   Z
setTabTextr•   )r[   rÔ   rž  r{  r<   r<   r=   r„  e  s    z IPythonConsole.rename_client_tabc             C   s    |   ¡ }d}x0|  ¡ D ]$}t|ƒt|ƒkr||jkrd}P qW |jr^d|kr^|s^|  ||¡ n|  |d¡ |jrœd|krœ|sœx|  |¡D ]}|  ||¡ qˆW dS )z#Rename tabs after a change in name.FTr¼   N)r   r  rû   rž  r‚  r„  rv  )r[   rž  rÔ   Zrepeatedr  r<   r<   r=   rÎ   m  s    z'IPythonConsole.rename_tabs_after_changec             C   s    | j  ¡ }| j  ¡ j |¡ dS )zTrigger the tab name editor.N)r¾   rr  rÌ   r  Zedit_tab)r[   r{  r<   r<   r=   r  „  s    
zIPythonConsole.tab_name_editorc             C   s:   t t|ƒƒ}|r6| ¡ \}}| j t |¡t|ƒd¡ dS )zGo to error if relevantr‚   N)r1   r'   Úgroupsr  rÿ   r…   ÚabspathrL   )r[   r„   Úmatchr  Zlnbr<   r<   r=   rp  Š  s    zIPythonConsole.go_to_errorc             C   s   ddl m} | jj |¡ dS )zShow intro to IPython helpr   )Úinteractive_usageN)ÚIPython.core.usager¢  r»   rÖ   Úshow_rich_text)r[   r¢  r<   r<   r=   Ú
show_intro‘  s    zIPythonConsole.show_introc             C   s"   ddl m} | jjj|dd dS )zShow qtconsole helpr   )Úgui_referenceT)ZcollapseN)Zqtconsole.usager¦  r»   rÖ   r¤  )r[   r¦  r<   r<   r=   Úshow_guiref—  s    zIPythonConsole.show_guirefc             C   s   ddl m} | jj |¡ dS )zShow IPython Cheat Sheetr   )Úquick_referenceN)r£  r¨  r»   rÖ   Zshow_plain_text)r[   r¨  r<   r<   r=   Úshow_quickref  s    zIPythonConsole.show_quickrefc          	   C   s†   t  tƒ ¡s6yt tƒ ¡ W n ttfk
r4   dS X d}xF|s€tt 	¡ ƒ 
d¡d }tj tƒ d| ¡}tj |¡sz|nd}q<W |S )z‰
        Generate a new connection file

        Taken from jupyter_client/console_app.py
        Licensed under the BSD license
        Nr‚   ú-rH   zkernel-%s.json)r…   rÇ   r   rQ   rÈ   ÚIOErrorÚOSErrorr  ÚuuidZuuid4rK   r‹   r‰   rx  )r[   rq   Zidentr<   r<   r=   rI  ¤  s    z#IPythonConsole._new_connection_filec             C   s<   | j jd k	r| j j |j¡ | j jd k	r8| j j |j¡ d S )N)r»   rÖ   rü   rù   rú   rœ  )r[   rÔ   r<   r<   r=   rY  ¸  s    zIPythonConsole.process_startedc             C   s$   | j jd k	r | j j t|jƒ¡ d S )N)r»   rú   r›  rû   rù   )r[   rÔ   r<   r<   r=   r[  ¾  s    zIPythonConsole.process_finishedc             C   s˜  y0t  |¡}t  |¡}|r|nd }t||d}W n2 ttfk
rb   t | tdƒtdƒ| ¡ d S X d }d }d}	t	dƒd }
d }xf|  
¡ D ]Z}||jkrŠ| ¡ d k	r¬| ¡ }|j}|d krÄ|jd }|j}t	|jd ƒ}||
krŠ|}
qŠW |d kr|  jd7  _t| jƒ}d	}	t|t|
d ƒd
}|  d¡}|  d¡}|  d¡}t| ||tdƒ|  ¡ |  ¡ |  ¡ || j||	d	|||d}| jd k	rŒ| j|_t|d}| ¡  |d k	r0yDt|j|j|j |j!|j"d}|  #||||¡}|\|_|_ |_!|_"W nB t$k
r. } z"t | tdƒtdƒt|ƒ ¡ d S d }~X Y nX | %¡  ||j&_'||j&_(|	rh|j&j) *| j+¡ |j& ,¡  |	sx|  -|¡ | j.|| /¡ d |  0|¡ d S )N)rŒ   r‹   r8   zUnable to connect to <b>%s</b>Fr<  rD   r=  r>  T)r=  r>  rœ   r›   r   z
history.py)r?  rž  r@  rA  rB  rC  rD  r¿   rV  Úexternal_kernelZslaverœ   rÜ   r   )rD  )r’  rŽ  r  r  r‘  zConnection errorz+Could not open ssh tunnel. The error was:

)r  )1r…   r†   r‡   r   r«  ÚUnboundLocalErrorr   Zcriticalr   Úordr  rD  r*  r?  rž  rÀ   r'   rH  Úchrr±   r4   r    rA  rB  rC  r¿   rÅ   rJ  r   Zload_connection_filer’  rŽ  r  r  r‘  r•  r€  r`  rù   ra  rP  Zsig_is_spykernelrr   r  Zis_spyder_kernelrˆ  rK  r•   rQ  )r[   rD  rV  rW  r\   Zcf_pathZcf_filenameZ	master_idrž  r®  Z	slave_ordrP  r  Znew_slave_ordrR  rœ   rÜ   r   rÔ   ra  r”  Znewportsr  r<   r<   r=   rU  Ã  s¢    













z(IPythonConsole._create_client_for_kernelc          	   C   sf   t jdkrbtƒ }xPt  |¡D ]B}t |¡d dkryt  t ||¡¡ W q tk
r\   Y qX qW dS )zÀ
        Remove stderr files left by previous Spyder instances.

        This is only required on Windows because we can't
        clean up stderr files while Spyder is running on it.
        r‰  rD   z.stderrN)	rQ   r  r0   Úlistdirr…   r'  ry  r‰   r€  )r[   Ztmpdirr  r<   r<   r=   r  3  s    
z'IPythonConsole._remove_old_stderr_files)NF)F)TF)Tr‚   F)F)T)NNF)F)NNr  )F)F)r‚   )PrŽ   r   r   r‘   ZCONF_SECTIONr”   ZCONFIGWIDGET_CLASSZDISABLE_ACTIONS_WHEN_HIDDENr
   r  r  rL   rƒ   r  r   rL  ro   rÕ   rß   ræ   rç   rê   rì   rð   rË   r
  r  r  r  r   r!  r  r  r5  r  r#  r;  r   rä   r  rO  Úobjectrc  rA  rC  rB  rQ  rÏ   r  rv  rw  r  rn  r  r  r)  r(  rˆ  rŒ  r•  r—  r^  r  r  rK  rÍ   rƒ  rý   r„  rÎ   r  rp  r¥  r§  r©  rI  rY  r[  rU  r  r<   r<   r<   r=   r¹   ƒ  s˜   
A	
	(I


:
?
B
J	

 



!
pr¹   )r?   NNr@   )er‘   rN   rQ   Úos.pathr‹   r…   r­  r²   r™  Zjupyter_client.connectr   Zjupyter_core.pathsr   r   Zqtconsole.clientr   Zqtconsole.managerr   Zqtpyr   Zqtpy.compatr   Zqtpy.QtCorer	   r
   r   Zqtpy.QtWidgetsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Ztraitlets.config.loaderr   r   Zzmq.sshr   rŠ  r9   rJ   Zspyderr   Zspyder.config.baser   r    r!   Zspyder.config.mainr"   Zspyder.pluginsr#   Zspyder.plugins.configdialogr$   Zspyder.py3compatr%   r&   r'   Zspyder.utils.ipython.kernelspecr(   Zspyder.utils.ipython.styler)   Zspyder.utils.qthelpersr*   r+   Zspyder.utilsr,   rè   r-   r.   r/   Zspyder.utils.programsr0   Zspyder.utils.miscr1   r2   Zspyder.widgets.findreplacer3   Zspyder.widgets.ipythonconsoler4   Zspyder.widgets.tabsr5   ZSYMPY_REQVERÚaddZCYTHON_REQVERZQTCONSOLE_REQVERZIPYTHON_REQVERZMATPLOTLIB_REQVERr>   r_   r`   r”   r¹   r<   r<   r<   r=   Ú<module>	   sv   D



 
J|  b