
    G@d                     V   d Z ddlZddlZddlZddlZddlmZmZ ddlZddl	m
Z
 ddlmZ ddlmZmZmZmZmZ ddlmZ ddlmZmZ dd	lmZmZ dd
l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j(        e)          Z*d  e+e!          D             Z,d Z- G d de          Z.dS )z
Spyder completion plugin.

This plugin is in charge of creating and managing multiple code completion and
introspection providers.
    N)ListUnion)parse)iter_entry_points)QMutexQMutexLockerQTimerSlotSignal)CONF)SpyderPluginV2Plugins)on_plugin_availableon_plugin_teardown)_running_under_pytest	NoDefault)CompletionRequestTypesSpyderCompletionProviderCOMPLETION_ENTRYPOINT)CompletionConfigPage)CompletionContainerc                 `    g | ]+}|                                 t          t          |          ,S  )isuppergetattrr   ).0cs     @lib/python3.11/site-packages/spyder/plugins/completion/plugin.py
<listcomp>r!   -   sF     L L Lqyy{{Lw5q99 L L L    c                 0      G  fdd           }|S )z#Return a partial class constructor.c                   <    e Zd Z ej        j        g R i ZdS )partialclass.<locals>.NewClsN)__name__
__module____qualname__	functoolspartialmethod__init__)argsclskwdss   r    NewClsr%   3   s3        *9*3<G$GGG$GGr"   r/   r   )r-   r,   r.   r/   s   ``` r    partialclassr0   1   sT    H H H H H H H H H H H HMr"   c                        e Zd ZdZdZdZej        ej        gZ	ej
        ej        ej        gZdZi ZdZeZ eeee          Z	  ee          Z	  eee          Z	  e            Z	  eee          Z	  ee          Z	  eeee          Z	  ee          Z 	 dZ!dZ"e#j$        hZ%e#j$        hZ&dd fd	Z'e(defd	            Z)defd
Z*d Z+d Z, e-ej                  d             Z. e-ej                  d             Z/ e-ej                  d             Z0 e-ej
                  d             Z1 e-ej                  d             Z2 e3ej                  d             Z4 e3ej                  d             Z5 e3ej                  d             Z6 e3ej
                  d             Z7 e3ej                  d             Z8d Z9de:fdZ;dede:fdZ<de=e>eef                  fdZ?d Z@dfdZAdfd ZBd! ZCeDd"             ZE eF            d#             ZGd$ ZHd% ZId& ZJd' ZKd( ZLd) ZMd* ZNe(d+eOd,ed-efd.            ZPd+eOd,edefd/ZQd+eOd,efd0ZRd1 ZSd+eOfd2ZTded3ZU eFe          d,efd4            ZVd5ede:fd6ZWd5efd7ZXd8edeOfd9ZYd8ede:fd:ZZd5ede=e         fd;Z[d5ede:fd<Z\d=e=e         d>ede=e         fd?Z]d,efd@Z^d,efdAZ_dB Z`dC ZadD ZbdE ZcdF ZddG ZedH ZfdI ZgdJ Zhd5ed>edKefdLZid5edMedNefdOZjd>edKefdPZk	 	 dgdRefdSZl eFee          dTed5efdU            Zmd5edTefdVZn eFeee          dWedXedYefdZ            Zo eFe          dXefd[            ZpdXefd\ZqdXefd]Zrd^efd_Zsd`efdaZtd>edbefdcZu xZvS )hCompletionPlugina  
    Spyder completion plugin.

    This class provides a completion and linting plugin for the editor in
    Spyder.

    This plugin works by forwarding all the completion/linting requests to a
    set of :class:`SpyderCompletionProvider` instances that are discovered
    and registered via entrypoints.

    This plugin can assume that `fallback`, `snippets`, `lsp` and `kite`
    completion providers are available, since they are included as part of
    Spyder.
    completionsFNrunningstoppedc                    t                                          ||           i | _        i | _        i | _        i | _        d| _        t          t          j                  | _	        i | _
        i | _        |                     d          | _        g | _        g | _        t!          t"                    D ]}	 d|j        v rt&                              d|            |                                }|                     |           T# t.          $ r$}t&                              d|            |d }~ww xY w|                     d           |                                 \  }}t7          t8          |          | _        d	|i| _        d S )
