B
    j]\A                 @   sh   d Z ddlZddlmZ ddlZddlZddlmZ ej	d dkZ
ddddd	gZd
ZG dd deZdS )z
Spyder kernel for Jupyter
    N)IPythonKernel2ZInZOutexitget_ipythonquit   c                   sh  e Zd ZdZ fddZedd Zedd Zdd	 Zd
d Z	dTd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dUd d!Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ ZdVd0d1Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dWdLdMZ)dNdO Z*dPdQ Z+dRdS Z,  Z-S )XSpyderKernelzSpyder kernel for Jupyterc                s4   t t| j|| i | _d | _d | _d| _d | _d S )NT)superr   __init__namespace_view_settings_pdb_obj	_pdb_step_do_publish_pdb_state_mpl_backend_error)selfargskwargs)	__class__ <lib/python3.7/site-packages/spyder_kernels/console/kernel.pyr
   $   s    zSpyderKernel.__init__c             C   s"   | j dk	r| j jdk	r| j jS dS )z(Return current Pdb frame if there is anyN)r   Zcurframe)r   r   r   r   
_pdb_frame.   s    zSpyderKernel._pdb_framec             C   s   | j r| jjS i S dS )zl
        Return current Pdb frame locals if available. Otherwise
        return an empty dictionary
        N)r   r   Zcurframe_locals)r   r   r   r   _pdb_locals4   s    zSpyderKernel._pdb_localsc             C   s>   ddl m} | j}|r2|  }t|||t}|S tdS dS )a  
        Return the namespace view

        This is a dictionary with the following structure

        {'a': {'color': '#800000', 'size': 1, 'type': 'str', 'view': '1'}}

        Here:
        * 'a' is the variable name
        * 'color' is the color used to show it
        * 'size' and 'type' are self-evident
        * and'view' is its value or the text shown in the last column
        r   )make_remote_viewN)spyder_kernels.utils.nsviewr   r   _get_current_namespacereprEXCLUDED_NAMES)r   r   settingsnsZviewr   r   r   get_namespace_viewA   s    zSpyderKernel.get_namespace_viewc             C   s   ddl m} | j}|r|  }|||dtd}i }xnt| D ]^\}}t|ttft|t	| 
|| || || || || || |d	||< q@W t|S tdS dS )zW
        Get some properties of the variables in the current
        namespace
        r   )get_remote_dataZeditable)modemore_excluded_names)	Zis_listZis_dictlenZis_arrayZis_imageZis_data_frameZ	is_seriesZarray_shapeZ
array_ndimN)r   r    r   r   r   listitems
isinstancetupledict_get_len	_is_array	_is_image_is_data_frame
_is_series_get_array_shape_get_array_ndimr   )r   r    r   r   dataZ
propertiesnamevaluer   r   r   get_var_propertiesY   s&    zSpyderKernel.get_var_propertiesNc             C   sR   ddl }|dkri }||d< | jj| jd||j|tdg| jd}| j| dS )a  
        Publish custom messages to the Spyder frontend.

        Parameters
        ----------

        spyder_msg_type: str
            The spyder message type
        content: dict
            The (JSONable) content of the message
        data: any
            Any object that is serializable by cloudpickle (should be most
            things). Will arrive as cloudpickled bytes in `.buffers[0]`.
        r   Nspyder_msg_typeZ
spyder_msg)Zprotocol)contentZbuffersparent)	cloudpickleZsessionsendZiopub_socketdumpsPICKLE_PROTOCOLZ_parent_headerlogdebug)r   r4   r5   r0   r7   msgr   r   r   send_spyder_msgx   s    
zSpyderKernel.send_spyder_msgc             C   sH   |   }|| }y| jd|d W n   | jddd Y nX d| _dS )zGet the value of a variabler0   )r0   NF)r   r>   r   )r   r1   r   r2   r   r   r   	get_value   s    zSpyderKernel.get_valuec             C   sN   ddl }| |}|d }|r,ts,t|d}||}|||< | j| dS )zSet the value of a variabler   Nzlatin-1)r7   _get_reference_namespacePY2bytesloadsr;   r<   )r   r1   r2   ZPY2_frontendr7   r   ZsvalueZdvaluer   r   r   	set_value   s    


zSpyderKernel.set_valuec             C   s   |  |}|| dS )zRemove a variableN)r@   pop)r   r1   r   r   r   r   remove_value   s    
zSpyderKernel.remove_valuec             C   s   |  |}|| ||< dS )zCopy a variableN)r@   )r   Z	orig_namenew_namer   r   r   r   
copy_value   s    
zSpyderKernel.copy_valuec          
   C   s   ddl m} ddlm} |  }|j| }||\}}|r>|S x>t| D ].}	||	t| d}
