Base library

The base elements of the library. Implements the foundation for extension loading, events handling, and protocol parsing.

auxparse

Parsing for various IRC mini-languages.

IRC has a mini-language/grammar fetish and uses them extensively to compensate for the fact that RFC1459 frames are deficient, to be excessively generous.

This module has various parsers for some of them (by no means exhaustive - and that's probably not even possible, given everyone and their dog seems to love inventing new ones for no discernible reason).

Hopefully one day this module will disappear, when IRC gets a sane framing format. Until that day comes, this needs to be here.

class PyIRC.auxparse.CTCPMessage(msgtype, command, target, param)

Represent a CTCP message.

>>> CTCPMessage("PRIVMSG", "PING", "#Sporks", "lol")
... 
CTCPMessage(...='PRIVMSG', ...='PING', ...='#Sporks', ...='lol')
>>> CTCPMessage("PRIVMSG", "PING", "#Sporks", "lol").line
... 
Line(..., command='PRIVMSG', params=['#Sporks', '\x01PING lol\x01'])
>>> line = Line(tags=None, hostmask=None, command='PRIVMSG',
... params=['#test', '\x01TEST TEST\x01'])
>>> CTCPMessage.parse(line)
... 
CTCPMessage(msgtype='PRIVMSG', ...='TEST', ...='#test', param='TEST')
line

Return a Line instance representing this CTCP message

classmethod parse(line)

Return a new CTCPMessage from the Line instance specified.

class PyIRC.auxparse.ParsedPrefix(mode_to_prefix, prefix_to_mode)
mode_to_prefix

Alias for field number 0

prefix_to_mode

Alias for field number 1

PyIRC.auxparse.banmask_parse(string, supported_extban)

Normalise a ban mask into either an extban or nick!user@host set

PyIRC.auxparse.isupport_parse(params)

Parse an ISUPPORT string into a dictionary. Uses the params derived from line params.

>>> isupport_parse(["CHANTYPES=a,b,cdefg"])
{'CHANTYPES': ('a', 'b', 'cdefg')}
>>> isupport_parse(["EXCEPTS"])
{'EXCEPTS': True}
>>> isupport_parse(["PREFIX=(ov)@+"])
{'PREFIX': '(ov)@+'}
>>> isupport_parse(["EXTBAN=,ABCNOQRSTUcjmprsz"])
{'EXTBAN': ('', 'ABCNOQRSTUcjmprsz')}
>>> isupport_parse(["MAXLIST=ACCEPT:5"])
{'MAXLIST': {'ACCEPT': '5'}}
>>> sorted(isupport_parse(["MAXLIST=ACCEPT:,TEST:5"])["MAXLIST"].items())
[('ACCEPT', None), ('TEST', '5')]
>>> sorted((k,v) for k, v in isupport_parse(["EXCEPTS", "INVEX"]).items())
[('EXCEPTS', True), ('INVEX', True)]
PyIRC.auxparse.mode_parse(modes, params, modegroups, prefix)

Parse IRC mode strings

A generator that yields (modechar, param, adding). param may be None. adding will either be True or False, depending on what is happening to the mode.

Parameters:
  • modes -- Initial string of modes (should resemble +blah/-blah or some such).
  • params -- Parameters for the modes, likely the remaining parameters after modes.
  • modegroups -- The item from the isupport string CHANMODES.
  • prefix -- The mode prefixes from the isupport string PREFIX, optionally parsed by prefix_parse.
>>> modegroups = ("beIq", "k", "flj", "ac")
>>> prefixmodes = "(ov)@+"
>>> f = lambda x: [(char, param, adding) for char, param, adding in x]
>>> f(mode_parse("+oba", ("a", "b"), modegroups, prefixmodes))
[('o', 'a', True), ('b', 'b', True), ('a', None, True)]
>>> f(mode_parse("+o-o", ("a", "a"), modegroups, prefixmodes))
[('o', 'a', True), ('o', 'a', False)]
>>> f(mode_parse("+k-k", ("test",), modegroups, prefixmodes))
[('k', 'test', True), ('k', None, False)]
>>> f(mode_parse("+bf-k+b", ("a", "b", "c"), modegroups, prefixmodes))
[('b', 'a', True), ('f', 'b', True), ('k', None, False), ('b', 'c', True)]
>>> prefixmodes = prefix_parse(prefixmodes)
>>> f(mode_parse("+ov-v", ("a", "b", "c"), modegroups, prefixmodes))
[('o', 'a', True), ('v', 'b', True), ('v', 'c', False)]
PyIRC.auxparse.prefix_parse(prefix)

Parse ISUPPORT PREFIX extension into mode : prefix and vice versa.

Parameters:prefix -- Prefix string to parse (e.g., (ov)@+)

Note

If prefix and modes are not properly balanced, ValueError will be raised.

>>> [sorted(p.items()) for p in prefix_parse("(ov)@+")]
[[('o', '@'), ('v', '+')], [('+', 'v'), ('@', 'o')]]
>>> [sorted(p.items()) for p in prefix_parse("(qahov)~&%@+")]
... 
[[('a', '&'), ..., ('~', 'q')]]
>>> prefix_parse("(ov)@+")[1]["@"]
'o'
>>> prefix_parse("(ov)@+")[0]["o"]
'@'
>>> prefix_parse("(o)@+")
Traceback (most recent call last):
    ...
ValueError: Unbalanced modes and prefixes
PyIRC.auxparse.status_prefix_parse(string, prefix)

Parse a string containing status sigils.

Parameters:
  • string -- Nick or channel containing leading sigils.
  • prefix -- The mode prefixes from ISupport.supported['PREFIX'], optionally parsed by prefix_parse.
Returns:

(status, string) tuple, where status is a set of the statuses. string is the string with all leading status sigils removed.

>>> status_prefix_parse("@#channel", "(ov)@+")
({'o'}, '#channel')
>>> status_prefix_parse("+#ch@nnel", "(ov)@+")
({'v'}, '#ch@nnel')
>>> status_prefix_parse("+#", "(ov)@+")
({'v'}, '#')
>>> modes, channel = status_prefix_parse("@+#", "(ov)@+")
>>> sorted(modes), channel
(['o', 'v'], '#')
PyIRC.auxparse.userhost_parse(mask)

Parse a USERHOST reply.

Returns:An object with the following attributes set:
hostmask:Hostmask of the user. This may be a cloak.
operator:Whether or not the user is an operator. False does not mean they are not an operator, as operators may be hidden on the server.
away:Whether or not the user is away.
PyIRC.auxparse.who_flag_parse(flags)

Parse WHO flags.

Parameters:flags -- Flags to parse.
Returns:A namespace object containing the following attributes:
operator:Whether or not the user is an operator.
away:Whether or not the user is away.
modes:A set of the user's present modes (prefixes).

base

Library base classes

Contains the most fundamental parts of PyIRC. This is the glue that binds everything together.

class PyIRC.base.IRCBase(serverport, username, nick, gecos, extensions, **kwargs)

The base IRC class meant to be used as a base for more concrete implementations.

Variables:
  • events -- Our EventManager instance.
  • extensions -- Our ExtensionManager instance.
  • connected -- If True, we have connected to the server successfully.
  • registered -- If True, we have completed the server handshake and are ready to send commands.
call_event(hclass, event, *args, **kwargs)

A convenience method for call_event

call_event_inst(hclass, event, inst)

A convenience method for call_event_inst

case_change()

Change server casemapping semantics

Do not call this unless you know what you're doing

casecmp(string, other)

Do a caseless comparison of two strings.

Returns True if equal, or False if not.

Parameters:
  • string -- String to compare
  • other -- String to compare
casefold(string)

Fold a nick according to server case folding rules.

Parameters:string -- The string to casefold according to the IRC server semantics.
close()

Do the connection teardown

connect()

Do the connection handshake

get_extension(extension)

A convenience method for get_extension

recv(line)

Receive a line.

Parameters:line -- A Line instance to recieve from the wire.
schedule(time, callback)

Schedule a callback for a specific time.

Returns an object that can be passed to unschedule. The object should be treated as opaque.

Parameters:
  • time (float) -- Seconds into the future to perform the callback.
  • callback -- Callback to perform. Use functools.partial to pass arguments.
send(command, params)

Send a line out onto the wire.

Parameters:
  • command -- IRC command to send.
  • params -- A Sequence of parameters to send with the command. Only the last parameter may contain spaces due to IRC framing format limitations.
unschedule(sched)

Unschedule a callback previously registered with schedule.

Parameters:sched -- Event to unschedule returned by schedule.
wrap_ssl()

Wrap the underlying connection with an SSL connection.

Warning

Not all backends support this!

casemapping

IRC-style casemapping and casefolding

IRC uses two forms of casemapping: RFC1459 and ASCII. Unicode is not handled or casemapped by any known servers.

ASCII is simply casemapped as "abc..." <-> "ABC...".

RFC1459 is the same as ASCII in terms of casefolding semantics, except that the characters {}|- are the lowercase equivalents of []^. This is due to an historical wart in the protocol.

event

The event subsystem

PyIRC is built on a powerful yet easy-to-use event system. In addition to command events (each command and numeric has its own event you can hook), your code can define its own event types wherever necessary - for example, the CTCP extension defines a CTCP message event.

class PyIRC.event.Event(event)

The base class for all events passed to callbacks.

Variables:
  • status -- The current status of the event.
  • last_function -- Set to the function who cancelled us, if we are cancelled.
static key(k)

Key function

class PyIRC.event.EventManager

EventManager manages event registration and dispatch.

Variables:events_reg -- The hclass to (events, type) mapping. Useful for advanced usage.
call_event(hclass, event, *args, **kwargs)

Call the callbacks for a given event.

Parameters:
  • hclass -- The class of the event that is occuring.
  • event -- The name of the event that is occuring.
  • *args -- The arguments to pass to the Event type constructor used for the event class.
call_event_inst(hclass, event, event_inst)

Call an event with the given event instance.

If the event is paused, it will resume calling unless cancelled.

Parameters:
  • hclass -- The class of the event that is occuring.
  • event -- The name of the event that is occuring.
  • event_inst -- The Event type we are reusing for this call.
clear()

Unregister all event classes.

Warning

This will clear all callbacks, events, and event classes. Do not use unless you really know what you're doing.

register_callback(hclass, event, priority, callback)

Register a callback for an event.

This method should only be used directly if you know what you're doing.

Parameters:
  • hclass -- The class of the event to register with this callback.
  • event -- The name of the event to register with this callback.
  • priority -- The priority of this callback with this event.
  • callback -- A Callable to invoke when this event occurs.
register_callbacks_from_inst(hclass, inst)

Register callbacks from a given instance, using hook tables

Parameters:
  • hclass -- The instance of the event to register with this callback
  • inst -- The instance to process
register_callbacks_from_inst_all(inst)

Register all (known) callback classes from a given instance, using hook tables

Parameters:inst -- The instance to process
register_callbacks_from_table(hclass, table)

Register callbacks from the given hook table.

Parameters:
  • hclass -- The class of the event to register with this callback.
  • table -- The table to process.
register_class(hclass, type)

Register a class of events.

Parameters:
  • hclass -- The name of the event class. If this name is already registered, this method is a no-op. To change the py:class:~PyIRC.event.Event type for a given class, you must unregister the class with unregister_class, and then re-register it wiht the new type.
  • type -- The type of Event that will be passed to event handlers.
register_event(hclass, event)

Register an event to a given class.

Parameters:
  • hclass -- The class of the event to register.
  • event -- The name of the event to register.

If event is already registered in hclass, this method is a no-op.

unregister_callback(hclass, event, callback)

Unregister a callback for an event.

Parameters:
  • hclass -- The class of the event to unregister this callback from.
  • event -- The name of the event to unregister this callback from.
  • callback -- The callback to unregister.
unregister_callbacks_from_inst(hclass, inst)

Unregister callbacks from a given instance, using hook tables.

Parameters:
  • hclass -- The class of the event to register with this callback.
  • inst -- The class to process.
unregister_callbacks_from_inst_all(inst)

Unregister all (known) callback classes from a given instance, using hook tables

Parameters:inst -- The instance to process
unregister_callbacks_from_table(hclass, table)

Unregister callbacks from the given hook table.

Parameters:
  • hclass -- The class of the event to register with this callback.
  • table -- The table to process
unregister_class(hclass)

Unregister a class of events.

unregister_event(hclass, event)

Unregister an event from a given class.

Parameters:
  • hclass -- The class of the event to unregister.
  • event -- The name of the event to unregister.

Note

It is an error to unregister an event that does not exist.

class PyIRC.event.EventRegistry(events, type)
events

Alias for field number 0

type

Alias for field number 1

class PyIRC.event.EventState

The current state of an event.

cancel = None

Event is cancelled; do not run any further callbacks.

ok = None

Proceed with other callbacks, if any.

pause = None

Pause the callback chain for later resumption

terminate_now = None

Abort the entire library immediately.

Warning

This state should only be used if data loss may occur.

terminate_soon = None

Send a QUIT to the IRC server.

class PyIRC.event.HookEvent(event)

The event for hooks

class PyIRC.event.LineEvent(event, line)

The event for lines

extension

class PyIRC.extension.BaseExtension(base, **kwargs)

The base class for extensions.

Hooks may exist in this, in a hclass_hooks dictionary. These can be created by hand, but it is recommended to let them be created by the build_hook_table function and the hook decorator.

Any unknown attributes in this class are redirected to the base attribute.

hook_classes = {}

A Mapping of hclass to an Event subclass

priority = 0

The priority of this extension, lower is higher (like Unix)

requires = []

Required extensions (must be a name)

class PyIRC.extension.ExtensionManager(base, kwargs, events, extensions=[], database=None)

Manage extensions to PyIRC's library, and register their hooks.

add_extension(extension)

Add an extension by class

Warning

Use with caution - this method will obliterate all present instances at the moment!

Parameters:extension -- Extension to add.
create_db()

Build the extensions database

create_default_events()

Create default events and classes

create_default_hooks()

Enumerate present extensions and build the commands and hooks cache.

create_hooks(hclass)

Register hooks contained in the given attribute from loaded :param extensions:

Arguments:

Parameters:hclass -- Class to create hooks for
get_extension(extension)

Get an extension by name

Returns None if the extension is not found.

Parameters:extension -- Extension to retrieve by name
remove_extension(extension)

Remove a given extension by name

Parameters:extension -- Extension to remove.

formatting

Formatting of IRC messages.

This module contains IRC formatting-related data, and reformatting classes to deal with this formatting.

Bold, italic, underline, reverse, and colours are handled.

class PyIRC.formatting.Colour

A list of colour numbers from name to index.

mIRC maintains a list of colour indexes to names.

class PyIRC.formatting.ColourEscape

Defines a new ANSI/VT100-style colour escape sequence

class PyIRC.formatting.ColourRGB

Colours used on IRC, converted to RGB values.

mIRC maintains a list of colour codes to values.

class PyIRC.formatting.ColourVT100

Colours used on IRC, approximated with VT100/ANSI escapes.

class PyIRC.formatting.Formatter

A basic format parser that uses callbacks to perform formatting.

The callbacks return a string which is then added to the final output.

Variables:
  • bold -- Set when text should be bold.
  • colour -- A (foreground, background) tuple; members not set are set to None.
  • reverse -- Set when colours are being reversed.
  • italic -- Set when text should be in italics.
  • underline -- Set when text should be underline.
do_bold()

Callback to do bold formatting

do_colour()

Callback to do colour formatting

do_italic()

Callback to do italic formatting

do_normal()

Callback to remove all formatting

do_reverse()

Callback to do reversal formatting (reverse colours)

do_underline()

Callback to do underline formatting

format(string)

Convert a given IRC string.

Returns the final formatted string.

Special formatting is done by using callbacks. All callbacks are called after the state is updated to reflect the new status, except for normal which cannot work in any other way (due to needing to know what formatters to reset).

Parameters:string -- String to reformat.
reset()

Reset all colours.

You should not need to override this.

class PyIRC.formatting.FormattingCodes

IRC formatting codes.

A list is maintained by WikiChip.

class PyIRC.formatting.HTMLFormatter

A basic HTML IRC formatting class

class PyIRC.formatting.NullFormatter

A stripping formatter that simply removes formatting

class PyIRC.formatting.VT100Formatter

A VT100 IRC formatting class, suitable for Unix-style terminals

hook

PyIRC.hook.PRIORITY_DONTCARE = 0

Hook can run whenever it wants

PyIRC.hook.PRIORITY_FIRST = -1000

Hook should run first

PyIRC.hook.PRIORITY_LAST = 1000

Hook should run last

PyIRC.hook.build_hook_table(instance)

Build the hook tables for a class

Warning

This creates foo_hooks variables for each instance! If you use __slots__ you MUST have a foo_hooks for each hclass you use.

PyIRC.hook.hook(hclass, hook, priority=None)

Decorator to add a class hook

Parameters:
  • hclass -- hook class to use
  • hook -- name of the hook to use
  • priority -- optional priority value of this hook (defaults to the class priority)

line

Objects and utilities related to IRC messages

class PyIRC.line.Hostmask(*, nick=None, username=None, host=None, mask=None)

Stores a hostmask

Hostmasks are used to store sources and destinations in IRC messages.

>>> Hostmask.parse('nick!user@host')
Hostmask(nick='nick', username='user', host='host')
>>> Hostmask.parse('nick@host')
Hostmask(nick='nick', username=None, host='host')
>>> Hostmask.parse('host.org')
Hostmask(nick=None, username=None, host='host.org')
>>> Hostmask.parse('nickname')
Hostmask(nick='nickname', username=None, host=None)
classmethod parse(raw)

Parse a raw hostmask into a Hostmask object.

Parameters:raw -- The raw hostmask to parse.
class PyIRC.line.Line(*, tags=None, hostmask=None, command=None, params=None, line=None)

Stores an IRC line in the RFC1459 framing format.

IRCv3 has a JSON framing format in the works, but it is unclear as to what its final server and client support will be, and is unfinished at any rate.

>>> Line.parse(':lol.org PRIVMSG')
... 
Line(..., hostmask=Hostmask(...), command='PRIVMSG', params=[])
>>> Line.parse('PING')
Line(tags=None, hostmask=None, command='PING', params=[])
>>> Line.parse('PING Elizacat')
Line(tags=None, hostmask=None, command='PING', params=['Elizacat'])
>>> Line.parse('PING Elizacat :test')
Line(tags=None, hostmask=None, command='PING', params=['Elizacat', 'test'])
>>> Line.parse('PING :test')
Line(tags=None, hostmask=None, command='PING', params=['test'])
>>> Line.parse(':nick!user@host PRIVMSG #testroom meow :testing')
... 
Line(..., command='PRIVMSG', params=['#testroom', 'meow', 'testing'])
classmethod parse(line)

Parse a raw string into a Line.

Also should raise on any invalid line. It will be quite liberal with hostmasks (accepting such joys as '' and 'user1@user2@user3'), but trying to enforce strict validity in hostmasks will be slow.

class PyIRC.line.Tags(*, tags=None, tagstr=None)

Stores message tags

Message tags are a new feature proposed by IRCv3 to add enhanced out-of-band data to messages.

Not presently tested a whole lot due to the lack of conforming servers.

classmethod parse(raw)

Parse a raw tag string into a Tags object.

numerics

Numerics for IRC servers. Not documented at the moment pending us finding a better way to document them.