Nr   completions_wait_for_mskitezLoading entry point: z4Failed to load completion provider from entry point Fplugin_loaded	providersr3   )superr+   _available_providersr<   language_statusrequestsreq_idr   	Recursivecollection_mutexsource_priorityprovider_speedget_confwait_for_msapplication_menus_to_create!items_to_add_to_application_menusr   r   nameloggerdebugresolve"_instantiate_and_register_provider	Exceptionwarningregister_statusbar_widgetsgather_providers_and_configtabsr0   r   CONF_WIDGET_CLASSADDITIONAL_CONF_TABS)	selfparentconfigurationentry_pointProvidereconf_providers	conf_tabs	__class__s	           r    r+   zCompletionPlugin.__init__   s   /// %'!   "   !'v'7 8 8  " !  ==)BCC ,.( 24. --BCC 	 	K
 [---B[BBCCC&..0077AAAA     6(3 6  6 7 7 7 	''e'<<< '+&J&J&L&L#!- N"< "< "<%2I$>!!!s   2	D<AD
D1D,,D1returnc                       t          d          S )NzCompletion and lintingr   r   r"   r    get_namezCompletionPlugin.get_name  s    )***r"   c                      t          d          S )NzThis plugin is in charge of handling and dispatching, as well as of receiving the responses of completion and linting requests sent to multiple providers.r`   rU   s    r    get_descriptionz CompletionPlugin.get_description  s     @ A A 	Ar"   c                 ,    |                      d          S )Nr3   )create_iconrc   s    r    get_iconzCompletionPlugin.get_icon  s    ...r"   c                 ,   | j                             | j                   t                      rRt          j                            d          s3| j        D ])}| j        |         }t          j	        |d                    *d S | 
                                 d S )NSPY_TEST_USE_INTROSPECTIONinstance)sig_interpreter_changedconnectupdate_completion_statusr   osenvirongetr<   r   unobserve_configurationstart_all_providersrU   provider_nameprovider_infos      r    on_initializezCompletionPlugin.on_initialize  s    $,,T-JKKK  !! 	:>>">?? %)^ L LM$(N=$AM0z1JKKKK  """""r"   )pluginc                 n    |                      t          j                  }|                    |            d S N)
get_pluginr   Preferencesregister_plugin_preferencesrU   preferencess     r    on_preferences_availablez)CompletionPlugin.on_preferences_available!  s0    oog&9:://55555r"   c                     |                      t          j                  }|                                }| j        j                            |j                   |j                            | j                   d S ry   )rz   r   MainInterpreterget_containercompletion_statussig_open_preferences_requestedrl   rk   rU   maininterpretermi_containers      r    on_maininterpreter_availablez-CompletionPlugin.on_maininterpreter_available&  sz    //'*ABB&4466 	=EE7	9 	9 	9 	,44(	* 	* 	* 	* 	*r"   c                    |                                  }|                     t          j                  | _        |                                D ]}| j                            |           | j                            | j                   d S ry   )r   rz   r   	StatusBar	statusbarall_statusbar_widgetsadd_status_widgetr   rU   	containersbs      r    on_statusbar_availablez'CompletionPlugin.on_statusbar_available2  s|    &&((	):;;1133 	1 	1BN,,R0000(()?@@@@@r"   c                     |                      t          j                  }| j        D ]\  }} |j        |i | | j        D ]\  }} |j        |i | d S ry   )rz   r   MainMenurH   create_application_menurI   add_item_to_application_menu)rU   	main_menur,   kwargss       r    on_mainmenu_availablez&CompletionPlugin.on_mainmenu_available:  s    OOG$455	 !< 	? 	?LD&-I-t>v>>>> !B 	D 	DLD&2I2DCFCCCC	D 	Dr"   c                     |                      t          j                  }|j                            | j                   d S ry   )rz   r   PythonpathManagersig_pythonpath_changedrl   rU   pythonpath_managers     r    on_pythonpath_manager_availablez0CompletionPlugin.on_pythonpath_manager_availableF  sB    !__W-FGG199'	) 	) 	) 	) 	)r"   c                 n    |                      t          j                  }|                    |            d S ry   )rz   r   r{   deregister_plugin_preferencesr}   s     r    on_preferences_teardownz(CompletionPlugin.on_preferences_teardownL  s0    oog&9::11$77777r"   c                     |                      t          j                  }|                                }|j                            | j                   d S ry   )rz   r   r   r   rk   
disconnectr   s      r    on_maininterpreter_teardownz,CompletionPlugin.on_maininterpreter_teardownQ  sR    //'*ABB&4466,77(	* 	* 	* 	* 	*r"   c                     |                                  }|                     t          j                  | _        |                                D ]!}| j                            |j                   "d S ry   )r   rz   r   r   r   r   remove_status_widgetIDr   s      r    on_statusbar_teardownz&CompletionPlugin.on_statusbar_teardownY  si    &&((	):;;1133 	7 	7BN//6666	7 	7r"   c                    |                      t          j                  }t          j        |j                  }| j        D ]"\  }}|d         }|                    |           #| j        D ]\  }} |j	        |i |}|
                                 |j        d         }|j        d         }d }t          |d          r|j        }nt          |d          r|j        }||                    ||           d S )Nr   itemmenu_id	action_id)r   )rz   r   r   inspect	signaturer   rH   remove_application_menurI   bindapply_defaults	argumentshasattrr   r   !remove_item_from_application_menu)	rU   r   r   r,   r   r   bindingr   item_ids	            r    on_mainmenu_teardownz%CompletionPlugin.on_mainmenu_teardown`  s#   OOG$455	%i&LMM	 < 	7 	7LD&1gG--g6666 B 	. 	.LD&$ind5f55G""$$$$V,D'	2GGt[)) '.y)) ',";;W < . . .	. 	.r"   c                     |                      t          j                  }|j                            | j                   d S ry   )rz   r   r   r   r   r   s     r    on_pythonpath_manager_teardownz/CompletionPlugin.on_pythonpath_manager_teardownx  sB    !__W-FGG1<<'	) 	) 	) 	) 	)r"   c                     | j         D ]:}| j         |         }|d         | j        k    r|d                                          ;dS )z&Stop all running completion providers.statusrj   N)r<   RUNNINGshutdownrs   s      r    stop_all_providersz#CompletionPlugin.stop_all_providers  sS    !^ 	5 	5M N=9MX&$,66j)22444		5 	5r"   c                     d}| j         D ]A}| j         |         }|d         | j        k    r!|d         }|                                }||z  }B|S )z+Check if any provider has any pending task.Fr   rj   )r<   r   	can_close)rU   r   rt   ru   providerprovider_can_closes         r    r   zCompletionPlugin.can_close  sd    	!^ 	0 	0M N=9MX&$,66(4%-%7%7%9%9"//	r"   c                     d}| j         D ]W}| j         |         }|d         | j        k    r7|d         }|                                }||z  }|r|                                 X|S )z:Check if any provider has any pending task before closing.Fr   rj   )r<   r   r   r   )rU   
cancelabler   rt   ru   r   r   s          r    on_closezCompletionPlugin.on_close  s~    	!^ 	( 	(M N=9MX&$,66(4%-%7%7%9%9"//	% (%%'''r"   optionsc                    t          i           }|D ]}|dk    r|                     d          | _        #t          |t                    r|^}}}|dk    ro|                     d|f          }|r+|                     |           |                     |           |                     |           |                     |           |dk    r||hz  }| j	        
                    d|fi            dS )z
        Update plugin and/or provider configurations.

        Settings are propagated from changes on the configuration page and/or
        provider tabs.
        r7   enabled_providersprovider_configurationupdate_source_menuN)setrF   rG   