|
|	krL||	||
< qLW y|	| W n& t
k
r } zt|S d}~X Y nX dS )zLoad data from filenamer   )iofunctions)fix_reference_name)Z	blacklistN)spyder_kernels.utils.iofuncsrI   Zspyder_kernels.utils.miscrJ   	_mglobalsZ
load_funcsr$   keysrE   update	Exceptionstr)r   filenameZextrI   rJ   glbsZ	load_funcr0   Zerror_messagekeyZnew_keyerrorr   r   r   	load_data   s     
zSpyderKernel.load_datac             C   sF   ddl m} ddlm} |  }| j}|||dtd }|||S )zSave namespace into filenamer   )r    )rI   Z	picklable)r!   r"   )	r   r    rK   rI   r   r   r   copyZsave)r   rQ   r    rI   r   r   r0   r   r   r   save_namespace   s    zSpyderKernel.save_namespacec             C   s@   | j r6| jr6t|  |  | jd}| jdd|id d| _dS )z_
        Publish Variable Explorer state and Pdb step through
        send_spyder_msg.
        )Znamespace_viewZvar_propertiesstepZ	pdb_state)r5   TN)r   r   r(   r   r3   r   r>   )r   stater   r   r   publish_pdb_state   s    
zSpyderKernel.publish_pdb_statec             C   s   | j r| d dS )z
        Tell the console to run 'continue' after entering a
        Pdb session to get to the first breakpoint.

        Fixes issue 2034
        pdb_continueN)r   r>   )r   r   r   r   r[      s    zSpyderKernel.pdb_continueFc             C   s&   ddl m} | jdd}||||dS )z5Return True if object is defined in current namespacer   )	isdefinedT)with_magics)force_import	namespace)spyder_kernels.utils.dochelpersr\   r   )r   objr^   r\   r   r   r   r   
is_defined   s    zSpyderKernel.is_definedc             C   sN   yddl }d|jd< W n   Y nX ddlm} | |\}}|rJ||S dS )z#Get object documentation dictionaryr   NTzdocstring.hardcopy)getdoc)
matplotlibZrcParamsr`   rc   _eval)r   objtxtrd   rc   ra   validr   r   r   get_doc  s    zSpyderKernel.get_docc             C   s*   ddl m} | |\}}|r&||S dS )zGet object sourcer   )	getsourceN)r`   ri   re   )r   rf   ri   ra   rg   r   r   r   
get_source  s    zSpyderKernel.get_sourcec             C   s   t | dS )zSet current working directory.N)oschdir)r   dirnamer   r   r   set_cwd  s    zSpyderKernel.set_cwdc             C   s   t  S )zGet current working directory.)rk   getcwd)r   r   r   r   get_cwd  s    zSpyderKernel.get_cwdc             C   s   t jdd S )zReturn sys.path contents.N)syspath)r   r   r   r   get_syspath"  s    zSpyderKernel.get_syspathc             C   s
   t j S )zGet environment variables.)rk   environrV   )r   r   r   r   get_env&  s    zSpyderKernel.get_envc             C   s.   yddl m} |d ~W n   Y nX dS )zClose all Matplotlib figures.r   Nall)Zmatplotlib.pyplotZpyplotclose)r   Zpltr   r   r   close_all_mpl_figures*  s    
z"SpyderKernel.close_all_mpl_figuresc             C   sp   i }|   }| jdkr"|| n|| || j |rl| jjjd }| jjjd }|| || |S )z
        Return current namespace

        This is globals() if not debugging, or a dictionary containing
        both locals() and globals() for current frame when debugging
        NlineZcell)rL   r   rN   r   shellZmagics_managerZmagics)r   r]   r   rR   Zline_magicsZcell_magicsr   r   r   r   5  s    



z#SpyderKernel._get_current_namespacec             C   s0   |   }| jdkr|S | j}||kr(|S |S dS )z
        Return namespace where reference name is defined

        It returns the globals() if reference has not yet been defined
        N)rL   r   r   )r   r1   rR   Zlclsr   r   r   r@   O  s    
z%SpyderKernel._get_reference_namespacec             C   s   | j dk	r| j jS | jjS dS )z,Return current globals -- handles Pdb framesN)r   	f_globalsrz   Zuser_ns)r   r   r   r   rL   _  s    
zSpyderKernel._mglobalsc             C   s   yt |S    dS dS )zReturn sequence lengthN)r#   )r   varr   r   r   r)   f  s    zSpyderKernel._get_lenc             C   s$   yddl }t||jS    dS dS )z(Return True if variable is a NumPy arrayr   NF)numpyr&   Zndarray)r   r|   r}   r   r   r   r*   m  s
    zSpyderKernel._is_arrayc             C   s(   yddl m} t||jS    dS dS )z,Return True if variable is a PIL.Image imager   )ImageFN)ZPILr~   r&   )r   r|   r~   r   r   r   r+   u  s
    zSpyderKernel._is_imagec             C   s&   yddl m} t||S    dS dS )z&Return True if variable is a DataFramer   )	DataFrameFN)pandasr   r&   )r   r|   r   r   r   r   r,   }  s
    
