B
    nb\3                 @   s  d dl mZ d dlmZ d dlZd dl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mZmZ d dlmZ d d	lmZ d d
lmZ dddgZedZedkZdZdZejdeded dZejdeded G dd deZ G dd deZ!G dd de"Z#dS )    )print_function)OrderedDictN)QObjectQTimerSignal)QApplication)dependencies)_DEBUGdebug_printget_conf_path)
sourcecode)PluginClient)CodeInfoZropejedifallbackzintrospection.log   g      ?z>=0.9.4z3Editor's code completion, go-to-definition and help)Zrequired_versionz>=0.9.0c                   sT   e Zd ZeeZ fddZdd Zdd Zdd Z	d	d
 Z
dd Zdd Z  ZS )PluginManagerc                s   t t|   t }xtD ]z}yt||}|  W n< tk
rp } ztd|  tt	| wW d d }~X Y nX td|  |||< |j
| j qW || _t | _g | _t | _d | _d | _d | _d | _d| _d S )NzIntrospection Plugin Failed: %szIntrospection Plugin Loaded: %sF)superr   __init__r   PLUGINSr   run	Exceptionr   strZreceivedconnecthandle_responsepluginsr   timerdesireddictidsinforequestpendingpending_requestwaiting)self
executabler   nameplugine)	__class__ Alib/python3.7/site-packages/spyder/utils/introspection/manager.pyr   /   s,    

zPluginManager.__init__c       	      C   s  | j r,| | j kr || _ntd dS td|j  d}|| _|j}|jdkrrd| jkrr|j	 
drrd}| rt|js| r|jdkrd}| j }|r| j| g}|g| _n^|jd	kr|j r|jdkrt| j | _n.t| j dd
 }t| j dd
 | _t | _d| _ d|j }| }t | _x&|D ]}|||}|j| j|< qNW | j  | jtd | j dS )z)Handle an incoming request from the user.zskipping duplicate requestNz
%s requestZ
completionr   )zimport zfrom r   r!   
definitionTzget_%si  )r%   Z	serializer!   r$   r   r(   editorr   linelstrip
startswithis_python_liker   Z
is_keywordobjin_comment_or_stringvaluesr   Z	is_pythonlistkeystime_start_timer   r    r"   r   stopZ
singleShotLEAD_TIME_SEC_handle_timeout)	r&   r!   r   r0   r   methodvaluer)   
request_idr,   r,   r-   send_requestH   sF    