isinstancetuplestart_provider_instanceregister_statusbar_widgetshutdown_provider_instanceunregister_statusbarsig_editor_rpcemit)rU   r   providers_to_updateoptionoption_namert   __provider_statuss           r    after_configuration_updatez+CompletionPlugin.after_configuration_update  s+    ""gg 	; 	;F222#'==-$/ $/  FE** ;28/]R"555&*mm,m<'> '>O& A44]CCC66}EEEE77FFF11-@@@@ $<<<'M?:'
 	  !5z2FFFFFr"   c                 h    | j         D ])}| j         |         }|d                                          *d S )Nrj   )r<   on_mainwindow_visiblers   s      r    r   z&CompletionPlugin.on_mainwindow_visible  sC    !^ 	> 	>M N=9M*%;;====	> 	>r"   Tc                 |    | j         D ]3}|                     d|fd          }|r|                     ||           4dS )aS  
        Register status bar widgets for all providers with the container.

        Parameters
        ----------
        plugin_loaded: bool
            True if the plugin is already loaded in Spyder, False if it is
            being loaded. This is needed to avoid adding statusbar widgets
            multiple times at startup.
        r   Tr9   N)r<   rF   r   )rU   r:   provider_keyprovider_ons       r    rQ   z+CompletionPlugin.register_statusbar_widgets  sg     !N 	? 	?L--$l3T; ;K ?..  / ? ? ?		? 	?r"   c                     |                                  }| j        |         d         }|                    |j        |          }|rG|D ]F}|j        |         }|| j                                        vr| j                            |           EdS dS )aQ  
        Register statusbar widgets for a given provider.

        Parameters
        ----------
        provider_name: str
            Name of the provider that is going to create statusbar widgets.
        plugin_loaded: bool
            True if the plugin is already loaded in Spyder, False if it is
            being loaded.
        rj   N)r   r<   rQ   STATUS_BAR_CLASSESstatusbar_widgetsr   get_status_widgetsr   )rU   rt   r:   r   r   widgets_idsid_current_widgets           r    r   z*CompletionPlugin.register_statusbar_widget  s     &&((	>-0<::'8 8 	E" E E!*!<S!A dn??AAAAN44^DDD	E 	EE Er"   c                    |                                  }|                                                      |          }|D ]L}||j        v rA|                                                      |           | j                            |           MdS )z
        Unregister statusbar widgets for a given provider.

        Parameters
        ----------
        provider_name: str
            Name of the provider that is going to delete statusbar widgets.
        N)r   get_provider_statusbar_keysr   remove_statusbar_widgetr   r   )rU   rt   r   provider_keysr   s        r    r   z%CompletionPlugin.unregister_statusbar  s     &&((	**,,HH   	9 	9C i111""$$<<SAAA33C888	9 	9r"   c                 4    |                                  j        S ry   )r   r   rc   s    r    r   z"CompletionPlugin.completion_status  s    !!##55r"   c                    |                      t          j                  }|                                j        }|j        }|j        }d|v r|                    d          d         }d|v r|                    d          \  }}n|d}}|                                }|                                }d| }|r	|d| dz  }| j	        
                    ||           d S )N(r   : zCompletions: ))rz   r   r   r   interpreter_statusvalue_interpretersplitstripr   update_status)rU   r   	mi_statusr   tool_tipkindrJ   	new_values           r    rm   z)CompletionPlugin.update_completion_status  s    //'*ABB#1133F	)%<<KK$$Q'E%<<S))JD$$$Dzz||zz||*D**	 	%T$I,,YAAAAAr"   c                 p   g }g }|                                  }| j        D ]}| j        |         d         }|j        D ]}t          |d|                     |                     t          |d|                     |                     t          |d|                     |                     t          |d|                     ||                     |D ]+\  }}t          |||                     |||                     ,||j        z  }|	                    ||
                                f           ||fS )a  
        Gather and register providers and their configuration tabs.

        This method iterates over all completion providers, takes their
        corresponding configuration tabs, and patches the methods that
        interact with writing/reading/removing configuration options to
        consider provider options that are stored inside this plugin's
        `provider_configuration` option, which makes providers unaware
        of the CompletionPlugin existence.
        rj   
get_option
set_optionremove_optionapply_settings)gather_create_opsr<   	CONF_TABSsetattrwrap_get_optionwrap_set_optionwrap_remove_optionwrap_apply_settingswrap_create_opappendra   )	rU   r[   r\   widget_funcsr   r   tabrJ   poss	            r    rR   z0CompletionPlugin.gather_providers_and_configtabs   s    	--// N 	G 	GL~l3J?H) J J\,,\::< < <\,,\::< < <_//==? ? ? -00lCCE E E ". J JID#C //c<HHJ J J JJ ++I!!<1B1B1D1D"EFFFFy((r"   c                    t          j        t                    }g }|D ]i\  }}|                    d          rOt          j        |          }|j        }d|j        v r+d}|D ]}|dk    r n|dz  }|                    ||f           j|S )z
        Extract all the create_* methods declared in the
        :class:`spyder.api.preferences.PluginConfigPage` class
        create_r      )r   
getmembersr   
startswithr   
parametersr  )	rU   membersr  rJ   callsigr  r
  params	            r    r   z"CompletionPlugin.gather_create_opsH  s     $%9::! 
	5 
	5JD$y)) 	5'-- ^