zSpyderKernel._is_data_framec             C   s&   yddl m} t||S    dS dS )z#Return True if variable is a Seriesr   )SeriesFN)r   r   r&   )r   r|   r   r   r   r   r-     s
    
zSpyderKernel._is_seriesc             C   s(   y|  |r|jS dS W n
   dS dS )zReturn array's shapeN)r*   shape)r   r|   r   r   r   r.     s    
zSpyderKernel._get_array_shapec             C   s(   y|  |r|jS dS W n
   dS dS )zReturn array's ndimN)r*   ndim)r   r|   r   r   r   r/     s    
zSpyderKernel._get_array_ndimc             C   s
   || _ dS )z$Register Pdb session to use it laterN)r   )r   Zpdb_objr   r   r   _register_pdb_session  s    z"SpyderKernel._register_pdb_sessionc             C   s,   | j s
dS |d }t|}| j | dS )z3Set all Spyder breakpoints in an active pdb sessionNr   )r   picklerC   Zset_spyder_breakpoints)r   ZbreakpointsZserialized_breakpointsr   r   r   _set_spyder_breakpoints  s
    
z$SpyderKernel._set_spyder_breakpointsc             C   s   | j r| d d S )NZset_breakpoints)r   r>   )r   r   r   r   _ask_spyder_for_breakpoints  s    z(SpyderKernel._ask_spyder_for_breakpointsc             C   sB   ddl m} ||st| jdd}yt||dfS    dS dS )z
        Evaluate text and return (obj, valid)
        where *obj* is the object represented by *text*
        and *valid* is True if object evaluation did not raise any exception
        r   )is_text_stringT)r]   )NFN)Zspyder_kernels.py3compatr   AssertionErrorr   eval)r   textr   r   r   r   r   re     s    zSpyderKernel._evalc          
   C   s   ddl }ddlm} d}|r dnd}d}y| || W nz tk
r } z<dt|krvddl}	|	 }
d|
}~	n||	 }W dd}~X Y n" t
k
r   ||	 }Y nX || _dS )	z
        Set a backend for Matplotlib.

        backend: A parameter that can be passed to %matplotlib
                 (e.g. inline or tk).
        r   N)r   zM
NOTE: The following error appeared when setting your Matplotlib backend

{0}pylabrd   zGUI eventloopsz
NOTE: Spyder *can't* set your selected Matplotlib backend because there is a previous backend already in use.

Your backend will be {0})	tracebackIPython.core.getipythonr   run_line_magicRuntimeErrorrP   rd   Zget_backendformat
format_excrO   r   )r   Zbackendr   r   r   Zgeneric_errormagicrT   errrd   Zprevious_backendr   r   r   _set_mpl_backend  s$    zSpyderKernel._set_mpl_backendc             C   s   | j dk	rt| j  dS )z9Show Matplotlib backend errors after the prompt is ready.N)r   print)r   r   r   r   _show_mpl_backend_errors  s    
z%SpyderKernel._show_mpl_backend_errorsc             C   sF   ddl m} y | dd | dd W n tk
r@   Y nX dS )zLoad %autoreload magic.r   )r   
reload_extZ
autoreloadr   N)r   r   r   rO   )r   r   r   r   r   _load_autoreload_magic  s    z#SpyderKernel._load_autoreload_magicc             C   sB   t jdks>ddlm} y| dd W n tk
r<   Y nX dS )zLoad wurlitzer extension.ntr   )r   r   Z	wurlitzerN)rk   r1   r   r   r   rO   )r   r   r   r   r   _load_wurlitzer  s    
zSpyderKernel._load_wurlitzer)NN)F)F)F).__name__
__module____qualname____doc__r
   propertyr   r   r   r3   r>   r?   rD   rF   rH   rU   rW   rZ   r[   rb   rh   rj   rn   rp   rs   ru   rx   r   r@   rL   r)   r*   r+   r,   r-   r.   r/   r   r   r   re   r   r   r   r   __classcell__r   r   )r   r   r   !   sR   


	


(	r   )r   rk   os.pathrr   Zospr   rq   Zipykernel.ipkernelr   versionrA   r   r:   r   r   r   r   r   <module>   s   