zPluginManager.send_requestc             C   s"   x| j  D ]}|d qW d S )Nvalidate)r   r7   r"   )r&   r)   r,   r,   r-   rC   t   s    zPluginManager.validatec             C   sn   | j |d d }|sd S |dd r8td|d  d S || jd ksL| jsd|dd rj| | n|| _d S )NrA   errorzResponse error:r   result)r    getr   r   r%   	_finalizer#   )r&   responser(   r,   r,   r-   r   x   s    zPluginManager.handle_responsec             C   s2   x,| j  D ]\}}|  td| qW d S )NzIntrospection Plugin Closed: {})r   itemscloser   format)r&   r(   r)   r,   r,   r-   rJ      s    zPluginManager.closec             C   s   d| _ d | _| jrht | j }td| jj|d t|d d d |f  | j|d< d | _| j	| | j
r| j
}d | _
| | d S )NFz-%s request from %s finished: "%s" in %.1f secr(   rE   d   r!   )r%   r#   r!   r:   r;   r   r(   r   sig_introspection_completeemitr$   rB   )r&   rH   Zdeltar!   r,   r,   r-   rG      s    
zPluginManager._finalizec             C   s&   d| _ | jr| | j ntd d S )NFzNo valid responses acquired)r%   r#   rG   r   )r&   r,   r,   r-   r>      s    zPluginManager._handle_timeout)__name__
__module____qualname__r   objectrM   r   rB   rC   r   rJ   rG   r>   __classcell__r,   r,   )r+   r-   r   +   s   ,r   c                   s   e Zd ZeeeeeeZeeeeZdg f f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dZdd Zdd Zdd Zdd Zdd Zdd  Zd&d"d#Z  ZS )'IntrospectionManagerNc                sf   t t|   d | _d | _tjd d  | _|| _| jrB| j	| || _
t|| _| jj| j d S )N)r   rT   r   editor_widgetr#   syspathsys_path
extra_pathextendr'   r   plugin_managerrM   r   introspection_complete)r&   r'   rY   )r+   r,   r-   r      s    
zIntrospectionManager.__init__c             C   s   || _ |   d S )N)r'   _restart_plugin)r&   r'   r,   r,   r-   change_executable   s    z&IntrospectionManager.change_executablec             C   s0   || j kr,|| _ tjdd | _| j| dS )z&Change extra_path and update sys_path.N)rY   rV   rW   rX   rZ   )r&   rY   r,   r,   r-   change_extra_path   s    
z&IntrospectionManager.change_extra_pathc             C   s*   | j   t| j| _ | j j| j d S )N)r[   rJ   r   r'   rM   r   r\   )r&   r,   r,   r-   r]      s    
z$IntrospectionManager._restart_pluginc             C   s
   || _ d S )N)rU   )r&   rU   r,   r,   r-   set_editor_widget   s    z&IntrospectionManager.set_editor_widgetc             K   sp   | j  }| j  }| }|d kr.|d}||d< ||d< | j |d< | j|d< t|| ||j|j	|f|S )Ncursorr0   finforU   rX   )
rU   Zget_current_editorZget_current_finfor6   get_positionrX   r   Zget_source_codefilenamer4   )r&   r(   positionkwargsr0   rb   r6   r,   r,   r-   _get_code_info   s    




z#IntrospectionManager._get_code_infoc             C   s   | j d|d}| j| dS )zGet code completionZcompletions)	automaticN)rg   r[   rB   )r&   rh   r!   r,   r,   r-   get_completions   s    z$IntrospectionManager.get_completionsc             C   s   |  d|}| j| dS )zGo to definitionr.   N)rg   r[   rB   )r&   re   r!   r,   r,   r-   go_to_definition   s    z%IntrospectionManager.go_to_definitionTc             C   s    | j d||d}| j| dS )z:Show signature calltip and/or docstring in the Help pluginr!   )autoN)rg   r[   rB   )r&   re   rk   r!   r,   r,   r-   show_object_info   s    z%IntrospectionManager.show_object_infoc             C   s   | j   dS )zValidate the pluginsN)r[   rC   )r&   r,   r,   r-   rC      s    zIntrospectionManager.validatec             C   s(   | j r$| j  }t|dr$|js$dS dS )z$Check if the main app is starting upis_starting_upTN)rU   windowhasattrrm   )r&   rn   r,   r,   r-   is_editor_ready   s    
z$IntrospectionManager.is_editor_readyc          
   C   s   | dd}|dkrdS |d }| |d d }|r|j|jkrt| d|j }y|||| W n* tk
r } zt| W dd}~X Y nX dS )zr
        Handle an introspection response completion.

        Route the response to the correct handler.
        rE   Nr!   r(   z_handle_%s_result)rF   rg   rd   getattrr(   r   r   )r&   rH   rE   r!   Zcurrentfuncr*   r,   r,   r-   r\      s    z+IntrospectionManager.introspection_completec                s   j |j krdS j |j}|jdkr.d d} |s<dS jrtjtjkrfdd|D }|rjd}|tj tj }j| j |}d kr dd  dd |D } fd	d|D }j	| |j
 dS )
z
        Handle a `completions` result.

        Only handle the response if we are on the same line of text and
        on the same `obj` as the original request.
        N c                s$   g | ]\}}|  jr||fqS r,   )r3   full_obj).0ct)r!   r,   r-   