s~--C!+ ! ! H,,!Eq ''s444r"   c                 *    | t           dffd	}|S )a=  
        Wraps `get_option` method for a provider config tab to consider its
        actual section nested inside the `provider_configuration` key of this
        plugin options.

        This wrapper method allows configuration tabs to not be aware about
        their presence behind the completion plugin.
        Nc                 ~    |$t          |t                    r	ddg|R }ndd|f}                    |||          S Nr   values)r   r   rF   )rU   r   defaultsectionrw   r   s       r    wrapperz1CompletionPlugin.wrap_get_option.<locals>.wrapperh  s`    fe,, &6( '%' 'FF 7($&F??67G<<<r"   r   rU   r   r  rw   s    ` @r    r  z CompletionPlugin.wrap_get_option]  s:     *3T 	= 	= 	= 	= 	= 	= 	= r"   c                      | 	 	 dfd	}|S )a=  
        Wraps `set_option` method for a provider config tab to consider its
        actual section nested inside the `provider_configuration` key of this
        plugin options.

        This wrapper method allows configuration tabs to not be aware about
        their presence behind the completion plugin.
        NFc                     |$t          |t                    r	ddg|R }ndd|f}                    ||||          S )Nr   r  )recursive_notification)r   r   set_conf)rU   r   r   r  r   rw   r   s        r    r  z1CompletionPlugin.wrap_set_option.<locals>.wrapper~  so    fe,, &6( '%' 'FF 7($&F??w'= # ? ? ?r"   )NFr   r  s    ` @r    r  z CompletionPlugin.wrap_set_options  s;     15+0	? 	? 	? 	? 	? 	? 	? r"   c                     | dfd	}|S )a@  
        Wraps `remove_option` method for a provider config tab to consider its
        actual section nested inside the `provider_configuration` key of this
        plugin options.

        This wrapper method allows configuration tabs to not be aware about
        their presence behind the completion plugin.
        Nc                     |:t          |t                    r	ddg|R }ndd|f}                    ||          S d S r  )r   r   remove_conf)rU   r   r  rw   r   s      r    r  z4CompletionPlugin.wrap_remove_option.<locals>.wrapper  sg    fe,, &6( '%' 'FF 7($&F))&'::: r"   ry   r   r  s    ` @r    r  z#CompletionPlugin.wrap_remove_option  s5     	; 	; 	; 	; 	; 	; 	; r"   c                     fd}|S )a<  
        Wraps `create_*` methods for a provider config tab to consider its
        actual section nested inside the `provider_configuration` key of this
        plugin options.

        This wrapper method allows configuration tabs to not be aware about
        their presence behind the completion plugin.
        c                 L   |                     dd           Zt          |          }t          |         t                    rddg|         R |<   ndd|         f|<   t          |          }t	          | j                  } ||i |}|                    |            |S )Nr  r   r  )rp   listr   r   r   rV   	setParent)	rU   r,   r   arg_listr  widgetcreate_nameopt_posr   s	         r    r  z0CompletionPlugin.wrap_create_op.<locals>.wrapper  s    zz)T**2::d7mU33 '0(H)(g)( )(HW%%
 1(HW)'HW% X4;44DT4*6**FT"""Mr"   r   )rU   r+  r,  r   r  s    ``` r    r  zCompletionPlugin.wrap_create_op  s/    	 	 	 	 	 	 	  r"   c                 $    |j         fd}|S )aA  
        Wraps `apply_settings` method for a provider config tab to consider its
        actual section nested inside the `provider_configuration` key of this
        plugin options.

        This wrapper method allows configuration tabs to not be aware about
        their presence behind the completion plugin.
        c                     t          i           } |           D ].}t          |t                    r|ddg|R hz  }$|dd|fhz  }/|S r  )r   r   r   )rU   wrapped_optsoptprev_methodr   s      r    r  z5CompletionPlugin.wrap_apply_settings.<locals>.wrapper  s    r77L"{4(( L Lc5)) L &>&.&@;>&@ &@ %A ALL !0(Hc&K %L LLLr"   )r   )rU   Tabr   r  r1  s     ` @r    r  z$CompletionPlugin.wrap_apply_settings  s3     (		  		  		  		  		  		  r"   rY   rt   provider_configurationsc                    t          | j                  }| j        }||vr|||d}|||<   ||         }t          | j                  }t          |d                   }|d         }|d         }|                                |                                z
  }	|	D ]}
||
         ||
<   ||
         ||
<   ||k    r|                                |                                z  }|D ]*}||         ||         k    r||         ||<   ||         ||<   +|j        |j        k    rX|                                |                                z
  }|D ],}|                    |           |                    |           -t          |          ||fS )Nversionr  defaultsr6  r  r7  )dictCONF_DEFAULTSCONF_VERSIONr   keysmajorpopstr)rY   rt   r3  provider_defaultsprovider_conf_versionprovider_configcurrent_conf_versioncurrent_conf_valuescurrent_defaultsnew_keysnew_keypreserved_keyskeydeleted_keyss                 r    _merge_default_configurationsz.CompletionPlugin._merge_default_configurations  s    !!788 ( 5 777 1+- O 6E#M2 2-@ %h&; < <$_Y%?@@-h7*:6 %))++.A.F.F.H.HH 	C 	CG+<W+E((9'(BW%% #777 .22447H7M7M7O7OON% F F#C(,=c,BBB,=c,B$S)/@/E',$*.B.HHH %))++.?.D.D.F.FF ' 1 1C$((---'++C0000)**,? " 	"r"   c                     |                      d          }|                     |||          \  }}}|||d}|||<   |                     d|           |S )z&Get provider configuration dictionary.r   r5  )rF   rJ  r!  )rU   rY   rt   r3  r@  rC  r?  new_provider_configs           r    get_provider_configurationz+CompletionPlugin.get_provider_configuration  s     #'--$#& #&
 #@@}&=? ?				 -))
 

 2E. 	.0GHHH""r"   c                     |                      d          }|j        }t          D ]4}|                    |i           }|j        | j        |<   |dz
  ||<   |||<   5|| _        |                     d|           dS )z9Sort request priorities based on Provider declared order.request_prioritiesr  N)rF   DEFAULT_ORDERCOMPLETION_REQUESTSrp   SLOWrE   rD   r!  )rU   rY   rt   source_prioritiesprovider_priorityrequestrO  s          r    update_request_prioritiesz*CompletionPlugin.update_request_priorities  s     !MM*>??$2* 	< 	<G!2!6!6w!C!C19D.0AA0E}-);g&&0*,=>>>>>r"   c                    |                                  }|j                            | j                   |j                            | j                   |j                            | j                   |j                            | j                   |j                            | j                   |j	                            | j
                   |j                            |j                   |j                            |j                   |j                            | j                   | j                            |j                   | j                            |j                   dS )z)Connect SpyderCompletionProvider signals.N)r   sig_provider_readyrl   provider_availablesig_stop_completionssig_response_readyreceive_responsesig_exception_occurred"sig_language_completions_availablesig_disable_providerr   sig_show_widgetshow_widgetsig_call_statusbarstatusbar_rpcsig_open_filer   python_path_updaterk   main_interpreter_changed)rU   provider_instancer   s      r    connect_provider_signalsz)CompletionPlugin.connect_provider_signals-  su   &&((	,44T5LMMM.66%	' 	' 	',44T5JKKK088'	) 	) 	)<DD3	5 	5 	5.66+	- 	- 	-)11!	
 	
 	
 	,44#	% 	% 	%'//0BCCC#++0	2 	2 	2$,,6	8 	8 	8 	8 	8r"   c                    |j         }|| j        v rd S || j        |<   t                              d                    |                     |                     ||          }|                     ||            || |d                   }|                     |           || j        d| j	        |<   | j
        D ]}| j
        |         }d||<   d S )Nz"Completion plugin: Registering {0}r  )rj   r   F)COMPLETION_PROVIDER_NAMEr>   rK   rL   formatrM  rV  rh  STOPPEDr<   r?   )rU   rY   rt   rA  rg  languageserver_statuss          r    rN   z3CompletionPlugin._instantiate_and_register_providerG  s    9D555F3;!-09@@  	 	 	
 99m% % 	&&x??? %HT?8+DEE 	%%&7888 *l)
 )
}%
 , 	1 	1H 0:M+0M-((	1 	1r"   c                     | j         D ]V}| j         |         }|d         | j        k    s|r4|                     d|fd          }|r|d                                          WdS )z(Start all detected completion providers.r   r   Trj   N)r<   rl  rF   start)rU   forcert   ru   provider_enableds        r    rr   z$CompletionPlugin.start_all_providersi  s    !^ 	6 	6M N=9MX&$,66%6#'==(-8$$@ $@ # 6!*-33555	6 	6r"   c                 h    | j         |         }| j        |d<   | j                            |           dS )zAIndicate that the completion provider `provider_name` is running.r   N)r<   r   rX  r   rs   s      r    rY  z#CompletionPlugin.provider_availables  s9     }5"&,h$$]33333r"   rm  c                     d}| j                             |i           }| j        D ]G}| j        |         }|d         | j        k    r'|d         }|                    |          }||z  }|||<   H|| j         |<   |S )z<Start completion providers for a given programming language.Fr   rj   )r?   rp   r<   r   &start_completion_services_for_language)rU   rm  startedlanguage_providersrt   ru   r   provider_starteds           r    ru  z7CompletionPlugin.start_completion_services_for_languagez  s    !155hCC!^ 	E 	EM N=9MX&$,66(4CCHMM !++4D"=1);X&r"   c                     | j         D ]=}| j         |         }|d         }|d         | j        k    r|                    |           >| j                            |           dS )z;Stop completion providers for a given programming language.rj   r   N)r<   r   %stop_completion_services_for_languager?   r=  )rU   rm  rt   ru   rj   s        r    rz  z6CompletionPlugin.stop_completion_services_for_language  so    !^ 	I 	IM N=9M$Z0HX&$,66>>xHHH  *****r"   rJ   c                 (    | j         |         d         S )zAGet the :class:`SpyderCompletionProvider` identified with `name`.rj   r;   )rU   rJ   s     r    get_providerzCompletionPlugin.get_provider  s    ~d#J//r"   c                     | j                             |i                               d| j                  }|| j        k    S )zReturn if provider is running.r   )clientsrp   rl  r   )rU   rJ   r   s      r    is_provider_runningz$CompletionPlugin.is_provider_running  s8    !!$++//$,GG%%r"   c                 T    g }|| j         v r| j         |         fdD             }|S )z<Return the list of providers available for a given language.c                 $    g | ]}|         
|S r   r   )r   pr   s     r    r!   zECompletionPlugin.available_providers_for_language.<locals>.<listcomp>  s#    JJJqq7IJJJJr"   )r?   )rU   rm  r<   r   s      @r     available_providers_for_languagez1CompletionPlugin.available_providers_for_language  sB    	t+++"28<OJJJJOJJJIr"   c                 x    t          |                     |                    }ddh}||z
  t                      k    S )zp
        Return if fallback and snippets are the only available providers for
        a given language.
        snippetsfallback)r   r  )rU   rm  available_providersfallback_providerss       r    is_fallback_onlyz!CompletionPlugin.is_fallback_only  sE    
 "11(;;= =(*5#&88SUUBBr"   r<   req_typec                 F    | j         |         t          |fd          S )z(Sort providers for a given request type.c                     |          S ry   r   )r  request_orders    r    <lambda>z=CompletionPlugin.sort_providers_for_request.<locals>.<lambda>  s    }Q/? r"   rH  )rD   sorted)rU   r<   r  r  s      @r    sort_providers_for_requestz+CompletionPlugin.sort_providers_for_request  s/     ,X6i%?%?%?%?@@@@r"   c                 z    | j         |         }|d         | j        k    r|d                                          dS dS )zStart a given provider.r   rj   N)r<   rl  rp  rs   s      r    r   z(CompletionPlugin.start_provider_instance  sE    }5"dl22*%++----- 32r"   c                     | j         |         }|d         | j        k    r&|d                                          | j        |d<   dS dS )zShutdown a given provider.r   rj   N)r<   r   r   rl  rs   s      r    r   z+CompletionPlugin.shutdown_provider_instance  sQ    }5"dl22*%..000&*lM(### 32r"   c                 N    |                                  }||d<    |j        |i |S )NrV   )r   create_actionrU   r,   r   r   s       r    r  zCompletionPlugin.create_action  s5    &&((	$x&y&7777r"   c                 D    |                                  } |j        |i |S ry   )r   
get_actionr  s       r    r  zCompletionPlugin.get_action  s+    &&((	#y#T4V444r"   c                 b    |                      t          j                  }|r |j        |i |S d S ry   )rz   r   r   get_application_menurU   r,   r   r   s       r    r  z%CompletionPlugin.get_application_menu  sE     OOG$455	 	C1914B6BBB	C 	Cr"   c                 D    |                                  } |j        |i |S ry   )r   get_menur  s       r    r  zCompletionPlugin.get_menu  s+    &&((	!y!426222r"   c                 >    | j                             ||f           d S ry   )rH   r  rU   r,   r   s      r    r   z(CompletionPlugin.create_application_menu  s#    (//v?????r"   c                 D    |                                  } |j        |i |S ry   )r   create_menur  s       r    r  zCompletionPlugin.create_menu  s+    &&((	$y$d5f555r"   c                 >    | j                             ||f           d S ry   )rI   r  r  s      r    r   z-CompletionPlugin.add_item_to_application_menu  s#    .55tVnEEEEEr"   c                 f    |                      t          j                  }|r |j        |i | d S d S ry   )rz   r   r   r   r  s       r    r   z2CompletionPlugin.remove_item_from_application_menu  sI    OOG$455	 	I7I7HHHHHH	I 	Ir"   c                 H    |                                  } |j        |i | d S ry   )r   add_item_to_menur  s       r    r  z!CompletionPlugin.add_item_to_menu  s1    &&((	"	"D3F33333r"   reqc                      j          xj         dz  c_         ||t          j        |d                   i dd j        <                        |                                          }t           fd|D                       }| j        v r@|dk    r: j        dk    rt          j
         j         fd           nd	 j                 d
<   |D ]-} j        |         }|d                             |||           .dS )aS  
        Send a completion or linting request to all available providers.

        The completion request `req_type` needs to have a response.

        Parameters
        ----------
        language: str
            Name of the programming language of the file that emits the
            request.
        req_type: str
            Type of request, one of
            :class:`spyder.plugins.completion.api.CompletionRequestTypes`
        req: dict
            Request body
            {
                'filename': str,
                **kwargs: request-specific parameters
            }
        r  response_instanceF)rm  r  r  sources	timed_outc                 *    g | ]}j         |         S r   )rE   )r   r  rU   s     r    r!   z1CompletionPlugin.send_request.<locals>.<listcomp>  s!    "M"M"Ma4#6q#9"M"M"Mr"      r   c                  .                                    S ry   )receive_timeout)rA   rU   s   r    r  z/CompletionPlugin.send_request.<locals>.<lambda>  s    $*>*>v*F*F r"   Tr  rj   N)rA   weakrefrefr@   r  lowersumAGGREGATE_RESPONSESrG   r	   
singleShotr<   send_request)	rU   rm  r  r  r<   slow_provider_countrt   ru   rA   s	   `       @r    r  zCompletionPlugin.send_request  sS   * q ! !(S1D-E!F!F!
 !
f 99(..:J:JKK	!"M"M"M"M9"M"M"MNN t///4G!4K4K!##!$"2"F"F"F"F"FH H H H 6:f%k2 ' 	1 	1M N=9M*%22(C1 1 1 1	1 	1r"   notification_typenotificationc                     |                      |                                          }|D ]=}| j        |         }|d         | j        k    r|d                             |||           >dS )a  
        Send a notification to all available completion providers.

        Parameters
        ----------
        language: str
            Name of the programming language of the file that emits the
            request.
        notification_type: str
            Type of request, one of
            :class:`spyder.plugins.completion.api.CompletionRequestTypes`
        notification: dict
            Request body
            {
                'filename': str,
                **kwargs: notification-specific parameters
            }
        r   rj   N)r  r  r<   r   send_notification)rU   rm  r  r  r<   rt   ru   s          r    r  z"CompletionPlugin.send_notification  s~    ( 99(..:J:JKK	& 	? 	?M N=9MX&$,66j);;/? ? ?	? 	?r"   c                     | j         D ]<}| j         |         }|d         | j        k    r|d                             ||           =dS )a  
        Send a notification to all available completion providers for all
        programming languages.

        Parameters
        ----------
        req_type: str
            Type of request, one of
            :class:`spyder.plugins.completion.api.CompletionRequestTypes`.
        req: dict
            Request body:
            {
                'filename': str,
                **kwargs: notification-specific parameters
            }
        r   rj   N)r<   r   broadcast_notification)rU   r  r  rt   ru   s        r    r  z'CompletionPlugin.broadcast_notification7  s`    " "^ 	# 	#M N=9MX&$,66j)@@c# # #	# 	#r"   additionproject_pathc                     | j         D ]=}| j         |         }|d         | j        k    r|d                             |||           >dS )a  
        Handle project path updates on Spyder.

        Parameters
        ----------
        project_path: str
            Path to the project folder being added or removed.
        update_kind: str
            Path update kind, one of
            :class:`spyder.plugins.completion.WorkspaceUpdateKind`.
        instance: object
            Reference to :class:`spyder.plugins.projects.plugin.Projects`.
        r   rj   N)r<   r   project_path_update)rU   r  update_kindrj   rt   ru   s         r    r  z$CompletionPlugin.project_path_updateN  sb     "^ 	 	M N=9MX&$,66j)== +x  	 	r"   filenamec                     |F|F| j         D ]@}| j         |         }|d         | j        k    r|d                             ||           =dS dS dS )ak  
        Handle file modifications and file switching events, including when a
        new file is created.

        Parameters
        ----------
        filename: str
            Path to the file that was changed/opened/focused.
        language: str
            Name of the programming language of the file that was
            changed/opened/focused.
        Nr   rj   )r<   r   file_opened_closed_or_updated)rU   r  rm  rt   ru   s        r    r  z.CompletionPlugin.file_opened_closed_or_updatedd  sy     H$8!% , , $} = *dl::!*-KK (, , ,	  $8$8, ,r"   c                     | j         D ]=}| j         |         }|d         | j        k    r|d                             |||           >dS )a  
        Register file to perform completions.
        If a language client is not available for a given file, then this
        method should keep a queue, such that files can be initialized once
        a server is available.

        Parameters
        ----------
        language: str
            Programming language of the given file.
        filename: str
            Filename to register.
        codeeditor: spyder.plugins.editor.widgets.codeeditor.CodeEditor
            Codeeditor to send the client configurations.
        r   rj   N)r<   r   register_file)rU   rm  r  
