Skip to main content

A Sopel plugin for declaring subcommands

Project description

This plugin for the IRC bot Sopel allows for

Installation

$ pip install sopel-subcmd

Example usage

Import the SubcommandDispatcher class to your plugin, register handlers for your desired subcommands, and call it with the bot, trigger associated with your event. The return value indicates if a subcommand handler was found and called. Note that exceptions from handlers are allowed to propagate freely.

from sopel import plugin
from sopel_subcmd import SubcommandDispatcher


dispatcher = SubcommandDispatcher()

@dispatcher.register
def dummy_subcmd1(bot, trigger, *args, **kwargs):
    bot.say(f"dummy:subcmd1 subcommand (args={args!r}, kwargs={kwargs!r})")


@dispatcher.register
def dummy_subcmd2(bot, trigger, *args, **kwargs):
    bot.say(f"dummy:subcmd2 subcommand (args={args!r}, kwargs={kwargs!r})")


@plugin.commands(
        "dummy",
        "dummy:subcmd1",
        "dummy:subcmd2",
        "dummy:fakesub",  # this pattern has no dedicated handler, we will use the base
)
def dummy(bot, trigger):
    # We can do some computations common to every command before dispatch, if appropriate
    data = 42
    moredata = "Twas brillig and the slithy toves"

    # automatically hand off to the subcommand handlers, if appropriate
    if dispatcher.dispatch_subcmd(bot, trigger, data, moredata=moredata):
        return

    # we don't *have* to pass data to the handler if ``bot, trigger`` would be enough
    # if _dispatch_subcmd(bot, trigger):
    #     return

    bot.say(f"base command, invoked as {trigger.group(0)!r}")

The above sample plugin produces the following behavior:

<SnoopJ> !dummy
<testibot> base command, invoked as '!dummy'
<SnoopJ> !dummy:subcmd1
<testibot> dummy:subcmd1 subcommand (args=(42,), kwargs={'moredata': 'Twas brillig and the slithy toves'})
<SnoopJ> !dummy:subcmd2
<testibot> dummy:subcmd2 subcommand (args=(42,), kwargs={'moredata': 'Twas brillig and the slithy toves'})
<SnoopJ> !dummy:fakesub
<testibot> base command, invoked as '!dummy:fakesub'
<SnoopJ> !version
<testibot> [version] Sopel v8.0.0.dev0 | Python: 3.7.16 | Commit: b5eba03ce74baae36e3456ac938686fb23f5671b

Unicode support

Because Python has excellent support for Unicode identifiers, you can dispatch to functions whose names are written in nontrivial scripts:

from sopel_subcmd import SubcommandDispatcher


dispatcher = SubcommandDispatcher()

@dispatcher.register
def dummy_猫(bot, trigger, *args, **kwargs):
    bot.say("にゃあああー")


# ç = U+0063 U+0327
@dispatcher.register
def dummy_çava(bot, trigger, *args, **kwargs):
    bot.say("ça va")


@dispatcher.register
def dummy_パイソン(bot, trigger, *args, **kwargs):
    bot.say("\N{SNAKE}")


@plugin.commands(
        "dummy",
        "dummy:猫",

        # NOTE:we need to repeat our command for Sopel to match different codepoint sequences,
        # but dispatch will find the function whose name is equivalent under NFKC normalization (which Python uses)
        "dummy:çava",        # ç = U+00e7
        "dummy:çava",        # ç = U+0063 U+0327
        "dummy:パイソン",
        "dummy:パイソン",
)
def dummy(bot, trigger):
    # We can do some computations common to every command before dispatch, if appropriate
    data = 42
    moredata = "Twas brillig and the slithy toves"

    # automatically hand off to the subcommand handlers, if appropriate
    if dispatcher.dispatch_subcmd(bot, trigger, data, moredata=moredata):
        return

    bot.say(f"base command, invoked as {trigger.group(0)!r}")

Which makes the feature a little more transparent on the user-facing side

<SnoopJ> !dummy:猫
<testibot> にゃあああー
<SnoopJ> !dummy:çava
<testibot> ça va
<SnoopJ> !dummy:çava
<testibot> ça va
<SnoopJ> !dummy:パイソン
<testibot> 🐍
<SnoopJ> !dummy:パイソン
<testibot> 🐍

Misc.

If needed, you can check the version of this plugin using Sopel's version command:

<SnoopJ> !version sopel-subcmd
<testibot> [version] sopel-subcmd v1.0.0

Known issues

  • subcommands whose names are invalid function names are not normalized

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sopel-subcmd-1.0.0.tar.gz (4.9 kB view details)

Uploaded Source

Built Distribution

sopel_subcmd-1.0.0-py3-none-any.whl (5.0 kB view details)

Uploaded Python 3

File details

Details for the file sopel-subcmd-1.0.0.tar.gz.

File metadata

  • Download URL: sopel-subcmd-1.0.0.tar.gz
  • Upload date:
  • Size: 4.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for sopel-subcmd-1.0.0.tar.gz
Algorithm Hash digest
SHA256 797c8fee88101c607d20de581d3bc099e14b3cf51b92db2c2e7e480c6db3ef50
MD5 f2cd7b88c749cc1e7549ed050b178b36
BLAKE2b-256 c91f621aa131537a4bb51dde2da2ed0e9f81ceb81dbe276d0a9d31824cef1c64

See more details on using hashes here.

File details

Details for the file sopel_subcmd-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for sopel_subcmd-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8452eb9e48a800d7157039b2a22a74e9d7a7515a4b5da94266295358ef350583
MD5 c1672cd97d2904298b00b4d0f9110696
BLAKE2b-256 bef4c83c86530e12c29bc60d2a0e2865c52b53ad69e2db58450551b3ca6237de

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page