<listcomp>  s    zCIntrospectionManager._handle_completions_result.<locals>.<listcomp>ra   .r/   c             S   s"   g | ]\}}| d d |fqS )ry   r/   )split)ru   rv   rw   r,   r,   r-   rx   +  s    c                s"   g | ]\}}|  r||fqS r,   )r3   )ru   rv   rw   )completion_textr,   r-   rx   ,  s    )line_numr5   r3   rt   lenr0   rc   Zset_cursor_positionrz   Zshow_completion_listrh   )r&   Z	comp_listr!   	prev_infoZ	prev_textZnew_listposZnew_posr,   )r{   r!   r-   _handle_completions_result  s.    


z/IntrospectionManager._handle_completions_resultc             C   s^   |j |j krdS |d r2|jjd|d d|jd | j|d |d |d |d	 |j  dS )
z
        Handle an `info` result, triggering a calltip and/or docstring.

        Only handle the response if we are on the same line of text as
        when the request was initiated.
        NZcalltipZ	ArgumentsT)Z	signatureZat_positionr(   ZargspecZnoteZ	docstring)r|   r0   Zshow_calltipre   sig_send_to_helprN   rk   )r&   respr!   r~   r,   r,   r-   _handle_info_result2  s    
z(IntrospectionManager._handle_info_resultc             C   s   |\}}| j ||d dS )zHandle a `definition` resultrs   N)sig_edit_gotorN   )r&   r   r!   r~   fnamelinenor,   r,   r-   _handle_definition_resultG  s    z.IntrospectionManager._handle_definition_result`  c             C   sF   | j rBy&| j   }||| t  W n tk
r@   Y nX dS )zS
        Post a message to the main window status bar with a timeout in ms
        N)rU   rn   Z	statusBarZshowMessager   ZprocessEventsAttributeError)r&   messageZtimeoutZ	statusbarr,   r,   r-   _post_messageL  s    z"IntrospectionManager._post_message)N)T)r   )rO   rP   rQ   r   r   boolr   intr   r   r^   r_   r]   r`   rg   ri   rj   rl   rC   rp   r\   r   r   r   r   rS   r,   r,   )r+   r-   rT      s$   

	'rT   c               @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )IntrospectionPluginc             C   s   dS )zInitialize the pluginNr,   )r&   r,   r,   r-   load_plugin[  s    zIntrospectionPlugin.load_pluginc             C   s   dS )zGet a list of completionsNr,   )r&   r!   r,   r,   r-   ri   _  s    z#IntrospectionPlugin.get_completionsc             C   s   dS )aX  
        Find the calltip and docs

        Returns a dict like the following:
           {'note': 'Function of numpy.core.numeric...',
            'argspec': "(shape, dtype=None, order='C')'
            'docstring': 'Return an array of given...'
            'name': 'ones',
            'calltip': 'ones(shape, dtype=None, order='C')'}
        Nr,   )r&   r!   r,   r,   r-   get_infoc  s    zIntrospectionPlugin.get_infoc             C   s   dS )z4Get a (filename, line_num) location for a definitionNr,   )r&   r!   r,   r,   r-   get_definitionp  s    z"IntrospectionPlugin.get_definitionc             C   s   dS )zValidate the pluginNr,   )r&   r,   r,   r-   rC   t  s    zIntrospectionPlugin.validateN)rO   rP   rQ   r   ri   r   r   rC   r,   r,   r,   r-   r   Y  s
   r   )$Z
__future__r   collectionsr   r:   rV   Zqtpy.QtCorer   r   r   Zqtpy.QtWidgetsr   Zspyderr   Zspyder.config.baser	   r
   r   r   Zspyder.utilsr   Z(spyder.utils.introspection.plugin_clientr   Z spyder.utils.introspection.utilsr   r   ZLOG_FILENAMEZDEBUG_EDITORr=   ZROPE_REQVERaddZJEDI_REQVERr   rT   rR   r   r,   r,   r,   r-   <module>   s4   
w 8