codeeditorrt   ru   s         r    r  zCompletionPlugin.register_filey  sb      "^ 	 	M N=9MX&$,66j)77h
  	 	r"   completion_sourcerA   respc                 ,   t                               d                    ||                     || j        vrdS t	          | j                  5  | j        |         }||d         |<   |                     |           ddd           dS # 1 swxY w Y   dS )z4Process request response from a completion provider.z4Completion plugin: Request {0} Got response from {1}Nr  )rK   rL   rk  r@   r   rC   match_and_reply)rU   r  rA   r  request_responsess        r    r\  z!CompletionPlugin.receive_response  s     	   &v/@ A A	C 	C 	C &&F$/00 	) 	) $f 5>Bi():;  (((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)s   .B		BBc                    || j         vrdS t                              d                    |                     t	          | j                  5  | j         |         }d|d<   |                     |           ddd           dS # 1 swxY w Y   dS )z6Collect all provider completions and reply on timeout.Nz'Completion plugin: Request {} timed outTr  )r@   rK   rL   rk  r   rC   r  )rU   rA   r  s      r    r  z CompletionPlugin.receive_timeout  s     &&F>EEfMMNNN$/00 	) 	) $f 5-1k*  (((	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	) 	)s   (BB	Bc                 <  	 || j         vrdS | j         |         		d                                         }	d         }|                     |          }|                     ||          }|| j        v rx	d         }t          	fd|D                       }|s|r|                     |           dS dS t          	fd|D                       }|s|r|                     |           dS dS t          	fd|D                       }|r|                     |           dS dS )zw
        Decide how to send the responses corresponding to req_id to
        the instance that requested them.
        Nrm  r  r  c              3   ,   K   | ]}|d          v V  dS r  Nr   r   sourcer  s     r    	<genexpr>z3CompletionPlugin.match_and_reply.<locals>.<genexpr>  sB       ? ?#)  &):9)EE ? ? ? ? ? ?r"   c              3   N   K   | ]}d                               |          V   dS r  rp   r  s     r    r  z3CompletionPlugin.match_and_reply.<locals>.<genexpr>  sR       #C #C'- $5Y#?#C#CF#K#K #C #C #C #C #C #Cr"   c              3   N   K   | ]}d                               |          V   dS r  r  r  s     r    r  z3CompletionPlugin.match_and_reply.<locals>.<genexpr>  sJ       ? ?#)  1;??GG ? ? ? ? ? ?r"   )r@   r  r  r  r  allskip_and_replyany)
