Source code for spyder.api.plugin_registration.decorators

# -----------------------------------------------------------------------------
# Copyright (c) 2021- Spyder Project Contributors
#
# Released under the terms of the MIT License
# (see LICENSE.txt in the project root directory for details)
# -----------------------------------------------------------------------------

"""
Spyder API plugin registration decorators.
"""

from __future__ import annotations

# Standard library imports
import functools
from collections.abc import Callable


[docs] def on_plugin_available( func: Callable | None = None, plugin: str | None = None, ) -> Callable: """ Decorate a method to be called back when a specific plugin becomes ready. The decorated method must be a member of a :class:`~spyder.api.plugins.SpyderPluginV2` subclass for the decorator to work as intended. Methods to be decorated must have the signature .. code-block:: python def method(self): ... when observing a single plugin, or .. code-block:: python def method(self, plugin: str): ... when observing all plugins listed as dependencies. .. caution:: Any ``plugin``\\(s) specified must be listed under either the :attr:`~spyder.api.plugins.SpyderPluginV2.REQUIRES` or :attr:`~spyder.api.plugins.SpyderPluginV2.OPTIONAL` class constants of the plugin's :class:`~spyder.api.plugins.SpyderPluginV2` class. If not, a :exc:`~spyder.api.exceptions.SpyderAPIError` will be raised when the plugin class is initialized. Parameters ---------- func: Callable | None, optional Method to decorate, passed automatically when applying the decorator. plugin: str | None, optional Name of the requested plugin whose availability triggers ``func``. If ``None`` (the default), observes all plugins listed as dependencies. Must be listed under the class' ':attr:`~spyder.api.plugins.SpyderPluginV2.REQUIRES` or :attr:`~spyder.api.plugins.SpyderPluginV2.OPTIONAL` class constants, or else a :exc:`~spyder.api.exceptions.SpyderAPIError` will be raised. Returns ------- func: Callable The method passed as ``func`` with the plugin listener set up. Raises ------ SpyderAPIError When initializing a plugin class with decorated methods, if trying to watch a ``plugin`` that is not listed in the plugin class' :attr:`~spyder.api.plugins.SpyderPluginV2.REQUIRES` or :attr:`~spyder.api.plugins.SpyderPluginV2.OPTIONAL` class constants. """ if func is None: return functools.partial(on_plugin_available, plugin=plugin) if plugin is None: # Use special __all identifier to signal that the function # observes all plugins listed as dependencies. plugin = "__all" func._plugin_listen = plugin return func
[docs] def on_plugin_teardown( func: Callable | None = None, plugin: str | None = None, ) -> Callable: """ Decorate a method to be called back when tearing down a specific plugin. The decorated method must be a member of a :class:`~spyder.api.plugins.SpyderPluginV2` subclass for the decorator to work as intended. The decorator will be called **before** the specified ``plugin`` is deleted and also **before** the plugin that uses the decorator is destroyed. Methods that use this decorator must have the signature .. code-block:: python def method(self): ... .. important:: A plugin name must be passed to ``plugin``. While a default of ``None`` is accepted due to technical limitations, it will raise a :exc:`ValueError` at runtime. .. caution:: Any ``plugin``\\(s) specified must be listed under either the :attr:`~spyder.api.plugins.SpyderPluginV2.REQUIRES` or :attr:`~spyder.api.plugins.SpyderPluginV2.OPTIONAL` class constants of the plugin's :class:`~spyder.api.plugins.SpyderPluginV2` class. If not, a :exc:`~spyder.api.exceptions.SpyderAPIError` will be raised when the plugin class is initialized. Parameters ---------- func: Callable | None, optional Method to decorate, passed automatically when applying the decorator. plugin: str Name of the requested plugin whose teardown triggers ``func``. While ``None``, the default, is accepted for technical reasons, :exc:`ValueError` is raised if a plugin name is not passed. Must be listed under the class' ':attr:`~spyder.api.plugins.SpyderPluginV2.REQUIRES` or :attr:`~spyder.api.plugins.SpyderPluginV2.OPTIONAL` class constants, or else a :exc:`~spyder.api.exceptions.SpyderAPIError` will be raised. Returns ------- func: Callable The method passed as ``func`` with the plugin listener set up. Raises ------ ValueError If an explicit plugin name is not passed to ``plugin``. SpyderAPIError When initializing a plugin class with decorated methods, if trying to watch a ``plugin`` that is not listed in the plugin class' :attr:`~spyder.api.plugins.SpyderPluginV2.REQUIRES` or :attr:`~spyder.api.plugins.SpyderPluginV2.OPTIONAL` class constants. """ if func is None: return functools.partial(on_plugin_teardown, plugin=plugin) if plugin is None: raise ValueError( "on_plugin_teardown must have a well defined " "plugin keyword argument value, " "e.g., plugin=Plugins.Editor" ) func._plugin_teardown = plugin return func