sopel.plugins.callables¶
Plugin object definitions.
Added in version 8.1.
The core of a plugin consists of several objects, either plugin callables or
plugin jobs. These objects are represented by instances of
PluginCallable and PluginJob respectively.
See also
The decorators in sopel.plugin create these objects directly.
Important
This is all relatively new. Its usage and documentation is for Sopel core development. It is subject to rapid changes between versions without much (or any) warning.
Do not build your plugin based on what is here, you do not need to.
Create a plugin decorator¶
Under the hood each decorator of sopel.plugin creates an instance of
PluginCallable and sets various properties. Upon loading the plugin,
Sopel will collect all instances of PluginCallable, to create the
appropriate rule handlers (see sopel.plugins.rules).
The structure of a typical decorator without any parameters looks like this:
def decorator(
function: TypedPluginCallableHandler | AbstractPluginObject
) -> PluginCallable:
# ensure that you have an instance of PluginCallable
handler = PluginCallable.ensure_callable(function)
# do something with the handler
# ...
# return the PluginCallable
return handler
The decorator can then be used like this:
@decorator
def some_plugin_function(bot: SopelWrapper, trigger: Trigger) -> None:
# do something here
...
The key behaviors of a plugin decorator are to:
ensure an instance of one of
PluginCallable,PluginJob, orPluginGenericoperate on the object
return the updated object
Everything else is mostly dealing with the various way you can use a decorator.
See also
All the decorators in sopel.plugin follow this structure, and they
can be taken as implementation examples.
Plugin object reference¶
- class sopel.plugins.callables.AbstractPluginObject(handler: Callable)¶
Abstract definition of a plugin object.
- Parameters:
handler – the function to execute when calling the plugin object
A plugin object encapsulates the logic and attributes required for a plugin to register and execute this object.
Added in version 8.1.
- classmethod from_plugin_object(
- obj: AbstractPluginObject,
Convert a plugin
objto this type of plugin object.- Parameters:
obj – the plugin object to convert from
- Returns:
an instance of the new plugin object from
obj
This class method will create a new instance of plugin object based on
obj’s generic attributes (like its label) and the same callable, assumingobjis a different type of plugin object.See also
The
@labeldecorator returns aPluginGenericthat needs to be converted into a plugin callable or a plugin job by this class method.
- abstract get_handler() Callable¶
Return this plugin object’s handler.
- Returns:
the plugin object’s handler
- label: str | None¶
Identifier of the plugin callable.
Can be set manually to define a human readable identifier.
- plugin_name: str | None¶
Name of the plugin that this plugin object is for.
Set automatically by Sopel when loading a plugin object.
- class sopel.plugins.callables.Capability(
- *cap_req: str,
- handler: CapabilityHandler | None = None,
Capability request representation.
See also
The decorator
sopel.plugin.capability().- callback(
- bot: SopelWrapper,
- acknowledged: bool,
Execute the acknowlegement callback of a capability request.
- Parameters:
bot – a Sopel instance
acknowledged – tell if the capability request is acknowledged (
True) or deny (False)
- Returns:
a 2-value tuple that contains if the request is done and the result of the handler (if any)
It executes the handler when the capability request receives an acknowledgement (either positive or negative), and returns the result. The handler’s return value is used to know if the capability request is done, or if the bot must wait for resolution from the plugin that requested the capability.
This method returns a 2-value tuple:
the first value tells if the negotiation is done for this request
the second is the handler’s return value (if any)
If no handler is registered, this automatically returns
(True, None), as the negotiation is considered done (without any result).This doesn’t prevent the handler from raising an exception.
- property cap_req: tuple[str, ...]¶
Capability request as a sorted tuple.
This is the capability request that will be sent to the server as is. A request is acknowledged or denied for all the capabilities it contains, so the request
(example/cap1, example/cap2)is not the same as two requests, one forexample/cap1and the other forexample/cap2. This makes each request unique.
- class sopel.plugins.callables.CapabilityHandler(*args, **kwargs)¶
Protocoldefinition for capability handler.When a plugin requests a capability, it can define a callback handler for that request using the
capability()decorator. That handler will be called upon Sopel receiving either anACK(capability enabled) or aNAK(capability denied) CAP message.Example:
from sopel import plugin from sopel.bot import SopelWrapper @plugin.capability('example/cap-name') def capability_handler( cap_req: tuple[str, ...], bot: SopelWrapper, acknowledged: bool, ) -> plugin.CapabilityNegotiation: if acknowledged: # do something if acknowledged # i.e. # activate a plugin's feature pass else: # do something else if not # i.e. use a fallback mechanism # or deactivate a plugin's feature if needed pass # always return if Sopel can send "CAP END" (DONE) # or if the plugin must notify the bot for that later (CONTINUE) return plugin.CapabilityNegotiation.DONE
Note
This protocol class should be used for type checking and documentation purposes only.
- class sopel.plugins.callables.CapabilityNegotiation(
- value,
- names=_not_given,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Capability Negotiation status.
- CONTINUE = 2¶
The capability negotiation must continue.
This must be returned by a capability request handler to signify to the bot that the capability requires further processing (e.g. SASL authentication) and negotiation must not end yet.
The plugin author MUST signal the bot once the negotiation is done.
- DONE = 1¶
The capability negotiation can end.
This must be returned by a capability request handler to signify to the bot that the capability has been properly negotiated and negotiation can end if all other conditions are met.
- ERROR = 3¶
The capability negotiation callback was improperly executed.
If a capability request’s handler returns this status, or if it raises an exception, the bot will mark the request as errored. A handler can use this return value to inform the bot that something wrong happened, without being an error in the code itself.
- class sopel.plugins.callables.PluginCallable(handler: TypedPluginCallableHandler)¶
Plugin callable, i.e. execute a plugin function when triggered.
- Parameters:
handler – a function to be called when the plugin callable is invoked
Note
You can guard against execution with
predicates: all predicates must returnTruefor the callable to execute.- classmethod ensure_callable( ) PluginCallable¶
Ensure that
objis a plugin callable.- Parameters:
obj – a function or a plugin object
- Returns:
a properly defined plugin callable
If
objis already an instance ofAbstractPluginObject, it is converted into a plugin callable. Otherwise, a new plugin callable is created, using theobjas its handler.
- get_handler() TypedPluginCallableHandler¶
Return this plugin object’s handler.
- Returns:
the plugin object’s handler
- property is_generic_rule: bool¶
Check if the callable is a generic rule.
A generic rule is a trigger condition without any specific pattern outside of the plugin defined regex.
Note
This will return true if no pattern is defined but at least an event or a CTCP is required without the callable being a named rule or an URL callback.
- property is_limitable: bool¶
Check if the callable is subject to rate limiting.
- Returns:
Trueif it is subject to rate limiting
Limitable callables aren’t necessarily triggerable directly, but they all must pass through Sopel’s rate-limiting machinery during dispatching.
- property is_named_rule: bool¶
Check if the callable is a named rule.
A named rule is anything with a name in it: commands, nickname commands, or action commands.
- property is_triggerable: bool¶
Check if the callable can handle the bot’s triggers.
- Returns:
Trueif it can handle the bot’s triggers
A triggerable is a callable that will be used by the bot to handle a particular trigger (i.e. an IRC message): it can be a regex rule, an event, a CTCP command, a command, a nickname command, or an action command, or even a URL callback. However, it must not be a job.
See also
Many of the decorators defined in
sopel.pluginmake the decorated function a triggerable object.
- property is_url_callback: bool¶
Check if the callable can handle a URL callback.
- Returns:
Trueif it can handle a URL callback
A URL callback handler is a callable that will be used by the bot to handle a particular URL in an IRC message.
See also
Both
sopel.plugin.url()sopel.plugin.url_lazy()make the decorated function a URL callback handler.
- predicates: list[TypedCallablePredicate]¶
List of predicates used to allow or prevent execution.
- priority: Literal['low', 'medium', 'high']¶
Priority of execution.
Plugin callables with a high priority will be executed before medium and low priority callables.
- replace_handler(
- handler: TypedPluginCallableHandler,
Replace this plugin object’s handler.
- Returns:
the plugin object’s previous handler
- setup(settings: Config) None¶
Setup of the plugin callable.
- Parameters:
settings – the bot’s configuration
This method will be called by the bot before registering the callable. It ensures the value of various meta-data.
- class sopel.plugins.callables.PluginGeneric(handler: Callable)¶
Generic plugin object, used as a container for common properties.
Some properties of a plugin object are not tied to a specific role, i.e., it is not possible to know what kind of object it is when setting these properties. This is useful when creating decorators that need to set these:
Note
Other plugin object classes should not subclass
PluginGenericand always subclassAbstractPluginObjectinstead.Added in version 8.1.
- classmethod ensure_callable(
- obj: Callable | AbstractPluginObject,
Ensure that
objis a proper plugin object.- Parameters:
obj – a function or a plugin object
- Returns:
a properly defined plugin object
If
objis already an instance ofAbstractPluginObject, it is returned as-is. Otherwise, a newPluginGenericis created from it.Note
Since a generic plugin object doesn’t hold much value, it never converts a specific plugin object into a generic one as to prevent meta-data loss.
- class sopel.plugins.callables.PluginJob(handler: TypedPluginJobHandler)¶
- classmethod ensure_callable( ) PluginJob¶
Ensure that
objis a plugin job.- Parameters:
obj – a function or a plugin object
- Returns:
a properly defined plugin job
If
objis already an instance ofAbstractPluginObject, it is converted into a plugin job. Otherwise, a new plugin job is created, using theobjas its handler.
- get_handler() TypedPluginJobHandler¶
Return this plugin object’s handler.
- Returns:
the plugin object’s handler
- replace_handler(
- handler: TypedPluginJobHandler,
Replace this plugin object’s handler.
- Returns:
the plugin object’s previous handler
- class sopel.plugins.callables.TypedCallablePredicate(*args, **kwargs)¶
Protocol definition of a plugin callable predicate function.
A predicate function must accept two positional arguments:
an instance of
SopelWrapperan instance of
Trigger
And it must return a boolean:
if True, the plugin callable can execute
otherwise, the predicate prevents the execution of the plugin callable
Added in version 8.1.
- class sopel.plugins.callables.TypedPluginCallableHandler(*args, **kwargs)¶
Protocol definition of a plugin callable handler function.
A callable handler function must accept two positional arguments:
an instance of
SopelWrapperan instance of
Trigger
Added in version 8.1.
- class sopel.plugins.callables.TypedPluginJobHandler(*args, **kwargs)¶
Protocol definition of a plugin job handler function.
A job handler function must accept one positional argument:
an instance of
Sopel
Added in version 8.1.
- class sopel.plugins.callables.TypedPluginObject¶
A
TypeVarbound toAbstractPluginObject.When used in the
AbstractPluginObject.from_plugin_object()class method, it means the return value must be an instance of the class used to call that method and not a different subclass ofAbstractPluginObject.Added in version 8.1.
alias of TypeVar(‘TypedPluginObject’, bound=
AbstractPluginObject)
- sopel.plugins.callables.clean_callable(func, config)¶
Clean the callable. (compile regexes, fix docs, set defaults)
- Parameters:
func (callable) – the callable to clean
config (
sopel.config.Config) – Sopel’s settings
This function will set all the default attributes expected for a Sopel callable, i.e. properties related to threading, docs, examples, rate limiting, commands, rules, and other features.
Deprecated since version 8.1: This function is made obsolete by the new plugin callable system and will be removed in Sopel 9.
Changed in version 8.1: This function used to be defined in
sopel.loaderbut was moved into thesopel.pluginsinternal machinery.
- sopel.plugins.callables.clean_module(
- module: ModuleType,
- config: Config,
Clean a module and return its command, rule, job, etc. callables.
- Parameters:
module (module) – the module to clean
config (
sopel.config.Config) – Sopel’s settings
- Returns:
a tuple with triggerable, job, shutdown, and url functions
- Return type:
This function will parse the
modulelooking for callables:shutdown actions
triggerables (commands, rules, etc.)
jobs
URL callbacks
This function will set all the default attributes expected for a Sopel callable, i.e. properties related to threading, docs, examples, rate limiting, commands, rules, and other features.
Changed in version 8.1: This function used to be defined in
sopel.loaderbut was moved into thesopel.pluginsinternal machinery.
- sopel.plugins.callables.is_limitable(obj)¶
Check if
objneeds to carry attributes related to limits.- Parameters:
obj – any function to check
- Returns:
Trueifobjmust have limit-related attributes
Limitable callables aren’t necessarily triggerable directly, but they all must pass through Sopel’s rate-limiting machinery during dispatching. Therefore, they must have the attributes checked by that machinery.
Deprecated since version 8.1: This function is made obsolete by the new plugin callable system and will be removed in Sopel 9.
- sopel.plugins.callables.is_triggerable(obj)¶
Check if
objcan handle the bot’s triggers.- Parameters:
obj – any function to check
- Returns:
Trueifobjcan handle the bot’s triggers
A triggerable is a callable that will be used by the bot to handle a particular trigger (i.e. an IRC message): it can be a regex rule, an event, a CTCP command, a command, a nickname command, or an action command. However, it must not be a job or a URL callback.
See also
Many of the decorators defined in
sopel.pluginmake the decorated function a triggerable object.Deprecated since version 8.1: This function is made obsolete by the new plugin callable system and will be removed in Sopel 9.
- sopel.plugins.callables.is_url_callback(obj)¶
Check if
objcan handle a URL callback.- Parameters:
obj – any function to check
- Returns:
Trueifobjcan handle a URL callback
A URL callback handler is a callable that will be used by the bot to handle a particular URL in an IRC message.
See also
Both
sopel.plugin.url()sopel.plugin.url_lazy()make the decorated function a URL callback handler.Deprecated since version 8.1: This function is made obsolete by the new plugin callable system and will be removed in Sopel 9.