rU   rA   rm  r  r  sorted_providersr  all_returnedany_nonemptyr  s
            @r    r  z CompletionPlugin.match_and_reply  s   
 &&F M&1$Z06688$Z0"CC ::+ + t///)+6I ? ? ? ?-=? ? ? ? ?L 	0 0''/////0 0  # #C #C #C #C1A#C #C #C  C  C 0< 0''/////0 0  ? ? ? ?-=? ? ? ? ?L ,##F+++++, ,r"   c                    | j         |         }|d         t           |d                               d}| j        v r<t          fd| j                                         D             pdg          }||k    }t
                              d                    |                     | j         |= |r|                     |           dS dS )z
        Skip intermediate responses coming from the same CodeEditor
        instance for some types of requests, and send the last one to
        it.
        r  r  Tc                 t    g | ]4\  }}|d          k    r#t           |d                               k    2|5S )r  r  )id)r   rH  r   r  r  s      r    r!   z3CompletionPlugin.skip_and_reply.<locals>.<listcomp>  s\     K K Kd$0010133448III IIIr"   r  z%Completion plugin: Request {} removedN)	r@   r  SKIP_INTERMEDIATE_REQUESTSmaxitemsrK   rL   rk  gather_and_reply)rU   rA   r  do_send
max_req_idr  r  s        @@r    r  zCompletionPlugin.skip_and_reply  s    !M&1$Z0E01DEGGHH t666K K K K Kdm&9&9&;&; K K K  4	 J
 +G<CCFKKLLLM&!  	5!!"344444	5 	5r"   r  c                 p   |d         }|d         } |d                     }t                               d                    |                     |t          j        k    r|                     |          }n|                     ||          }	 |r|                    ||           dS dS # t          $ r Y dS w xY w)z
        Gather request responses from all providers and send them to the
        CodeEditor instance that requested them.
        r  r  r  zGather responses for {0}N)	rK   rL   rk  r   DOCUMENT_COMPLETIONgather_completionsgather_responseshandle_responseRuntimeError)rU   r  r  req_id_responsesr  	responsess         r    r  z!CompletionPlugin.gather_and_reply  s    
 %Z0,Y7B-.ABDD/66x@@AAA-AAA//0@AAII--h8HIII	  G!11(IFFFFFG G 	 	 	 DD	s   B' '
