Mode Messages#

Mode management for IRC channels.

The ModeParser class is used internally by the bot to parse MODE messages for channels. User modes are not parsed (yet), as the bot doesn’t manage them.

The goal of the parser is to return a ModeMessage containing the actions represented by the raw message:

  • channel modes added/removed (including their parameters, if any)

  • privileges added/removed for user(s) in a channel

Errors (ignored modes and unused parameters) are also included, mostly for detecting when an IRC server is not conforming to specifications.

Important

This is mostly for internal use only as plugin developers should be more interested in privileges rather than how Sopel knows about them.

The interface of this module is subject to change between Sopel releases without advance notice, even in patch versions.

New in version 8.0.

sopel.irc.modes.DEFAULT_MODETYPE_PARAM_CONFIG = {'A': ParamRequired.ALWAYS, 'B': ParamRequired.ALWAYS, 'C': ParamRequired.ADDED, 'D': ParamRequired.NEVER}#

Default parameter requirements for mode types.

sopel.irc.modes.ModeDetails#

Tuple of mode details as (letter, mode, is_added, param).

Where type is the mode type (such as A, B, C, D); mode is the mode letter; is_added tells if the mode should be added or removed; and param is an optional parameter value for that mode only when necessary.

alias of Tuple[str, str, bool, Optional[str]]

exception sopel.irc.modes.ModeException#

Base exception class for mode management.

class sopel.irc.modes.ModeMessage#

Mode message with channel’s modes and channel’s privileges.

ignored_modes: tuple[ModeTuple, ...]#

Ignored modes when they are unknown or there is a missing parameter.

Each item is a ModeTuple.

leftover_params: tuple[str, ...]#

Parameters not used by any valid mode or privilege.

modes: tuple[ModeDetails, ...]#

Tuple of added and removed modes.

Each item is a ModeDetails.

privileges: tuple[PrivilegeDetails, ...]#

Tuple of added and removed privileges.

Each item is a PrivilegeDetails.

class sopel.irc.modes.ModeParser(
chanmodes: dict[str, tuple[str, ...]] = CHANMODES,
type_params: dict[str, ParamRequired] = DEFAULT_MODETYPE_PARAM_CONFIG,
privileges: set[str] = PRIVILEGES,
)#

ModeMessage parser for IRC’s MODE messages for channel modes.

CHANMODES = {'A': ('b', 'e', 'I'), 'B': ('k',), 'C': ('l',), 'D': ('O', 'i', 'm', 'n', 'p', 's', 'r', 't')}#

Default CHANMODES per RFC 2811.

Note

Mode a has been removed from the default list, as it appears to be a relic of the past and is more commonly used as a privilege.

Mode q has been removed too, as it is commonly used as a privilege.

If a server is unhappy with these defaults, they should advertise CHANMODES and PREFIX properly.

PRIVILEGES: set[str] = {'Y', 'a', 'h', 'o', 'q', 'v', 'y'}#

Set of user privileges used by default.

chanmodes: dict[str, tuple[str, ...]]#

Map of mode types (str) to their lists of modes (tuple).

This map should come from ISUPPORT, usually through bot.isupport.CHANMODES.

get_mode_info(mode: str, is_added: bool) tuple[str, bool]#

Retrieve mode’s information when added or removed.

Raises:
Returns:

a tuple with two values: the mode type and if it requires a parameter

>>> chanmodes = {'A': tuple('beI'), 'B': tuple('k')}
>>> t_params = {
...     'A': ParamRequired.ALWAYS,
...     'B': ParamRequired.ADDED,
... }
>>> mm = ModeParser(chanmodes, t_params)
>>> mm.get_mode_info('e', False)
('A', True)
>>> mm.get_mode_info('k', False)
('B', False)
>>> mm.get_mode_info('e', True)
('A', True)
>>> mm.get_mode_info('k', True)
('B', True)

Note

A user privilege mode doesn’t have a type and will trigger a ModeTypeUnknown exception.

get_mode_type(mode: str) str#

Retrieve the type of mode.

Raises:

ModeTypeUnknown – if the mode’s type cannot be determined

Returns:

the mode’s type as defined by chanmodes

>>> mm = ModeParser({'A': tuple('beI'), 'B': tuple('k')}, {})
>>> mm.get_mode_type('b')
'A'
>>> mm.get_mode_type('k')
'B'

This method will raise a ModeTypeUnknown if the mode is unknown, including the case where mode is actually a user privilege such as v.

parse(modestring: str, params: tuple[str, ...]) ModeMessage#

Parse a modestring for a channel with its params.

Parameters:
  • modestring – suite of modes with +/- sign, such as +b-v

  • params – tuple of parameters as given by the MODE message

Returns:

the parsed and validated information for that modestring

This method parses a modestring, i.e. a suite of modes and privileges with + and - signs. The result is a ModeMessage with:

  • parsed modes, with their parameters when required

  • parsed privileges, with their parameters

  • ignore modes (unknown and invalid modes)

  • leftover parameters (parameter unused)

For example this message:

:irc.example.com MODE #foobar -o+vi mario luigi bowser

Should be parsed like this:

>>> modestring = '-o+vi'
>>> params = ('mario', 'luigi', 'bowser')
>>> modes = modeparser.parse(modestring, params)
>>> modes.modes
(('D', 'i', True, None),)
>>> modes.privileges
(('o', False, 'mario'), ('v', True, 'luigi'))
>>> modes.leftover_params
('bowser',)

The modestring -o+vi means:

* remove ``o`` privileges to user ``mario``
* add ``v`` privileges to user ``luigi``
* set ``i`` mode on channel ``#foobar`` (no parameter required)

Which means that bowser shouldn’t be here, and can be retrieved through the leftover_params attribute.

privileges#

Set of valid user privileges.

This set should come from ISUPPORT, usually through bot.isupport.PREFIX.

If a server doesn’t advertise its prefixes for user privileges, PRIVILEGES will be used as a default value.

type_params#

Map of mode types (str) with their param requirements.

This map defaults to DEFAULT_MODETYPE_PARAM_CONFIG.

sopel.irc.modes.ModeTuple#

Tuple of mode information: (mode, is_added).

Where mode is the mode or privilege letter and is_added tells if the mode or privilege wants to be added or removed.

This type alias represents the basic information for each mode found when parsing a modestring like +abc-efg. In that example mode a and mode f would be represented as these tuples: ('a', True) and ('f', False).

alias of Tuple[str, bool]

exception sopel.irc.modes.ModeTypeImproperlyConfigured(mode: str, letter: str)#

Exception when the mode’s type management is not configured properly.

exception sopel.irc.modes.ModeTypeUnknown(mode: str)#

Exception when a mode’s type is unknown or cannot be determined.

class sopel.irc.modes.ParamRequired(value)#

Enum of param requirement for mode types.

ADDED = 'added'#

The mode type requires a parameter only when the mode is added.

ALWAYS = 'always'#

The mode type always requires a parameter.

NEVER = 'never'#

The mode type never requires a parameter.

REMOVED = 'removed'#

The mode type requires a parameter only when the mode is removed.

sopel.irc.modes.PrivilegeDetails#

Tuple of privilege details as (mode, is_added, param)

Where privilege is the privilege letter; is_added tells if the privilege should be added or removed; and target is the target for that privilege.

alias of Tuple[str, bool, str]

sopel.irc.modes.parse_modestring(modestring: str) Iterator[ModeTuple]#

Parse a modestring like +abc-def and yield ModeTuple.