pydle - a Pythonic, extensible, compliant IRC library¶
pydle is a compact, flexible and standards-abiding IRC library for Python 3, written out of frustration with existing solutions.
Features¶
Well-organized, easily extensible
Thanks to the modular setup, pydle’s functionality is seperated in modules according to the standard they were defined in. This makes specific functionality trivial to find and decreases unwanted coupling, as well as allowing users to pick-and-choose the functionality they need.
No spaghetti code.
Compliant
pydle contains modules, or “features” in pydle terminology, for almost every relevant IRC standard:
- RFC1459: The standard that defines the basic functionality of IRC - no client could live without.
- TLS: Support for chatting securely using TLS encryption.
- CTCP: The IRC Client-to-Client Protocol, allowing clients to query eachother for data.
- ISUPPORT: A method for the server to indicate non-standard or extended functionality to a client, and for clients to activate said functionality if needed.
- WHOX: Easily query status information for a lot of users at once.
- IRCv3.1: An ongoing effort to bring the IRC protocol to the twenty-first century, featuring enhancements such as extended capability negotiation and SASL authentication.
- IRCv3.2 (in progress): The next, in-development iteration of IRCv3. Features among others advanced message tagging, a generalized metadata system, and online status monitoring.
No half-assing functionality.
Asynchronous
IRC is an asychronous protocol; it only makes sense a clients that implements it is asynchronous as well. Built on top of the wonderful Tornado library, pydle relies on proven technologies to deliver proper high-performance asynchronous functionality and primitives. pydle allows using Futures to make asynchronous programming just as intuitive as doing regular blocking operations.
No callback spaghetti.
Liberally licensed
The 3-clause BSD license ensures you can use pydle whenever, for what purpose you want.
No arbitrary restrictions.
Contents¶
Introduction to pydle¶
What is pydle?¶
pydle is an IRC library for Python 3.2 and up.
Although old and dated on some fronts, IRC is still used by a variety of communities as the real-time communication method of choice, and the most popular IRC networks can still count on tens of thousands of users at any point during the day.
pydle was created out of perceived lack of a good, Pythonic, IRC library solution that also worked with Python 3. It attempts to follow the standards properly, while also having functionality for the various extensions to the protocol that have been made over the many years.
What isn’t pydle?¶
pydle is not an end-user IRC client. Although a simple client may be trivial to implement using pydle, pydle itself does not seek out to be a full-fledged client. It does, however, provide the building blocks to which you can delegate most, if not all, of your IRC protocol headaches.
pydle also isn’t production-ready: while the maintainers try their utmost best to keep the API stable, pydle is still in heavy development, and APIs are prone to change or removal at least until version 1.0 has been reached.
Requirements¶
Most of pydle is written in pure, portable Python that only relies on the standard library. However, pydle relies on Tornado to do the heavy lifting on the asynchronous front. Optionally, if you plan to use pydle’s SASL functionality for authentication, the excellent pure-sasl library is required.
All dependencies can be installed using the standard package manager for Python, pip, and the included requirements file:
pip install -r requirements.txt
Compatibility¶
pydle works in any interpreter that implements Python 3.2 or higher. Although mainly tested in CPython, the standard Python implementation, there is no reason why pydle itself should not work in alternative implementations like PyPy, as long as they support the Python 3.2 language requirements.
Using pydle¶
Note
This section covers basic use of pydle. To see the full spectrum of what pydle is capable of, refer to the API reference.
A simple client¶
The most basic way to use pydle is instantiating a pydle.Client
object, connecting it to a server
and having it handle messages forever using pydle.Client.handle_forever()
.
pydle will automatically take care of ensuring that the connection persists, and will reconnect if for some reason disconnected unexpectedly.
import pydle
client = pydle.Client('MyBot')
# Client.connect() is a blocking function.
client.connect('irc.freenode.net', tls=True)
client.handle_forever()
Adding functionality¶
Of course, the above client doesn’t really do much, except idling and error recovery.
To truly start adding functionality to the client, subclass pydle.Client
and override one or more of the IRC callbacks.
import pydle
class MyClient(pydle.Client):
""" This is a simple bot that will greet people as they join the channel. """
def on_connect(self):
super().on_connect()
# Can't greet many people without joining a channel.
self.join('#kochira')
def on_join(self, channel, user):
super().on_join(channel, user)
self.message(channel, 'Hey there, {user}!', user=user)
client = MyClient('MyBot')
client.connect('irc.freenode.net', tls=True)
client.handle_forever()
This trivial example shows a few things:
pydle.Client.on_connect()
is a callback that gets invoked as soon as the client is fully connected to the server.pydle.Client.on_join()
is a callback that gets invoked whenever a user joins a channel.- Trivially enough, we can use
pydle.Client.join()
to instruct the client to join a channel.- Finally, we can use
pydle.Client.message()
to send a message to a channel or to a user; it will even format the message for us according to advanced string formatting.
Hint
It is recommended to call the callbacks of the parent class using super()
, to make sure whatever functionality
implemented by your parent classes gets called too: pydle will gracefully handle the call even if no functionality
was implemented or no callbacks overridden.
Multiple servers, multiple clients¶
Any pydle client instance can only be connected to a single server. That doesn’t mean that you are restricted
to only being active on a single server at once, though. Using a pydle.ClientPool
,
you can instantiate multiple clients, connect them to different servers using pydle.ClientPool.connect()
,
and handle them within a single loop.
import pydle
class MyClient(pydle.Client):
""" This is a simple bot that will greet people as they join the channel. """
def on_connect(self):
super().on_connect()
# Can't greet many people without joining a channel.
self.join('#kochira')
def on_join(self, channel, user):
super().on_join(channel, user)
self.message(channel, 'Hey there, {user}!', user=user)
# Setup pool and connect clients.
pool = pydle.ClientPool()
servers = [ 'irc.freenode.net', 'irc.rizon.net', 'irc.esper.net' ]
for server in servers:
client = pydle.Client('MyBot')
pool.connect(client, server, tls=True)
# Handle all clients in the pool at once.
pool.handle_forever()
Warning
While multiple pydle.ClientPool
instances can be created and ran, you should ensure a client is only
active in a single pydle.ClientPool
at once. Being active in multiple pools can lead to strange things
like receiving messages twice, or interleaved outgoing messages.
Mixing and matching¶
Thanks to pydle’s modular “feature” system, you don’t have to support everything you want to support.
You can choose just to select the options you think you need for your client by using pydle.featurize()
to create a base class
out of the featured you need.
import pydle
# Create a client that just supports the base RFC1459 spec, CTCP and an IRC services-style account system.
MyBaseClient = pydle.featurize(pydle.features.RFC1459Support, pydle.features.CTCPSupport, pydle.features.AccountSupport)
class MyClient(MyBaseClient):
...
A list of all available built-in features and their use can be found at the API reference.
In addition to this, you can of course also write your own features. Feature writing is discussed thoroughly in the feature section. Once you have written a feature, you can just featurize it on top of an existing client class.
import pydle
import vendor
# Add vendor feature on top of the base client.
MyBaseClient = pydle.featurize(pydle.Client, vendor.VendorExtensionSupport)
class MyClient(MyBaseClient):
...
Asynchronous functionality¶
Some actions inevitably require blocking and waiting for a result. Since pydle is an asynchronous library where a client runs in a single thread, doing this blindly could lead to issues like the operation blocking the handling of messages entirely.
Fortunately, pydle implements coroutines which allow you to handle a blocking operation almost as if it were a regular operation, while still retaining the benefits of asynchronous program flow. Coroutines allow pydle to be notified when a blocking operation is done, and then resume execution of the calling function appropriately. That way, blocking operations do not block the entire program flow,
In order for a function to be declared as a coroutine, it has to be decorated using the pydle.coroutine()
decorator.
It can then call functions that would normally block using Python’s yield
operator.
Since a function that calls a blocking function is itself blocking too, it has to be declared a coroutine as well.
Hint
As with a lot of things, documentation is key. Documenting that your function does blocking operations lets the caller know how to call the function, and to include the fact that it calls blocking operations in its own documentation for its own callers.
For example, if you are implementing an administrative system that works based off nicknames, you might want to check
if the users are identified to NickServ
. However, WHOISing a user using pydle.Client.whois()
would be a blocking operation.
Thanks to coroutines and pydle.Client.whois()
being a blocking operation compatible with coroutines,
the act of WHOISing will not block the entire program flow of the client.
import pydle
ADMIN_NICKNAMES = [ 'Shiz', 'rfw' ]
class MyClient(pydle.Client):
"""
This is a simple bot that will tell you if you're an administrator or not.
A real bot with administrative-like capabilities would probably be better off maintaining a cache
that would be invalidated upon parting, quitting or changing nicknames.
"""
def on_connect(self):
super().on_connect()
self.join('#kochira')
@pydle.coroutine
def is_admin(self, nickname):
"""
Check whether or not a user has administrative rights for this bot.
This is a blocking function: use a coroutine to call it.
See pydle's documentation on blocking functionality for details.
"""
admin = False
# Check the WHOIS info to see if the source has identified with NickServ.
# This is a blocking operation, so use yield.
if source in ADMIN_NICKNAMES:
info = yield self.whois(source)
admin = info['identified']
return admin
@pydle.coroutine
def on_message(self, target, source, message):
super().on_message(target, source, message)
# Tell a user if they are an administrator for this bot.
if message.startswith('!adminstatus'):
admin = yield self.is_admin(source)
if admin:
self.message(target, '{source}: You are an administrator.', source=source)
else:
self.message(target, '{source}: You are not an administrator.', source=source)
Writing your own blocking operation that can work with coroutines is trivial:
just make your blocking method return a pydle.Future
instance (without the act of creating and returning the Future itself being blocking),
and any coroutine yielding it will halt execution until the returned future is resolved, using either
pydle.Future.set_result()
or pydle.Future.set_exception()
, while pydle can still handle everything else.
Features¶
pydle’s main IRC functionality is divided into seperate modular components called “features”. These features allow you to mix and match your client to fit exactly to your requirements, as well as provide an easy way to extend pydle yourself, without having to dive into the source code.
Built-in features¶
The following features are packaged with pydle and live in the pydle.features
namespace.
RFC1459¶
API: pydle.features.RFC1459Support
RFC1459 is the bread and butter of IRC: it is the standard that defines the very base concepts of the IRC protocol, ranging from what a channel is to the basic commands to channel limits. If you want your client to have actually any useful IRC functionality, it is recommend to include this feature.
Transport Layer Security (TLS)¶
API: pydle.features.TLSSupport
Support for secure connections to the IRC server using Transport Layer Security.
This allows, if the server supports it, for encrypted connections between the server and the client, to prevent snooping and provide two-way authentication: both for the server to ensure its identity to the client, and for the client to ensure its identity to the server. The latter can also be used in certain service packages to automatically identify to the user account.
In order to connect to a TLS-enabled server, supply tls=True
to pydle.features.TLSSupport.connect()
.
Hint
pydle does not verify server-side TLS certificates by default; to enable certificate verification,
supply tls_verify=True
to pydle.features.TLSSupport.connect()
as well.
In order to supply a client certificate, pydle.features.TLSSupport
takes 3 additional constructor parameters:
tls_client_cert
: A path to the TLS client certificate.tls_client_cert_key
: A path to the TLS client certificate key.tls_client_cert_password
: The optional password for the certificate key.
Client-to-Client Protocol (CTCP)¶
API: pydle.features.CTCPSupport
Support for encapsulation of out-of-band features into standard IRC messages using the Client-to-Client Protocol.
This allows you to send meta-messages to other users, requesting e.g. their local time, client version, and more, and respond to such requests. It adds pydle.Client.ctcp(target, query, contents=None), which allows you to send a CTCP request to a target, and pydle.Client.ctcp_reply(target, query, contents=None), which allows you to respond to CTCP requests.
In addition, it registers the pydle.Client.on_ctcp(from, query, contents) hook, which allows you to act upon any CTCP request, and a per-type hook in the form of pydle.Client.on_ctcp_<type>(from, contents), which allows you to act upon CTCP requests of type type. type will always be lowercased. A few examples of type can be: action, time, version.
Finally, it registers the pydle.Client.on_ctcp_reply(from, queyr, contents) hook, which acts similar to the above hook, except it is triggered when the client receives a CTCP response. It also registers pydle.Client.on_ctcp_<type>_reply, which works similar to the per-type hook described above.
Server-side Extension Support (ISUPPORT)¶
API: pydle.features.ISUPPORTSupport
Support for IRC protocol extensions using the ISUPPORT message.
This feature allows pydle to support protocol extensions which are defined using the non-standard ISUPPORT (005) message. It includes built-in support for a number of popular ISUPPORT-based extensions, like CASEMAPPING, CHANMODES, NETWORK and PREFIX.
It also provides the generic pydle.Client.on_isupport_type(value) hook, where type is the type of ISUPPORT-based extension that the server indicated support for, and value is the optional value of said extension, or None if no value was present.
Account System¶
API: pydle.features.AccountSupport
Support for a generic IRC account system.
Most IRC networks have some kind of account system that allows users to register and manage their nicknames and personas. This feature provides additional support in pydle for this idea and its integration into the networks.
Currently, all it does is set the identified and account fields when doing a WHOIS query (pydle.Client.whois(user)) on someone, which indicate if the target user has identified to their account, and if such, their account name, if available.
Extended User Tracking¶
API: pydle.features.WHOXSupport
Support for better user tracking using WHOX.
This feature allows pydle to perform more accurate tracking of usernames, idents and account names, using the WHOX IRC extension. This allows pydle’s internal user database to be more accurate and up-to-date.
IRCv3.1¶
API: pydle.features.IRCv3_1Support
IRCv3.1 support.
The `IRCv3 Working Group`_ is a working group organized by several network, server author, and client author representatives with the intention to standardize current non-standard IRC practices better, and modernize certain parts of the IRC protocol. The IRCv3 standards are specified as a bunch of extension specifications on top of the last widely-used IRC version, IRC v2.7, also known as RFC1459.
The IRCv3.1 specification adds useful features to IRC from a client perspective, including SASL authentication, support for indicating when a user identified to their account, and indicating when a user went away from their PC.
Including this feature entirely will activate all IRCv3.1 functionality for pydle. You can also opt-in to only select the two major features of IRCv3.1, the capability negotiation framework and SASL authentication support, as described below, by only including their features.
Capability Negotiation Support¶
API: pydle.features.ircv3.CapabilityNegotiationSupport
Support for capability negotiation for IRC protocol extensions.
This feature enables support for a generic framework for negotiationg IRC protocol extension support between the client and the server. It was quickly found that ISUPPORT alone wasn’t sufficient, as it only advertises support from the server side instead of allowing the server and client to negotiate. This is a generic base feature: enabling it on its own won’t do much, instead other features like the IRCv3.1 support feature, or the SASL authentication feature will rely on it to work.
This feature adds three generic hooks for feature authors whose features makes use of capability negotiation:
pydle.Client.on_capability_<cap>_available(value)
: Called when the server indicates capability cap is available.Is passed a value as given by the IRC server, or None if no value was given Should return either a boolean indicating whether or not to request the capability, or a string indicating to request the capability with the returned value.
pydle.Client.on_capability_<cap>_enabled()
: Called when the server has acknowledged the request of capability cap, and ithas been enabled. Should return one of three values: pydle.CAPABILITY_NEGOTIATING when the capability will be further negotiated, pydle.CAPABILITY_NEGOTIATED when the capability has been negotiated successfully, or pydle.CAPABILITY_FAILED when negotiation of the capability has failed. If the function returned pydle.CAPABILITY_NEGOTIATING, it has to call pydle.Client.capability_negotiated(cap, success=True) when negotiating is finished.
pydle.Client.on_capability_<cap>_disabled()
: Called when a previously-enabled capability cap has been disabled.
User Authentication Support (SASL)¶
API: pydle.features.ircv3.SASLSupport
Support for user authentication using SASL.
This feature enables users to identify to their network account using the SASL protocol and practices. Three extra arguments are added to the pydle.Client constructor:
sasl_username
: The SASL username.sasl_password
: The SASL password.sasl_identity
: The identity to use. Default, and most common, is''
.
These arguments are also set as attributes.
Currently, pydle’s SASL support requires on the Python pure-sasl package and is limited to support for the PLAIN mechanism.
IRCv3.2¶
API: pydle.features.IRCv3_2Support
Support for the IRCv3.2 specification.
The IRCv3.2 specification is the second iteration of specifications from the `IRCv3 Working Group`_. This set of specification is still under development, and may change at any time. pydle’s support is conservative, likely incomplete and to-be considered experimental.
pydle currently supports the following IRCv3.2 extensions:
- IRCv3.2 improved capability negotiation.
- Indication of changed ident/host using CHGHOST.
- Indication of ident and host in RFC1459’s /NAMES command response.
- Monitoring of a user’s online status using MONITOR.
- Message tags to add metadata to messages.
- Arbitrary key/value storage using METADATA.
As with the IRCv3.1 features, using this feature enables all of pydle’s IRCv3.2 support. A user can also opt to only use individual large IRCv3.2 features by using the features below.
Online Status Monitoring¶
API: pydle.features.ircv3.MonitoringSupport
Support for monitoring a user’s online status.
This feature allows a client to monitor the online status of certain nicknames. It adds the pydle.Client.monitor(nickname) and pydle.Client.unmonitor(nickname) APIs to add and remove nicknames from the monitor list.
If a monitored user comes online, pydle.Client.on_user_online(nickname) will be called. Similarly, if a user disappears offline, pydle.Client.on_user_offline(nickname) will be called.
Tagged Messages¶
API: pydle.features.ircv3.TaggedMessageSupport
Support for message metadata using tags.
This feature allows pydle to parse message metadata that is transmitted using ‘tags’. Currently, this has no impact on any APIs or hooks for client developers.
Metadata¶
API: pydle.features.ircv3.MetadataSupport
Support for user and channel metadata.
This allows you to set and unset arbitrary key-value information on yourself and on channels, as well as retrieve such values from other users and channels.
Writing features¶
API reference¶
Client API¶
-
class
pydle.
Client
¶ pydle.Client
implements the featureset ofpydle.BasicClient
with all the features in thepydle.features
namespace added. For the full reference, check thepydle.BasicClient
documentation and the Feature API reference.
-
class
pydle.
MinimalClient
¶ pydle.MinimalClient
implements the featureset ofpydle.BasicClient
with some vital features in thepydle.features
namespace added, namely:For the full reference, check the
pydle.BasicClient
documentation and the Feature API reference.
-
class
pydle.
ClientPool
(clients=None, eventloop=None)[source]¶ A pool of clients that are ran and handled in parallel.
-
connect
(client, *args, eventloop=None, **kwargs)[source]¶ Add client to pool and connect it using the given argument. Refer to the connect() method of the added client for details on parameters.
-
disconnect
(client, *args, **kwargs)[source]¶ Disconnect client from pool and remove it. Refer to the disconnect() method of the removed client for details on parameters.
-
-
class
pydle.
BasicClient
(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]¶ Base IRC client class. This class on its own is not complete: in order to be able to run properly, _has_message, _parse_message and _create_message have to be overloaded.
users
A
dict
mapping a username to adict
with general information about that user. Available keys in the information dict:nickname
: The user’s nickname.username
: The user’s reported username on their source device.realname
: The user’s reported real name (GECOS).hostname
: The hostname where the user is connecting from.
channels
-
connect
(hostname=None, port=None, reconnect=False, eventloop=None, **kwargs)[source]¶ Connect to IRC server.
-
connected
¶ Whether or not we are connected.
Asynchronous API¶
-
pydle.
coroutine
(func)[source]¶ Decorator for coroutine functions that need to block for asynchronous operations.
-
class
pydle.
Future
[source]¶ A future. An object that represents a result that has yet to be created or returned.
-
result
(timeout=None)[source]¶ If the operation succeeded, return its result. If it failed, re-raise its exception.
This method takes a
timeout
argument for compatibility with concurrent.futures.Future but it is an error to call it before the Future is done, so thetimeout
is never used.
-
set_result
(result)[source]¶ Sets the result of a
Future
.It is undefined to call any of the
set
methods more than once on the same object.
-
Features API¶
RFC1459¶
-
class
pydle.features.
RFC1459Support
(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]¶ Basic RFC1459 client.
-
ban
(channel, target, range=0)[source]¶ Ban user from channel. Target can be either a user or a host. This command will not kick: use kickban() for that. range indicates the IP/host range to ban: 0 means ban only the IP/host, 1+ means ban that many ‘degrees’ (up to 3 for IP addresses) of the host for range bans.
-
is_same_channel
(left, right)[source]¶ Check if given nicknames are equal in the server’s case mapping.
-
on_channel_message
(target, by, message)[source]¶ Callback received when the client received a message in a channel.
-
on_channel_notice
(target, by, message)[source]¶ Callback called when the client received a notice in a channel.
-
on_invite
(channel, by)[source]¶ Callback called when the client was invited into a channel by someone.
-
on_join
(channel, user)[source]¶ Callback called when a user, possibly the client, has joined the channel.
-
on_kick
(channel, target, by, reason=None)[source]¶ Callback called when a user, possibly the client, was kicked from a channel.
-
on_kill
(target, by, reason)[source]¶ Callback called when a user, possibly the client, was killed from the server.
-
on_nick_change
(old, new)[source]¶ Callback called when a user, possibly the client, changed their nickname.
-
on_part
(channel, user, message=None)[source]¶ Callback called when a user, possibly the client, left a channel.
-
on_private_message
(by, message)[source]¶ Callback called when the client received a message in private.
-
on_private_notice
(by, message)[source]¶ Callback called when the client received a notice in private.
-
on_quit
(user, message=None)[source]¶ Callback called when a user, possibly the client, left the network.
-
on_topic_change
(channel, message, by)[source]¶ Callback called when the topic for a channel was changed.
-
on_user_mode_change
(modes)[source]¶ Callback called when a user mode change occurred for the client.
-
set_mode
(target, *modes)[source]¶ Set mode on target. Users should only rely on the mode actually being changed when receiving an on_{channel,user}_mode_change callback.
-
set_nickname
(nickname)[source]¶ Set nickname to given nickname. Users should only rely on the nickname actually being changed when receiving an on_nick_change callback.
-
set_topic
(channel, topic)[source]¶ Set topic on channel. Users should only rely on the topic actually being changed when receiving an on_topic_change callback.
-
unban
(channel, target, range=0)[source]¶ Unban user from channel. Target can be either a user or a host. See ban documentation for the range parameter.
-
Transport Layer Security¶
Client-to-Client Protocol¶
-
class
pydle.features.
CTCPSupport
(nickname, fallback_nicknames=[], username=None, realname=None, **kwargs)[source]¶ Support for CTCP messages.
Account¶
ISUPPORT¶
Licensing¶
pydle license¶
Copyright (c) 2014, Shiz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL SHIZ BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
pydle relies on Tornado for a significant part of its networking code; its license is printed in verbatim below.
Tornado license¶
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
pydle optionally relies on pure-sasl to provide SASL authentication methods; its license is printed in verbatim below.
pure-sasl license¶
http://www.opensource.org/licenses/mit-license.php
Copyright 2007-2011 David Alan Cridland
Copyright 2011 Lance Stout
Copyright 2012 Tyler L Hobbs
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.