B54B5r  c                 t  	 | j         t          j                 	t          t	          	                                          	fd          	d |D             }g }t                      }t          	          D ]\  }}||vr
||                             dg           D ]h}|d         	                                }||v r!|
                    |           ||d         f|d<   |                    |           ||xx         dz  cc<   it                              d                    |                     d|i}|S )	z+Gather completion responses from providers.c                     |          S ry   r   )r  
prioritiess    r    r  z5CompletionPlugin.gather_completions.<locals>.<lambda>  s    *Q- r"   r  c                     i | ]}|d S )r   r   )r   r  s     r    
<dictcomp>z7CompletionPlugin.gather_completions.<locals>.<dictcomp>  s    @@@Vvq@@@r"   paramslabelsortTextr  zResponses statistics: {0})rD   r   r  r  r'  r;  r   	enumeraterp   r   addr  rK   rL   rk  )
rU   r  merge_statsr  
dedupe_setpriorityr  response
dedupe_keyr  s
            @r    r  z#CompletionPlugin.gather_completions
  ss   )"68
D!2!233 7 7 7 79 9 9
 A@/?@@@	UU
 )* 5 5 	) 	)Hf---,V4882FF ) )%g.4466
++z***(0(:2F'G$  ***F###q(####) 	077DDEEEy)	r"   r  c                 v    d}| j         |         D ]&}||v r ||                             dd          }|r n'd|iS )z7Gather responses other than completions from providers.Nr  )rD   rp   )rU   r  r  r  r  s        r    r  z!CompletionPlugin.gather_responses%  s\    *84 	 	F""$V,004@@ E(##r"   ry   )F)T)r  N)wr&   r'   r(   __doc__NAMECONF_SECTIONr   r{   r   REQUIRESr   r   r   OPTIONAL	CONF_FILErT   rS   r   CONTAINER_CLASSr   r>  intr8  r[  rX  objectr   rk   r^  rd  r   r   rZ  r   rl  r   r  r  r  r+   staticmethodra   rd   rg   rv   r   r   r   r   r   r   r   r   r   r   r   r   r   boolr   r   r   r   r   r   rQ   r   r   propertyr   r
   rm   rR   r   r  r  r  r  r  r   rJ  rM  rV  rh  rN   rr   rY  ru  rz  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  __classcell__)r]   s   @r    r2   r2   8   s	         D L#W%<=H '";W=NOHI   *O  S$//   $VFF33	 %fhh *0c):):& F3KKM VC--N "6#;;	 GG 	2"
 	2@? @? @? @? @? @?F +c + + + \+A A A A A
/ / /# # #  34446 6 546  7888	* 	* 98	*  1222A A 32A  0111	D 	D 21	D  9:::) ) ;:)
 w23338 8 438 w6777* * 87* w01117 7 217 w/000. . 10.. w8999) ) :9)5 5 5	4 	 	 	 	 D    G$uUCZ7H2I G G G G>> > >? ? ? ?$E E E E29 9 9( 6 6 X6 
TVVB B VB0&) &) &)P  *  ,  2  ,  6  0 /"0H /"58/"?C/" /" /" \/"b#3K #25#:># # # #.?2J ?14? ? ? ?8 8 84 14 1  1  1  1D6 6 6 6 
T#YY4 4 4 4 Y4s t    +c + + + +0 0)A 0 0 0 0& & & & & &
 c    C C C C C CA!#YA25A:>s)A A A A.S . . . .3 3 3 3 38 8 8
5 5 5C C C3 3 3@ @ @6 6 6F F FI I I
4 4 4
11S 11C 11d 11 11 11 11f??47?GK? ? ? ?6#s # # # # #. BL%)     , 
T#s^^,c ,S , , , ^,(c S    0 
T#sD)%()25)=A) ) ) ) 
T#YY)c ) ) ) Y)',c ', ', ', ',R5S 5 5 5 58$    .4    6$ $ $ $ $ $ $ $ $ $r"   r2   )/r  r)   r   loggingrn   typingr   r   r  packaging.versionr   pkg_resourcesr   qtpy.QtCorer   r   r	   r
   r   spyder.config.managerr   spyder.api.pluginsr   r   )spyder.api.plugin_registration.decoratorsr   r   spyder.config.baser   r   spyder.config.userr   spyder.plugins.completion.apir   r   r   "spyder.plugins.completion.confpager   #spyder.plugins.completion.containerr   	getLoggerr&   rK   dirrQ  r0   r2   r   r"   r    <module>r     s          				          $ # # # # # + + + + + + B B B B B B B B B B B B B B ' & & & & & 6 6 6 6 6 6 6 6- - - - - - - - 6 6 6 6 6 6 6 6 ( ( ( ( ( (B B B B B B B B B B D C C C C C C C C C C C 
	8	$	$L L #$: ; ;L L L   u$ u$ u$ u$ u$~ u$ u$ u$ u$ u$r"   