<?xml version="1.0" encoding="UTF-8"?>
<leo_file>
<leo_header file_format="2" tnodes="0" max_tnode_index="1" clone_windows="0"/>
<globals body_outline_ratio="0.523099850969">
	<global_window_position top="10" left="10" height="671" width="1009"/>
	<global_log_window_position top="0" left="0" height="0" width="0"/>
</globals>
<preferences>
</preferences>
<find_panel_settings>
	<find_string></find_string>
	<change_string></change_string>
</find_panel_settings>
<vnodes>
<v t="root.20050203094141" a="ETV"><vh>Python vs Perl</vh>
<v t="root.20050203094346"><vh>Introduction</vh>
<v t="root.20050203094141.1"><vh>Surprise: You're already using python</vh></v>
<v t="root.20050203100914"><vh>Talk target audience</vh></v>
<v t="root.20050203094957"><vh>Why we love Perl</vh></v>
<v t="root.20050203094957.1"><vh>What I hate about Perl</vh></v>
<v t="root.20050203094957.3"><vh>Why you'll love Python</vh></v>
<v t="root.20050203094141.3"><vh>My story</vh>
<v t="root.20050203100308"><vh>My background</vh></v>
<v t="root.20050203111030"><vh>My experience with Perl</vh></v>
<v t="root.20050203111030.1"><vh>My motivation</vh></v>
</v>
<v t="root.20050203111339"><vh>My goal</vh></v>
</v>
<v t="root.20050203104844"><vh>In a nutshell: Python is runnable pseudo-code</vh></v>
<v t="root.20050203122350"><vh>Design philosophy: Python vs Perl</vh></v>
<v t="root.20050203094141.7"><vh>Common ground: Python and Perl</vh></v>
<v t="root.20050203105108"><vh>Readability comparsion example</vh>
<v t="root.20050203105108.1" a="E"><vh>Soundex algorithm</vh>
<v t="root.20050203105108.2"><vh>Python (written by someone new to Python)</vh></v>
<v t="root.20050203105108.3"><vh>Perl (standard library)</vh></v>
</v>
</v>
<v t="root.20050203111652"><vh>The dream</vh></v>
<v t="root.20050203094141.6" a="E"><vh>Python design principles</vh></v>
<v t="root.20050203111746"><vh>The power of python</vh>
<v t="root.20050203094141.25"><vh>Python projects</vh>
<v t="root.20050203094141.8"><vh>Leo</vh></v>
<v t="root.20050203105854.1"><vh>bittorrent: more traffic than email</vh></v>
<v t="root.20050203105854" a="E"><vh>Twisted: event driven networking framework</vh>
<v t="root.20050203110742"><vh>Protocols</vh></v>
<v t="root.20050203110742.1" a="E"><vh>Finger example</vh>
<v t="root.20050203110745"><vh>Specs</vh></v>
<v t="root.20050203110742.2"><vh>Code</vh></v>
<v t="root.20050203131208"><vh>pydoc output for Finger example</vh></v>
</v>
</v>
<v t="root.20050203105854.2"><vh>spambayes</vh></v>
<v t="root.20050203130324"><vh>PYRO: Python remote objects</vh></v>
<v t="root.20050203110257"><vh>Zope: CMS platform</vh></v>
<v t="root.20050203105854.3"><vh>plone: popular CMS implemented on top of Zope</vh></v>
<v t="root.20050203105854.4"><vh>nevow: web application framework (publish objects)</vh></v>
<v t="root.20050203105854.5"><vh>gadfly: relational database, in pure python</vh></v>
<v t="root.20050203130523"><vh>Python CAD applications</vh>
<v t="root.20050203130523.1"><vh>FreeCAD</vh></v>
<v t="root.20050203130523.2"><vh>Fandango</vh></v>
<v t="root.20050203130523.3"><vh>PythonCAD</vh></v>
</v>
</v>
</v>
<v t="root.20050203130900.1"><vh>Python advantages</vh>
<v t="root.20050203094141.15"><vh>clean syntax, beautiful</vh></v>
<v t="root.20050203094141.16"><vh>easy to learn, easy to teach (especially kids)</vh></v>
<v t="root.20050203094141.20"><vh>object oriented by design</vh>
<v t="root.20050203103407"><vh>Empty class. Perl vs Python</vh></v>
</v>
<v t="root.20050203094141.18"><vh>rich standard library</vh></v>
<v t="root.20050203094141.13"><vh>facilities for modular code</vh>
<v t="root.20050203131715"><vh>myModule.py</vh></v>
<v t="root.20050203131715.1"><vh>t.py</vh></v>
</v>
<v t="root.20050203094141.11"><vh>exceptions</vh></v>
<v t="root.20050203094141.21"><vh>introspective</vh></v>
<v t="root.20050203094141.19"><vh>bytecode compilation</vh></v>
<v t="root.20050203094141.14"><vh>interactive development / experimentation</vh></v>
<v t="root.20050203094141.23"><vh>powerful extension facilities</vh></v>
<v t="root.20050203132703"><vh>embeddable</vh></v>
<v t="root.20050203094141.10"><vh>self documenting (Embedded docs)</vh>
<v t="root.20050203131208"><vh>pydoc output for Finger example</vh></v>
</v>
<v t="root.20050203112042"><vh>Clean internals magic</vh></v>
<v t="root.20050203094141.17"><vh>excellent documentation</vh></v>
<v t="root.20050203094141.24"><vh>excellent windows support</vh></v>
<v t="root.20050203094141.29"><vh>brain drain: migration of best minds to python</vh></v>
<v t="root.20050203094141.26"><vh>shorter code</vh></v>
<v t="root.20050203094141.27"><vh>alternative implementations</vh></v>
<v t="root.20050203094141.28"><vh>community development process (PEPs and SIGs)</vh></v>
<v t="root.20050203094141.22"><vh>fast: psyco, JIT future</vh></v>
</v>
<v t="root.20050203122739"><vh>First impressions</vh>
<v t="root.20050203122739.1"><vh>That object methods are the default, not something tacked on:</vh></v>
<v t="root.20050203122739.2"><vh>That integer math is the default unless one or more of the operands isn't an integer:</vh></v>
<v t="root.20050203122739.3"><vh>That semicolons at the end of lines are optional: any of these are fine:</vh></v>
<v t="root.20050203122739.4"><vh>Indentation syntax. Everything indented is part of what happens when "mytest" is not 0 or null:</vh></v>
<v t="root.20050203122739.5"><vh>Default argument values for functions:</vh></v>
<v t="root.20050203122739.6"><vh>Exception handling. I like "try/except" logic (apparently Perl 6 has this too);</vh></v>
<v t="root.20050203122739.7"><vh>Variables. No $ @ % prefix to variables.</vh></v>
</v>
<v t="root.20050203094141.30"><vh>What is perl still good for</vh></v>
<v t="root.20050203094141.31"><vh>How to start out</vh></v>
<v t="root.20050203123822"><vh>Summary</vh></v>
<v t="root.20050203105504"><vh>Final warning</vh></v>
<v t="root.20050203124135"><vh>Testimonials</vh>
<v t="root.20050203124135.1"><vh>Perl fan recants</vh></v>
<v t="root.20050203124135.2"><vh>Words from a master</vh></v>
<v t="root.20050203124329"><vh>Eric Raymond: Why python</vh></v>
<v t="root.20050203124721"><vh>Discovering Python</vh></v>
</v>
<v t="root.20050203100308.1"><vh>Further reading</vh>
<v t="root.20050203133504"><vh>What's wrong with Perl</vh></v>
<v t="root.20050203133504.1"><vh>Why I promote python</vh></v>
<v t="root.20050203133504.2"><vh>Eric raymond explains why it's his favorite language</vh></v>
<v t="root.20050203133504.3"><vh>Python compared to other languages</vh></v>
<v t="root.20050203133504.4"><vh>Language comparsion research</vh></v>
</v>
</v>
</vnodes>
<tnodes>
<t tx="root.20050203094141">@nocolor </t>
<t tx="root.20050203094141.1">"Python has been an important part of Google since the beginning, and remains so as the system grows and evolves. Today dozens of Google engineers use Python, and we're looking for more people with skills in this language." said Peter Norvig, director of search quality at Google, Inc.</t>
<t tx="root.20050203094141.3"></t>
<t tx="root.20050203094141.6">* Beautiful is better than ugly.
* Explicit is better than implicit.
* Simple is better than complex.
* Complex is better than complicated.
* Flat is better than nested.
* Sparse is better than dense.
* Readability counts.
* Special cases aren't special enough to break the rules.
* Although practicality beats purity.
* Errors should never pass silently.
* Unless explicitly silenced.
* In the face of ambiguity, refuse the temptation to guess.
* There should be one -- and preferably only one -- obvious way to do it.
* Although that way may not be obvious at first unless you're Dutch.
* Now is better than never.
* Although never is often better than right now.
* If the implementation is hard to explain, it's a bad idea.
* If the implementation is easy to explain, it may be a good idea.
* Namespaces are one honking great idea -- let's do more of those!

* Correctness and clarity before speed</t>
<t tx="root.20050203094141.7">Dynamic typing and bounding
Garbage collection
Built-in support for high level data types: Strings, arrays, hashes / associative dictionaries

</t>
<t tx="root.20050203094141.8">My secret weapon. Would be much less productive without it.


</t>
<t tx="root.20050203094141.10"></t>
<t tx="root.20050203094141.11">(Supposed to come with Perl 6)</t>
<t tx="root.20050203094141.13">Modules are objects. Any python file automatically defines a namespace:
No cumbersome Export facilities.
Powerful Java-like namespaces / package mechanism
    (zimport)</t>
<t tx="root.20050203094141.14">idle, IPython
</t>
<t tx="root.20050203094141.15"></t>
<t tx="root.20050203094141.16">	mati's experience</t>
<t tx="root.20050203094141.17"></t>
<t tx="root.20050203094141.18">(random selection)

Support for serializing objects
Support for storing serialized objects in simple databases
A Python parser
Support for simple text databases (Perl has this too)
Libraries for ZIP file compression and decompression
XMLRPC libraries
A profiler (and a really nice one too!)
A CGI library
A URL parser library
A general URL connection library
Simplified HTML, SGML and XML parsers
A simple web server with CGI support
POP, IMAP and SMTP libraries (Python 1.5.1; I started with 1.4)</t>
<t tx="root.20050203094141.19">Allows non source distribution of modules. (plus for some proprietary uses)
Faster</t>
<t tx="root.20050203094141.20"></t>
<t tx="root.20050203094141.21">dir()
</t>
<t tx="root.20050203094141.22"></t>
<t tx="root.20050203094141.23">the standard facilities
pyrex (C++ level performance)</t>
<t tx="root.20050203094141.24">py2exe
wxpython (GUI)</t>
<t tx="root.20050203094141.25"></t>
<t tx="root.20050203094141.26"></t>
<t tx="root.20050203094141.27">Python is not a specific interpreter. It's a language.

Alternative implementations:
    Python in python
    JPython</t>
<t tx="root.20050203094141.28">Python Enchancement Proposals
Special interest groups
</t>
<t tx="root.20050203094141.29">More code will be written in Python
Perl will gradually be phased out to a marginal existance


</t>
<t tx="root.20050203094141.30">substitute for simple shell scripting
quick and dirty hacks
ugly language masks ugly programs
    Often a short term advantage!
</t>
<t tx="root.20050203094141.31">python website documentation:	http://www.python.org/doc/Intros.html
standard library code: read it as a reference, read the documentation.
programming python orielly: buy the book</t>
<t tx="root.20050203094346"></t>
<t tx="root.20050203094957">Glue language
    Perl lets us hack together quick solutions fast
Very powerful regular expression engine
Built-in facilities
    Solving programs in it's problem domain is a breeze
The mother of all scripting languages
    Language borrows ideas from C, sed, awk, basic
Unix heritage
CPAN
</t>
<t tx="root.20050203094957.1">Large and complex language, takes a long time to learn
"Write-only language", language encourages hard-to-read code
Object oriented facilities glued on top of Perl 5 with duct tape.
Poor definition of interfaces (more errors not catched)
Poor error handling
Unwieldy data structures (references, etc.)
Implicit behaviors going on behind your back, often biting even experienced Perl programmers
Doesn't scale: The larger your project becomes, the less progress you make over time. ("hitting a wall")
</t>
<t tx="root.20050203094957.3">It's very easy to learn
Everything is well documented. The documentation is free.
Programming at Python speed: If you use Python, you will be more powerful as a programmer.
    You will spend more time focusing on the logic of your program, instead of the mechanics of implementation.
    You'll spend less time debugging. Your programs will often just work. 
    Your programs will scale, it will be easier to handle increasing complexity.
    You'll need to spend less time documenting. You programs will be naturally documented. 
You will be able to collaborate with other programmers more effectively.
You will be able to read your own code 2 years from now.
Your code will be as beautiful as your logic.
Your code will work everywhere.


</t>
<t tx="root.20050203100308">http://Liraz.org/
Started programming early, in a UNIX background
Philosophy: Use the right tool for the job
Hobby: Finding better tools
Style: mix and match, rapid prototyping
Languages:
    Shell scripting, C, C++, Java
    Perl, Python
    PHP, Javascript
YAPH
    I've been programming Perl since 1996
The Perl Obfuscation Service
    http://liraz.org/obfus.html
Lifetime nemesis: Complexity
Python evangelist</t>
<t tx="root.20050203100308.1"></t>
<t tx="root.20050203100914">Specifically: Perl programmers
More generally: Any programmer
</t>
<t tx="root.20050203103407">package MyClass;
sub new {
    my $class = shift;
    my $self = {};
    bless $self, $class
    $self-&gt;initialize();  # do initialization here
    return $self;
}


class MyClass:
    pass</t>
<t tx="root.20050203104844"></t>
<t tx="root.20050203105108"></t>
<t tx="root.20050203105108.1"></t>
<t tx="root.20050203105108.2">def soundex(string):
    """Returns the Soundex code of the string. Characters not A-Z skipped."""
    string=lower(string)   

    if not is_letter(string[0]): string=string[1:]
    last=no_tbl[ord(string[0])-97]
    res =upper(string[0]) # This is where the result will end up

    for char in string[1:]:
	if is_letter(char):
	    new=no_tbl[ord(char)-97]
	    if (new!="0" and new!=last):
		res=res+new
	    last=new

    if len(res)&lt;4:
	return res+"0"*(4-len(res))
    else:
	return res[:4]</t>
<t tx="root.20050203105108.3">
sub soundex
{
  local (@s, $f, $fc, $_) = @_;

  push @s, '' unless @s;	# handle no args as a single empty string

  foreach (@s)
  {
    tr/a-z/A-Z/;
    tr/A-Z//cd;

    if ($_ eq '')
    {
      $_ = $soundex_nocode;
    }
    else
    {
      ($f) = /^(.)/;
      tr/AEHIOUWYBFPVCGJKQSXZDTLMNR/00000000111122222222334556/;
      ($fc) = /^(.)/;
      s/^$fc+//;
      tr///cs;
      tr/0//d;
      $_ = $f . $_ . '000';
      s/^(.{4}).*/$1/;
    }
  }

  wantarray ? @s : shift @s;
}</t>
<t tx="root.20050203105504">    Camels are docile when properly trained and handled but, especially in the rutting season, are liable to fits of rage. They spit when annoyed and can bite and kick dangerously.

    --Encyclopedia Britannica.

However, you may perhaps be curious about what the Encyclopedia Britannica has to say about Pythons? Here it is:

    ...the Monty Python Flying Circus troupe, which set a standard during the 1970s for its quirky parodies and wacky humour on television and later in films.

    --Encyclopedia Britannica

That's right. Python was named after a comedy troupe, not after a nasty reptile. </t>
<t tx="root.20050203105854"></t>
<t tx="root.20050203105854.1"></t>
<t tx="root.20050203105854.2"></t>
<t tx="root.20050203105854.3"></t>
<t tx="root.20050203105854.4">
</t>
<t tx="root.20050203105854.5"></t>
<t tx="root.20050203110257"></t>
<t tx="root.20050203110742">Supports TCP, UDP, SSL/TLS, multicast, Unix sockets, a large number of protocols (including HTTP, NNTP, IMAP, SSH, IRC, FTP, and others)</t>
<t tx="root.20050203110742.1"></t>
<t tx="root.20050203110742.2"># Do everything properly, and componentize
from twisted.application import internet, service
from twisted.internet import protocol, reactor, defer
from twisted.protocols import basic, irc
from twisted.python import components
from twisted.web import resource, server, static, xmlrpc, microdom
from twisted.web.woven import page, model, interfaces
from twisted.spread import pb
from OpenSSL import SSL
import cgi

class IFingerService(components.Interface):

    def getUser(self, user):
        """Return a deferred returning a string"""

    def getUsers(self):
        """Return a deferred returning a list of strings"""

class IFingerSetterService(components.Interface):

    def setUser(self, user, status):
        """Set the user's status to something"""

def catchError(err):
    return "Internal error in server"

class FingerProtocol(basic.LineReceiver):

    def lineReceived(self, user):
        d = self.factory.getUser(user)
        d.addErrback(catchError)
        def writeValue(value):
            self.transport.write(value+'\n')
            self.transport.loseConnection()
        d.addCallback(writeValue)


class IFingerFactory(components.Interface):

    def getUser(self, user):
        """Return a deferred returning a string"""

    def buildProtocol(self, addr):
        """Return a protocol returning a string"""


class FingerFactoryFromService(protocol.ServerFactory):

    __implements__ = IFingerFactory,

    protocol = FingerProtocol

    def __init__(self, service):
        self.service = service

    def getUser(self, user):
        return self.service.getUser(user)

components.registerAdapter(FingerFactoryFromService,
                           IFingerService,
                           IFingerFactory)

class FingerSetterProtocol(basic.LineReceiver):

    def connectionMade(self):
        self.lines = []

    def lineReceived(self, line):
        self.lines.append(line)

    def connectionLost(self, reason):
        if len(self.lines) == 2:
            self.factory.setUser(*self.lines)


class IFingerSetterFactory(components.Interface):

    def setUser(self, user, status):
        """Return a deferred returning a string"""

    def buildProtocol(self, addr):
        """Return a protocol returning a string"""


class FingerSetterFactoryFromService(protocol.ServerFactory):

    __implements__ = IFingerSetterFactory,

    protocol = FingerSetterProtocol

    def __init__(self, service):
        self.service = service

    def setUser(self, user, status):
        self.service.setUser(user, status)


components.registerAdapter(FingerSetterFactoryFromService,
                           IFingerSetterService,
                           IFingerSetterFactory)

class IRCReplyBot(irc.IRCClient):

    def connectionMade(self):
        self.nickname = self.factory.nickname
        irc.IRCClient.connectionMade(self)

    def privmsg(self, user, channel, msg):
        user = user.split('!')[0]
        if self.nickname.lower() == channel.lower():
            d = self.factory.getUser(msg)
            d.addErrback(catchError)
            d.addCallback(lambda m: "Status of %s: %s" % (msg, m))
            d.addCallback(lambda m: self.msg(user, m))


class IIRCClientFactory(components.Interface):

    """
    @ivar nickname
    """

    def getUser(self, user):
        """Return a deferred returning a string"""

    def buildProtocol(self, addr):
        """Return a protocol"""


class IRCClientFactoryFromService(protocol.ClientFactory):

    __implements__ = IIRCClientFactory,

    protocol = IRCReplyBot
    nickname = None

    def __init__(self, service):
        self.service = service

    def getUser(self, user):
        return self.service.getUser(user)

components.registerAdapter(IRCClientFactoryFromService,
                           IFingerService,
                           IIRCClientFactory)

class UsersModel(model.MethodModel):

    def initialize(self, *args, **kwargs):
        self.service=args[0]

    def wmfactory_users(self, request):
        return self.service.getUsers()

components.registerAdapter(UsersModel, IFingerService, interfaces.IModel)

class UserStatusTree(page.Page):

    template = """&lt;html&gt;&lt;head&gt;&lt;title&gt;Users&lt;/title&gt;&lt;/head&gt;&lt;body&gt;
    &lt;h1&gt;Users&lt;/h1&gt;
    &lt;ul model="users" view="List"&gt;
    &lt;li pattern="listItem"&gt;&lt;a view="Anchor" /&gt;&lt;/li&gt;
    &lt;/ul&gt;&lt;/body&gt;&lt;/html&gt;"""

    def initialize(self, *args, **kwargs):
        self.service=args[0]

    def getDynamicChild(self, path, request):
        return UserStatus(user=path, service=self.service)

    def wchild_RPC2 (self, request):
        return UserStatusXR(self.service)

components.registerAdapter(UserStatusTree, IFingerService, resource.IResource)


class UserStatus(page.Page):

    template='''&lt;html&gt;&lt;head&gt;&lt;title view="Text" model="user"/&gt;&lt;/head&gt;
    &lt;body&gt;&lt;h1 view="Text" model="user"/&gt;
    &lt;p model="status" view="Text" /&gt;
    &lt;/body&gt;&lt;/html&gt;'''

    def initialize(self, **kwargs):
        self.user = kwargs['user']
        self.service = kwargs['service']

    def wmfactory_user(self, request):
        return self.user

    def wmfactory_status(self, request):
        return self.service.getUser(self.user)


class UserStatusXR(xmlrpc.XMLRPC):

    def __init__(self, service):
        xmlrpc.XMLRPC.__init__(self)
        self.service = service

    def xmlrpc_getUser(self, user):
        return self.service.getUser(user)

    def xmlrpc_getUsers(self):
        return self.service.getUsers()


class IPerspectiveFinger(components.Interface):

    def remote_getUser(self, username):
        """return a user's status"""

    def remote_getUsers(self):
        """return a user's status"""

class PerspectiveFingerFromService(pb.Root):

    __implements__ = pb.Root.__implements__, IPerspectiveFinger

    def __init__(self, service):
        self.service = service

    def remote_getUser(self, username):
        return self.service.getUser(username)

    def remote_getUsers(self):
        return self.service.getUsers()

components.registerAdapter(PerspectiveFingerFromService,
                           IFingerService,
                           IPerspectiveFinger)


class FingerService(service.Service):

    __implements__ = IFingerService,

    def __init__(self, filename):
        self.filename = filename
        self._read()

    def _read(self):
        self.users = {}
        for line in file(self.filename):
            user, status = line.split(':', 1)
            user = user.strip()
            status = status.strip()
            self.users[user] = status
        self.call = reactor.callLater(30, self._read)

    def getUser(self, user):
        return defer.succeed(self.users.get(user, "No such user"))

    def getUsers(self):
        return defer.succeed(self.users.keys())


class ServerContextFactory:

    def getContext(self):
        """Create an SSL context.

        This is a sample implementation that loads a certificate from a file
        called 'server.pem'."""
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_certificate_file('server.pem')
        ctx.use_privatekey_file('server.pem')
        return ctx


application = service.Application('finger', uid=1, gid=1)
f = FingerService('/etc/users')
serviceCollection = service.IServiceCollection(application)
internet.TCPServer(79, IFingerFactory(f)
                   ).setServiceParent(serviceCollection)
site = server.Site(resource.IResource(f))
internet.TCPServer(8000, site
                   ).setServiceParent(serviceCollection)
internet.SSLServer(443, site, ServerContextFactory()
                   ).setServiceParent(serviceCollection)
i = IIRCClientFactory(f)
i.nickname = 'fingerbot'
internet.TCPClient('irc.freenode.org', 6667, i
                   ).setServiceParent(serviceCollection)
internet.TCPServer(8889, pb.PBServerFactory(IPerspectiveFinger(f))
                   ).setServiceParent(serviceCollection)</t>
<t tx="root.20050203110745">287 lines
Publishes a finger service with an interface to the port 79, Web, IRC, XMLRPC</t>
<t tx="root.20050203111030">Loved the language
Revelled in it's complexities
Quicksand scalability
    Learned the language + started being really productive in python in 3 hours.</t>
<t tx="root.20050203111030.1">Want to live in a world where programs are written in a decent language
A language we can teach kids in primary school
I promote Python because doing so is the right thing.
help you be more productive
You'll thank me later for it
    Lots of free beer</t>
<t tx="root.20050203111339">To wet your appetite, not teach you the language
Get you to explore Python for yourself afterwards
The rest happens by itself

</t>
<t tx="root.20050203111652">Python's inventor involved uin C4PE: Computer Programming 4 Everybody
Goal: make the Python language and tools accessible to children.
</t>
<t tx="root.20050203111746">Powerful enough to write object databases ZODB or relational databases
</t>
<t tx="root.20050203112042"></t>
<t tx="root.20050203122350">Perl's power is reflected in its complex syntax and many operator symbols. 
    Larry Wall is a linguist. Perl's motto is "there's more than one way to do it"
Python has a simple, elegant base language, and the power resides in its library.
    A precursor to Python was a Guido
</t>
<t tx="root.20050203122739">Data types. Setting a one value tuple is absolutely ugly:

this='abc','def',0;
print this, len(this)
this='hello' # NOT a tuple
print this, len(this)
this='hello', # Now it is
print this, len(this)

...
('abc', 'def', 0) 3
hello 5
('hello',) 1


      This is a consequence of not having data prefixes or formal declarations.
    * No "a++" or "a--". Sheesh.
    * No "$_". There's _, which apparently isn't quite the same - unless I misunderstand, which is certainly possible at this point.</t>
<t tx="root.20050203122739.1">
a=['abc','def','ghijkl']
print "Before Append",a
a.append('hello')
print "After Append",a

...

Before Append ['abc', 'def', 'ghijkl']
After Append ['abc', 'def', 'ghijkl', 'hello']


      There's a whole boatload of built-in methods: see http://www.python.org/doc/current/tut/node7.html. I'm not going to say I like these better than the Perl functions that do similar things, but I certainly have no problems with these and can see good use for them.</t>
<t tx="root.20050203122739.2">
print 7 / 2
print 7.0 / 2

...

3
3.5</t>
<t tx="root.20050203122739.3">
print 7/2;print 7/2.0

print 7/2;
print 7/2.0

print 7/2
print 7/2.0

      Leaving off semicolons is a common Perl goof..</t>
<t tx="root.20050203122739.4">
mytest=1
if mytest:
   print "mytest ",
   print "is set"

print "hello ",

      Oddly, this is something most Perl types really hate, but I'd find it easy to get used to. Since most of us tend to indent code within blocks anyway, it seems reasonable to me to dispense with the braces and just use the indentation.</t>
<t tx="root.20050203122739.5">
def foo(prompt="huh?", count=2):
 print prompt,count

foo()
foo("go","seven")
foo(count=89)

...
huh? 2
go seven
huh? 89</t>
<t tx="root.20050203122739.6"></t>
<t tx="root.20050203122739.7"></t>
<t tx="root.20050203123822">Python dominates Perl in most applications except for fairly short shell-script sorts of applications, and there they are roughly comparable.

</t>
<t tx="root.20050203124135">Source: http://infohost.nmt.edu/tcc/help/lang/python/vsperl.html
</t>
<t tx="root.20050203124135.1">
My good friend Danny Quist was one of the sharpest students to go through the excellent CS program here in the last few years. He works now at Los Alamos National Laboratories. He sent me this confession:

    This has been gnawing at my soul for quite some time, and now it's confession time. A couple of weeks ago I started programming python. It's an excellent language, I love it. It's very clean and the built-in datatypes are great. It has a very good object implementation and my code is better because of it. When you want to do abstract datatypes in perl it's nothing but trouble. Python won my heart with its flexibility in that regard. You were right, I was wrong.</t>
<t tx="root.20050203124135.2">
My former professor John Slimick, a Stanford graduate from the 1960s, was my principle CS guru when I was in college. He is still teaching at a Pitt branch campus. Some of his early thoughts on Python vs. Perl:

``I'm just finishing up a one credit on perl, and I'm not happy. I had the misfortune to be heard saying the perl was a write-only language, but that pretty much how I feel. I have never had such an intense feeling that perl is the language where:

    Possible perl programmer: "I really need something like an inversion operator (like box with - and two dots in APL)."

    perl spokesman: "Hey, Larry -- this guy needs a general matrix inversion operator."

    (muffled response from Larry Wall way in the back): "Tell him, for sure, version 7. Is there anything else he needs?"

``perl certainly looks and feels like the shell languages it came from. And don't get me started on defaults...

``I did have the unusual experience of two students in the perl class competing on who could write a piece of code in the fewest lines. The winner got it down to a single line. (The winner also said that while it is true that perl is unmaintainable, he wouldn't mind getting paid to maintain HIS perl code.)

``The one thing that I have noticed so far in python is that the language seems designed. The little that I've seen so far, apart from __thing__, seems readable, unlike most of perl. I don't feel handicapped by my knowledge of the ALGOL related languages.

``...I was delighted to see apply, map, and lambda. It's about time someone steals from LISP. My opinion is that LISP is probably still the champion of ideas/reserved word.''</t>
<t tx="root.20050203124329">http://noframes.linuxjournal.com/article/3882</t>
<t tx="root.20050203124721">Source: http://www.garshol.priv.no/download/text/perl.html

    Programming languages teach you not to want what they cannot provide. You have to think in a language to write programs in it, and it's hard to want something you can't describe. When I first started programming - in BASIC - I didn't miss recursion, because I didn't know there was such a thing. I thought in BASIC. I could only conceive iterative algorithms, so why should I miss recursion?

    --Paul Graham, ANSI Common Lisp.

So, after discovering all these bad things about Perl, what did I do? I kept using it. After all, as bad as it was, it was still better than doing text processing and web programming with C, Pascal or Java, and there were no better alternatives.

Or so I thought. At the University bookstore there was this book called "Internet Programming with Python". Being both a language freak and an internet freak I thought this was interesting and picked it up. Somewhere in the beginning of the book there was an anecdote about a Python programmer who wrote all his Python programs so that when an error occurred (ie: when an exception was thrown) the error handler called his beeper.

Wow, I thought. This sounds interesting. So I went home, found the Python tutorial, printed it out and started playing with Python. That night I wrote a POP3 client library in Python. Just like that. After going to bed I had an idea: wouldn't it be a lot nicer if I cached the messages and made this invisible to the user? In the morning I added that in half an hour.

I've since used this library to delete email without downloading it, moving 150 emails from one POP account to another and many other things. (Yes, I made a small SMTP library as well.) I can even use it as an email client using the Python interpreter as a command line.

I kept using Python more and more after this. I wrote a link checker that went over my web pages checking them for errors and kept adding more protocols and features to it. After a while I thought: this program spends a lot of time waiting for server responses. Maybe I can speed it up by using multi-threading so that it can wait for several servers at the same time?

I'd never really used multithreading before, but knew the theory behind it. I added this to the link checker in an hour and that includes the digging in the library documentation and removing the few bugs I did introduce. (Multithreading is much more complex than it sounds at first because things happen simultaneously. That's not Python's fault, though.)

Having read this you may now be convinced that I'm a master programmer, rather than that Python is a great programming language for this kind of thing. Personally, I don't think this is true. (Remember, I'm the guy who can't even make a Perl subroutine return a file handle.) Also, from what I hear, many other people have had similar experiences with Python. Here's one example:

    In my first 15 minutes programming Python I wrote a program which would download all the articles in a newsgroup into an mh folder for me - and comp.lang.python was my first newsgroup!

    --Thomas Corbin, in private email to the author

</t>
<t tx="root.20050203130324"> Pyro is short for PYthon Remote Objects. It is an advanced and powerful Distributed Object Technology system written entirely in Python, that is designed to be very easy to use. Never worry about writing network communication code again, when using Pyro you just write your Python objects like you would normally. With only a few lines of extra code, Pyro takes care of the network communication between your objects once you split them over different machines on the network. All the gory socket programming details are taken care of, you just call a method on a remote object as if it were a local object!

Pyro provides an object-oriented form of RPC. You can use Pyro within a single system but also use it for IPC. For those that are familiar with Java, Pyro resembles Java's Remote Method Invocation (RMI). It is less similar to CORBA - which is a system- and language independent Distributed Object Technology and has much more to offer than Pyro or RMI. But Pyro is small, simple and free

</t>
<t tx="root.20050203130523"></t>
<t tx="root.20050203130523.1">FreeCAD is an Open Source CAx RAD based on Open Cascade, QT and Python. It features some key concepts like Macro recording, Workbenches, ability to run as a server and dynamically loadable Application extensions and its designed to be platform independent... [WWW] http://free-cad.sourceforge.net/</t>
<t tx="root.20050203130523.2">Fandango is planned to be a full featured CAD program. It has a C++ core extensible by scripts. Currently the memory core for entity management is ready, scripting works wonderfully thanks to the ease of embedding and extending of Python. A KDE+XML user interface is now in place, controlling the keyboard and mouse. [WWW] http://www.soffernet.com/jaime/fandango/</t>
<t tx="root.20050203130523.3">
PythonCAD is a CAD package written, surprisingly enough, in Python. The PythonCAD project aims to produce a scriptable, open-source, easy to use CAD package for Linux, the various flavors of BSD Unix, commercial Unix, and other platforms to which someone who is interested ports the program. Work began on PythonCAD in July, 2002, and the first public release was on December 21, 2002. In addition it has been ported to winXP [WWW] http://www.pythoncad.org/</t>
<t tx="root.20050203130900.1"></t>
<t tx="root.20050203131208">Python Library Documentation: module finger22

NAME
    finger22 - # Do everything properly, and componentize

FILE
    /home/z/archives/python/Twisted-1.3.0/doc/howto/tutorial/listings/finger/finger22.py

CLASSES
    twisted.internet.protocol.ClientFactory(twisted.internet.protocol.Factory)
        IRCClientFactoryFromService
    twisted.protocols.irc.IRCClient(twisted.protocols.basic.LineReceiver)
        IRCReplyBot
    twisted.python.components.Interface(__builtin__.object)
        IFingerFactory
        IFingerService
        IFingerSetterFactory
        IFingerSetterService
        IIRCClientFactory
        IPerspectiveFinger
    twisted.protocols.basic.LineReceiver(twisted.internet.protocol.Protocol)
        FingerProtocol
        FingerSetterProtocol
    twisted.web.woven.model.MethodModel(twisted.web.woven.model.Model)
        UsersModel
    twisted.web.woven.page.Page(twisted.web.woven.model.MethodModel, twisted.web.woven.controller.Controller, twisted.web.woven.view.View)
        UserStatus
        UserStatusTree
    twisted.spread.flavors.Root(twisted.spread.flavors.Referenceable)
        PerspectiveFingerFromService
    ServerContextFactory
    twisted.internet.protocol.ServerFactory(twisted.internet.protocol.Factory)
        FingerFactoryFromService
        FingerSetterFactoryFromService
    twisted.application.service.Service
        FingerService
    twisted.web.xmlrpc.XMLRPC(twisted.web.resource.Resource)
        UserStatusXR
    
    class FingerFactoryFromService(twisted.internet.protocol.ServerFactory)
     |  Method resolution order:
     |      FingerFactoryFromService
     |      twisted.internet.protocol.ServerFactory
     |      twisted.internet.protocol.Factory
     |  
     |  Methods defined here:
     |  
     |  __init__(self, service)
     |  
     |  getUser(self, user)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __implements__ = (&lt;class 'finger22.IFingerFactory'&gt;,)
     |  
     |  __module__ = 'finger22'
     |  
     |  protocol = &lt;class finger22.FingerProtocol&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.Factory:
     |  
     |  buildProtocol(self, addr)
     |      Create an instance of a subclass of Protocol.
     |      
     |      The returned instance will handle input on an incoming server
     |      connection, and an attribute "factory" pointing to the creating
     |      factory.
     |      
     |      Override this method to alter how Protocol instances get created.
     |      
     |      @param addr: an object implementing L{twisted.internet.interfaces.IAddress}
     |  
     |  doStart(self)
     |      Make sure startFactory is called.
     |  
     |  doStop(self)
     |      Make sure stopFactory is called.
     |  
     |  startFactory(self)
     |      This will be called before I begin listening on a Port or Connector.
     |      
     |      It will only be called once, even if the factory is connected
     |      to multiple ports.
     |      
     |      This can be used to perform 'unserialization' tasks that
     |      are best put off until things are actually running, such
     |      as connecting to a database, opening files, etcetera.
     |  
     |  stopFactory(self)
     |      This will be called before I stop listening on all Ports/Connectors.
     |      
     |      This can be used to perform 'shutdown' tasks such as disconnecting
     |      database connections, closing files, etc.
     |      
     |      It will be called, for example, before an application shuts down,
     |      if it was connected to a port.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.Factory:
     |  
     |  noisy = 'sure, why not'
     |  
     |  numPorts = 0
    
    class FingerProtocol(twisted.protocols.basic.LineReceiver)
     |  Method resolution order:
     |      FingerProtocol
     |      twisted.protocols.basic.LineReceiver
     |      twisted.internet.protocol.Protocol
     |      twisted.internet.protocol.BaseProtocol
     |  
     |  Methods defined here:
     |  
     |  lineReceived(self, user)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.protocols.basic.LineReceiver:
     |  
     |  clearLineBuffer(self)
     |      Clear buffered data.
     |  
     |  dataReceived(self, data)
     |      Protocol.dataReceived.
     |      Translates bytes into lines, and calls lineReceived (or
     |      rawDataReceived, depending on mode.)
     |  
     |  lineLengthExceeded(self, line)
     |      Called when the maximum line length has been reached.
     |      Override if it needs to be dealt with in some special way.
     |  
     |  rawDataReceived(self, data)
     |      Override this for when raw data is received.
     |  
     |  sendLine(self, line)
     |      Sends a line to the other end of the connection.
     |  
     |  setLineMode(self, extra='')
     |      Sets the line-mode of this receiver.
     |      
     |      If you are calling this from a rawDataReceived callback,
     |      you can pass in extra unhandled data, and that data will
     |      be parsed for lines.  Further data received will be sent
     |      to lineReceived rather than rawDataReceived.
     |  
     |  setRawMode(self)
     |      Sets the raw mode of this receiver.
     |      Further data received will be sent to rawDataReceived rather
     |      than lineReceived.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.protocols.basic.LineReceiver:
     |  
     |  MAX_LENGTH = 16384
     |  
     |  _LineReceiver__buffer = ''
     |  
     |  delimiter = '\r\n'
     |  
     |  line_mode = 1
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.Protocol:
     |  
     |  connectionFailed(self)
     |      (Deprecated)
     |      
     |      This used to be called when the connection was not properly
     |      established.
     |  
     |  connectionLost(self, reason=&lt;twisted.python.failure.Failure twisted.internet.error.ConnectionDone&gt;)
     |      Called when the connection is shut down.
     |      
     |      Clear any circular references here, and any external references
     |      to this Protocol.  The connection has been closed.
     |      
     |      @type reason: L{twisted.python.failure.Failure}
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.Protocol:
     |  
     |  __implements__ = (&lt;class 'twisted.internet.interfaces.IProtocol'&gt;,)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.BaseProtocol:
     |  
     |  connectionMade(self)
     |      Called when a connection is made.
     |      
     |      This may be considered the initializer of the protocol, because
     |      it is called when the connection is completed.  For clients,
     |      this is called once the connection to the server has been
     |      established; for servers, this is called after an accept() call
     |      stops blocking and a socket has been received.  If you need to
     |      send any greeting or initial message, do it here.
     |  
     |  makeConnection(self, transport)
     |      Make a connection to a transport and a server.
     |      
     |      This sets the 'transport' attribute of this Protocol, and calls the
     |      connectionMade() callback.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.BaseProtocol:
     |  
     |  connected = 0
     |  
     |  transport = None
    
    class FingerService(twisted.application.service.Service)
     |  Methods defined here:
     |  
     |  __init__(self, filename)
     |  
     |  _read(self)
     |  
     |  getUser(self, user)
     |  
     |  getUsers(self)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __implements__ = (&lt;class 'finger22.IFingerService'&gt;,)
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.application.service.Service:
     |  
     |  __getstate__(self)
     |  
     |  disownServiceParent(self)
     |  
     |  privilegedStartService(self)
     |  
     |  setName(self, name)
     |  
     |  setServiceParent(self, parent)
     |  
     |  startService(self)
     |  
     |  stopService(self)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.application.service.Service:
     |  
     |  name = None
     |  
     |  parent = None
     |  
     |  running = 0
    
    class FingerSetterFactoryFromService(twisted.internet.protocol.ServerFactory)
     |  Method resolution order:
     |      FingerSetterFactoryFromService
     |      twisted.internet.protocol.ServerFactory
     |      twisted.internet.protocol.Factory
     |  
     |  Methods defined here:
     |  
     |  __init__(self, service)
     |  
     |  setUser(self, user, status)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __implements__ = (&lt;class 'finger22.IFingerSetterFactory'&gt;,)
     |  
     |  __module__ = 'finger22'
     |  
     |  protocol = &lt;class finger22.FingerSetterProtocol&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.Factory:
     |  
     |  buildProtocol(self, addr)
     |      Create an instance of a subclass of Protocol.
     |      
     |      The returned instance will handle input on an incoming server
     |      connection, and an attribute "factory" pointing to the creating
     |      factory.
     |      
     |      Override this method to alter how Protocol instances get created.
     |      
     |      @param addr: an object implementing L{twisted.internet.interfaces.IAddress}
     |  
     |  doStart(self)
     |      Make sure startFactory is called.
     |  
     |  doStop(self)
     |      Make sure stopFactory is called.
     |  
     |  startFactory(self)
     |      This will be called before I begin listening on a Port or Connector.
     |      
     |      It will only be called once, even if the factory is connected
     |      to multiple ports.
     |      
     |      This can be used to perform 'unserialization' tasks that
     |      are best put off until things are actually running, such
     |      as connecting to a database, opening files, etcetera.
     |  
     |  stopFactory(self)
     |      This will be called before I stop listening on all Ports/Connectors.
     |      
     |      This can be used to perform 'shutdown' tasks such as disconnecting
     |      database connections, closing files, etc.
     |      
     |      It will be called, for example, before an application shuts down,
     |      if it was connected to a port.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.Factory:
     |  
     |  noisy = 'sure, why not'
     |  
     |  numPorts = 0
    
    class FingerSetterProtocol(twisted.protocols.basic.LineReceiver)
     |  Method resolution order:
     |      FingerSetterProtocol
     |      twisted.protocols.basic.LineReceiver
     |      twisted.internet.protocol.Protocol
     |      twisted.internet.protocol.BaseProtocol
     |  
     |  Methods defined here:
     |  
     |  connectionLost(self, reason)
     |  
     |  connectionMade(self)
     |  
     |  lineReceived(self, line)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.protocols.basic.LineReceiver:
     |  
     |  clearLineBuffer(self)
     |      Clear buffered data.
     |  
     |  dataReceived(self, data)
     |      Protocol.dataReceived.
     |      Translates bytes into lines, and calls lineReceived (or
     |      rawDataReceived, depending on mode.)
     |  
     |  lineLengthExceeded(self, line)
     |      Called when the maximum line length has been reached.
     |      Override if it needs to be dealt with in some special way.
     |  
     |  rawDataReceived(self, data)
     |      Override this for when raw data is received.
     |  
     |  sendLine(self, line)
     |      Sends a line to the other end of the connection.
     |  
     |  setLineMode(self, extra='')
     |      Sets the line-mode of this receiver.
     |      
     |      If you are calling this from a rawDataReceived callback,
     |      you can pass in extra unhandled data, and that data will
     |      be parsed for lines.  Further data received will be sent
     |      to lineReceived rather than rawDataReceived.
     |  
     |  setRawMode(self)
     |      Sets the raw mode of this receiver.
     |      Further data received will be sent to rawDataReceived rather
     |      than lineReceived.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.protocols.basic.LineReceiver:
     |  
     |  MAX_LENGTH = 16384
     |  
     |  _LineReceiver__buffer = ''
     |  
     |  delimiter = '\r\n'
     |  
     |  line_mode = 1
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.Protocol:
     |  
     |  connectionFailed(self)
     |      (Deprecated)
     |      
     |      This used to be called when the connection was not properly
     |      established.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.Protocol:
     |  
     |  __implements__ = (&lt;class 'twisted.internet.interfaces.IProtocol'&gt;,)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.BaseProtocol:
     |  
     |  makeConnection(self, transport)
     |      Make a connection to a transport and a server.
     |      
     |      This sets the 'transport' attribute of this Protocol, and calls the
     |      connectionMade() callback.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.BaseProtocol:
     |  
     |  connected = 0
     |  
     |  transport = None
    
    class IFingerFactory(twisted.python.components.Interface)
     |  Method resolution order:
     |      IFingerFactory
     |      twisted.python.components.Interface
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  buildProtocol(self, addr)
     |      Return a protocol returning a string
     |  
     |  getUser(self, user)
     |      Return a deferred returning a string
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Class methods inherited from twisted.python.components.Interface:
     |  
     |  adaptWith(self, using, to, registry=None) from twisted.python.components.MetaInterface
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.python.components.Interface:
     |  
     |  __dict__ = &lt;dict-proxy object&gt;
     |  
     |  __metaclass__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __weakref__ = &lt;member '__weakref__' of 'Interface' objects&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from __builtin__.object:
     |  
     |  __delattr__(...)
     |      x.__delattr__('name') &lt;==&gt; del x.name
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') &lt;==&gt; x.name
     |  
     |  __hash__(...)
     |      x.__hash__() &lt;==&gt; hash(x)
     |  
     |  __init__(...)
     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
     |  
     |  __reduce__(...)
     |      helper for pickle
     |  
     |  __repr__(...)
     |      x.__repr__() &lt;==&gt; repr(x)
     |  
     |  __setattr__(...)
     |      x.__setattr__('name', value) &lt;==&gt; x.name = value
     |  
     |  __str__(...)
     |      x.__str__() &lt;==&gt; str(x)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from __builtin__.object:
     |  
     |  __class__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __new__ = &lt;built-in method __new__ of type object&gt;
     |      T.__new__(S, ...) -&gt; a new object with type S, a subtype of T
    
    class IFingerService(twisted.python.components.Interface)
     |  Method resolution order:
     |      IFingerService
     |      twisted.python.components.Interface
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  getUser(self, user)
     |      Return a deferred returning a string
     |  
     |  getUsers(self)
     |      Return a deferred returning a list of strings
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Class methods inherited from twisted.python.components.Interface:
     |  
     |  adaptWith(self, using, to, registry=None) from twisted.python.components.MetaInterface
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.python.components.Interface:
     |  
     |  __dict__ = &lt;dict-proxy object&gt;
     |  
     |  __metaclass__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __weakref__ = &lt;member '__weakref__' of 'Interface' objects&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from __builtin__.object:
     |  
     |  __delattr__(...)
     |      x.__delattr__('name') &lt;==&gt; del x.name
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') &lt;==&gt; x.name
     |  
     |  __hash__(...)
     |      x.__hash__() &lt;==&gt; hash(x)
     |  
     |  __init__(...)
     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
     |  
     |  __reduce__(...)
     |      helper for pickle
     |  
     |  __repr__(...)
     |      x.__repr__() &lt;==&gt; repr(x)
     |  
     |  __setattr__(...)
     |      x.__setattr__('name', value) &lt;==&gt; x.name = value
     |  
     |  __str__(...)
     |      x.__str__() &lt;==&gt; str(x)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from __builtin__.object:
     |  
     |  __class__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __new__ = &lt;built-in method __new__ of type object&gt;
     |      T.__new__(S, ...) -&gt; a new object with type S, a subtype of T
    
    class IFingerSetterFactory(twisted.python.components.Interface)
     |  Method resolution order:
     |      IFingerSetterFactory
     |      twisted.python.components.Interface
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  buildProtocol(self, addr)
     |      Return a protocol returning a string
     |  
     |  setUser(self, user, status)
     |      Return a deferred returning a string
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Class methods inherited from twisted.python.components.Interface:
     |  
     |  adaptWith(self, using, to, registry=None) from twisted.python.components.MetaInterface
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.python.components.Interface:
     |  
     |  __dict__ = &lt;dict-proxy object&gt;
     |  
     |  __metaclass__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __weakref__ = &lt;member '__weakref__' of 'Interface' objects&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from __builtin__.object:
     |  
     |  __delattr__(...)
     |      x.__delattr__('name') &lt;==&gt; del x.name
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') &lt;==&gt; x.name
     |  
     |  __hash__(...)
     |      x.__hash__() &lt;==&gt; hash(x)
     |  
     |  __init__(...)
     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
     |  
     |  __reduce__(...)
     |      helper for pickle
     |  
     |  __repr__(...)
     |      x.__repr__() &lt;==&gt; repr(x)
     |  
     |  __setattr__(...)
     |      x.__setattr__('name', value) &lt;==&gt; x.name = value
     |  
     |  __str__(...)
     |      x.__str__() &lt;==&gt; str(x)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from __builtin__.object:
     |  
     |  __class__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __new__ = &lt;built-in method __new__ of type object&gt;
     |      T.__new__(S, ...) -&gt; a new object with type S, a subtype of T
    
    class IFingerSetterService(twisted.python.components.Interface)
     |  Method resolution order:
     |      IFingerSetterService
     |      twisted.python.components.Interface
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  setUser(self, user, status)
     |      Set the user's status to something
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Class methods inherited from twisted.python.components.Interface:
     |  
     |  adaptWith(self, using, to, registry=None) from twisted.python.components.MetaInterface
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.python.components.Interface:
     |  
     |  __dict__ = &lt;dict-proxy object&gt;
     |  
     |  __metaclass__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __weakref__ = &lt;member '__weakref__' of 'Interface' objects&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from __builtin__.object:
     |  
     |  __delattr__(...)
     |      x.__delattr__('name') &lt;==&gt; del x.name
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') &lt;==&gt; x.name
     |  
     |  __hash__(...)
     |      x.__hash__() &lt;==&gt; hash(x)
     |  
     |  __init__(...)
     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
     |  
     |  __reduce__(...)
     |      helper for pickle
     |  
     |  __repr__(...)
     |      x.__repr__() &lt;==&gt; repr(x)
     |  
     |  __setattr__(...)
     |      x.__setattr__('name', value) &lt;==&gt; x.name = value
     |  
     |  __str__(...)
     |      x.__str__() &lt;==&gt; str(x)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from __builtin__.object:
     |  
     |  __class__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __new__ = &lt;built-in method __new__ of type object&gt;
     |      T.__new__(S, ...) -&gt; a new object with type S, a subtype of T
    
    class IIRCClientFactory(twisted.python.components.Interface)
     |  @ivar nickname
     |  
     |  Method resolution order:
     |      IIRCClientFactory
     |      twisted.python.components.Interface
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  buildProtocol(self, addr)
     |      Return a protocol
     |  
     |  getUser(self, user)
     |      Return a deferred returning a string
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = '\n    @ivar nickname\n    '
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Class methods inherited from twisted.python.components.Interface:
     |  
     |  adaptWith(self, using, to, registry=None) from twisted.python.components.MetaInterface
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.python.components.Interface:
     |  
     |  __dict__ = &lt;dict-proxy object&gt;
     |  
     |  __metaclass__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __weakref__ = &lt;member '__weakref__' of 'Interface' objects&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from __builtin__.object:
     |  
     |  __delattr__(...)
     |      x.__delattr__('name') &lt;==&gt; del x.name
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') &lt;==&gt; x.name
     |  
     |  __hash__(...)
     |      x.__hash__() &lt;==&gt; hash(x)
     |  
     |  __init__(...)
     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
     |  
     |  __reduce__(...)
     |      helper for pickle
     |  
     |  __repr__(...)
     |      x.__repr__() &lt;==&gt; repr(x)
     |  
     |  __setattr__(...)
     |      x.__setattr__('name', value) &lt;==&gt; x.name = value
     |  
     |  __str__(...)
     |      x.__str__() &lt;==&gt; str(x)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from __builtin__.object:
     |  
     |  __class__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __new__ = &lt;built-in method __new__ of type object&gt;
     |      T.__new__(S, ...) -&gt; a new object with type S, a subtype of T
    
    class IPerspectiveFinger(twisted.python.components.Interface)
     |  Method resolution order:
     |      IPerspectiveFinger
     |      twisted.python.components.Interface
     |      __builtin__.object
     |  
     |  Methods defined here:
     |  
     |  remote_getUser(self, username)
     |      return a user's status
     |  
     |  remote_getUsers(self)
     |      return a user's status
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Class methods inherited from twisted.python.components.Interface:
     |  
     |  adaptWith(self, using, to, registry=None) from twisted.python.components.MetaInterface
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.python.components.Interface:
     |  
     |  __dict__ = &lt;dict-proxy object&gt;
     |  
     |  __metaclass__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __weakref__ = &lt;member '__weakref__' of 'Interface' objects&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from __builtin__.object:
     |  
     |  __delattr__(...)
     |      x.__delattr__('name') &lt;==&gt; del x.name
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') &lt;==&gt; x.name
     |  
     |  __hash__(...)
     |      x.__hash__() &lt;==&gt; hash(x)
     |  
     |  __init__(...)
     |      x.__init__(...) initializes x; see x.__class__.__doc__ for signature
     |  
     |  __reduce__(...)
     |      helper for pickle
     |  
     |  __repr__(...)
     |      x.__repr__() &lt;==&gt; repr(x)
     |  
     |  __setattr__(...)
     |      x.__setattr__('name', value) &lt;==&gt; x.name = value
     |  
     |  __str__(...)
     |      x.__str__() &lt;==&gt; str(x)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from __builtin__.object:
     |  
     |  __class__ = &lt;class 'twisted.python.components.MetaInterface'&gt;
     |  
     |  __new__ = &lt;built-in method __new__ of type object&gt;
     |      T.__new__(S, ...) -&gt; a new object with type S, a subtype of T
    
    class IRCClientFactoryFromService(twisted.internet.protocol.ClientFactory)
     |  Method resolution order:
     |      IRCClientFactoryFromService
     |      twisted.internet.protocol.ClientFactory
     |      twisted.internet.protocol.Factory
     |  
     |  Methods defined here:
     |  
     |  __init__(self, service)
     |  
     |  getUser(self, user)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __implements__ = (&lt;class 'finger22.IIRCClientFactory'&gt;,)
     |  
     |  __module__ = 'finger22'
     |  
     |  nickname = None
     |  
     |  protocol = &lt;class finger22.IRCReplyBot&gt;
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.ClientFactory:
     |  
     |  clientConnectionFailed(self, connector, reason)
     |      Called when a connection has failed to connect.
     |      
     |      It may be useful to call connector.connect() - this will reconnect.
     |      
     |      @type reason: L{twisted.python.failure.Failure}
     |  
     |  clientConnectionLost(self, connector, reason)
     |      Called when an established connection is lost.
     |      
     |      It may be useful to call connector.connect() - this will reconnect.
     |      
     |      @type reason: L{twisted.python.failure.Failure}
     |  
     |  startedConnecting(self, connector)
     |      Called when a connection has been started.
     |      
     |      You can call connector.stopConnecting() to stop the connection attempt.
     |      
     |      @param connector: a Connector object.
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.Factory:
     |  
     |  buildProtocol(self, addr)
     |      Create an instance of a subclass of Protocol.
     |      
     |      The returned instance will handle input on an incoming server
     |      connection, and an attribute "factory" pointing to the creating
     |      factory.
     |      
     |      Override this method to alter how Protocol instances get created.
     |      
     |      @param addr: an object implementing L{twisted.internet.interfaces.IAddress}
     |  
     |  doStart(self)
     |      Make sure startFactory is called.
     |  
     |  doStop(self)
     |      Make sure stopFactory is called.
     |  
     |  startFactory(self)
     |      This will be called before I begin listening on a Port or Connector.
     |      
     |      It will only be called once, even if the factory is connected
     |      to multiple ports.
     |      
     |      This can be used to perform 'unserialization' tasks that
     |      are best put off until things are actually running, such
     |      as connecting to a database, opening files, etcetera.
     |  
     |  stopFactory(self)
     |      This will be called before I stop listening on all Ports/Connectors.
     |      
     |      This can be used to perform 'shutdown' tasks such as disconnecting
     |      database connections, closing files, etc.
     |      
     |      It will be called, for example, before an application shuts down,
     |      if it was connected to a port.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.Factory:
     |  
     |  noisy = 'sure, why not'
     |  
     |  numPorts = 0
    
    class IRCReplyBot(twisted.protocols.irc.IRCClient)
     |  Method resolution order:
     |      IRCReplyBot
     |      twisted.protocols.irc.IRCClient
     |      twisted.protocols.basic.LineReceiver
     |      twisted.internet.protocol.Protocol
     |      twisted.internet.protocol.BaseProtocol
     |  
     |  Methods defined here:
     |  
     |  connectionMade(self)
     |  
     |  privmsg(self, user, channel, msg)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.protocols.irc.IRCClient:
     |  
     |  __getstate__(self)
     |  
     |  _sendLine(self)
     |  
     |  action(self, user, channel, data)
     |      Called when I see a user perform an ACTION on a channel.
     |  
     |  away(self, message='')
     |  
     |  badMessage(self, line, excType, excValue, tb)
     |      When I get a message that's so broken I can't use it.
     |  
     |  bounce(self, info)
     |      Called with information about where the client should reconnect.
     |      
     |      @type info: C{str}
     |      @param info: A plaintext description of the address that should be
     |      connected to.
     |  
     |  created(self, when)
     |      Called with creation date information about the server, usually at logon.
     |      
     |      @type when: C{str}
     |      @param when: A string describing when the server was created, probably.
     |  
     |  ctcpMakeQuery(self, user, messages)
     |      Send one or more X{extended messages} as a CTCP query.
     |      
     |      @type messages: a list of extended messages.  An extended
     |      message is a (tag, data) tuple, where 'data' may be C{None}.
     |  
     |  ctcpMakeReply(self, user, messages)
     |      Send one or more X{extended messages} as a CTCP reply.
     |      
     |      @type messages: a list of extended messages.  An extended
     |      message is a (tag, data) tuple, where 'data' may be C{None}.
     |  
     |  ctcpQuery(self, user, channel, messages)
     |      Dispatch method for any CTCP queries received.
     |  
     |  ctcpQuery_ACTION(self, user, channel, data)
     |  
     |  ctcpQuery_CLIENTINFO(self, user, channel, data)
     |      A master index of what CTCP tags this client knows.
     |      
     |      If no arguments are provided, respond with a list of known tags.
     |      If an argument is provided, provide human-readable help on
     |      the usage of that tag.
     |  
     |  ctcpQuery_DCC(self, user, channel, data)
     |      Initiate a Direct Client Connection
     |  
     |  ctcpQuery_ERRMSG(self, user, channel, data)
     |  
     |  ctcpQuery_FINGER(self, user, channel, data)
     |  
     |  ctcpQuery_PING(self, user, channel, data)
     |  
     |  ctcpQuery_SOURCE(self, user, channel, data)
     |  
     |  ctcpQuery_TIME(self, user, channel, data)
     |  
     |  ctcpQuery_USERINFO(self, user, channel, data)
     |  
     |  ctcpQuery_VERSION(self, user, channel, data)
     |  
     |  ctcpReply(self, user, channel, messages)
     |      Dispatch method for any CTCP replies received.
     |  
     |  ctcpReply_PING(self, user, channel, data)
     |  
     |  ctcpUnknownQuery(self, user, channel, tag, data)
     |  
     |  ctcpUnknownReply(self, user, channel, tag, data)
     |      Called when a fitting ctcpReply_ method is not found.
     |      
     |      XXX: If the client makes arbitrary CTCP queries,
     |      this method should probably show the responses to
     |      them instead of treating them as anomolies.
     |  
     |  dataReceived(self, data)
     |  
     |  dccAcceptResume(self, user, fileName, port, resumePos)
     |      Send a DCC ACCEPT response to clients who have requested a resume.
     |  
     |  dccDoAcceptResume(self, user, file, port, resumePos)
     |      Called when a client has verified and accepted a DCC resume
     |      request made by us.  By default it will do nothing.
     |  
     |  dccDoChat(self, user, channel, address, port, data)
     |  
     |  dccDoResume(self, user, file, port, resumePos)
     |      Called when a client is trying to resume an offered file
     |      via DCC send.  It should be either replied to with a DCC
     |      ACCEPT or ignored (default).
     |  
     |  dccDoSend(self, user, address, port, fileName, size, data)
     |      Called when I receive a DCC SEND offer from a client.
     |      
     |      By default, I do nothing here.
     |  
     |  dccResume(self, user, fileName, port, resumePos)
     |      Send a DCC RESUME request to another user.
     |  
     |  dccSend(self, user, file)
     |  
     |  dcc_ACCEPT(self, user, channel, data)
     |  
     |  dcc_CHAT(self, user, channel, data)
     |  
     |  dcc_RESUME(self, user, channel, data)
     |  
     |  dcc_SEND(self, user, channel, data)
     |  
     |  handleCommand(self, command, prefix, params)
     |      Determine the function to call for the given command and call
     |      it with the given arguments.
     |  
     |  irc_ERR_NICKNAMEINUSE(self, prefix, params)
     |  
     |  irc_ERR_PASSWDMISMATCH(self, prefix, params)
     |  
     |  irc_JOIN(self, prefix, params)
     |  
     |  irc_KICK(self, prefix, params)
     |      Kicked?  Who?  Not me, I hope.
     |  
     |  irc_MODE(self, prefix, params)
     |  
     |  irc_NICK(self, prefix, params)
     |  
     |  irc_NOTICE(self, prefix, params)
     |  
     |  irc_PART(self, prefix, params)
     |  
     |  irc_PING(self, prefix, params)
     |  
     |  irc_PRIVMSG(self, prefix, params)
     |  
     |  irc_RPL_BOUNCE(self, prefix, params)
     |  
     |  irc_RPL_CREATED(self, prefix, params)
     |  
     |  irc_RPL_ENDOFMOTD(self, prefix, params)
     |  
     |  irc_RPL_LUSERCHANNELS(self, prefix, params)
     |  
     |  irc_RPL_LUSERCLIENT(self, prefix, params)
     |  
     |  irc_RPL_LUSERME(self, prefix, params)
     |  
     |  irc_RPL_LUSEROP(self, prefix, params)
     |  
     |  irc_RPL_MOTD(self, prefix, params)
     |  
     |  irc_RPL_MOTDSTART(self, prefix, params)
     |  
     |  irc_RPL_MYINFO(self, prefix, params)
     |  
     |  irc_RPL_NOTOPIC(self, prefix, params)
     |  
     |  irc_RPL_TOPIC(self, prefix, params)
     |      I just joined the channel, and the server is telling me the current topic.
     |  
     |  irc_RPL_WELCOME(self, prefix, params)
     |  
     |  irc_RPL_YOURHOST(self, prefix, params)
     |  
     |  irc_TOPIC(self, prefix, params)
     |      Someone in the channel set the topic.
     |  
     |  irc_unknown(self, prefix, command, params)
     |  
     |  isupport(self, options)
     |      Called with various information about what the server supports.
     |      
     |      @type options: C{list} of C{str}
     |      @param options: Descriptions of features or limits of the server, possibly
     |      in the form "NAME=VALUE".
     |  
     |  join(self, channel, key=None)
     |  
     |  joined(self, channel)
     |      Called when I finish joining a channel.
     |      
     |      channel has the starting character (# or &amp;) intact.
     |  
     |  kick(self, channel, user, reason=None)
     |  
     |  kickedFrom(self, channel, kicker, message)
     |      Called when I am kicked from a channel.
     |  
     |  leave(self, channel, reason=None)
     |  
     |  left(self, channel)
     |      Called when I have left a channel.
     |      
     |      channel has the starting character (# or &amp;) intact.
     |  
     |  lineReceived(self, line)
     |  
     |  luserChannels(self, channels)
     |      Called with the number of channels existant on the server.
     |      
     |      @type channels: C{int}
     |  
     |  luserClient(self, info)
     |      Called with information about the number of connections, usually at logon.
     |      
     |      @type info: C{str}
     |      @param info: A description of the number of clients and servers
     |      connected to the network, probably.
     |  
     |  luserMe(self, info)
     |      Called with information about the server connected to.
     |      
     |      @type info: C{str}
     |      @param info: A plaintext string describing the number of users and servers
     |      connected to this server.
     |  
     |  luserOp(self, ops)
     |      Called with the number of ops logged on to the server.
     |      
     |      @type ops: C{int}
     |  
     |  me(self, channel, action)
     |      Strike a pose.
     |  
     |  mode(self, chan, set, modes, limit=None, user=None, mask=None)
     |      Change the modes on a user or channel.
     |  
     |  modeChanged(self, user, channel, set, modes, args)
     |      Called when a channel's modes are changed
     |      
     |      @type user: C{str}
     |      @param user: The user and hostmask which instigated this change.
     |      
     |      @type channel: C{str}
     |      @param channel: The channel for which the modes are changing.
     |      
     |      @type set: C{bool} or C{int}
     |      @param set: true if the mode is being added, false if it is being
     |      removed.
     |      
     |      @type modes: C{str}
     |      @param modes: The mode or modes which are being changed.
     |      
     |      @type args: C{tuple}
     |      @param args: Any additional information required for the mode
     |      change.
     |  
     |  msg(self, user, message, length=None)
     |      Send a message to a user or channel.
     |      
     |      @type user: C{str}
     |      @param user: The username or channel name to which to direct the
     |      message.
     |      
     |      @type message: C{str}
     |      @param message: The text to send
     |      
     |      @type length: C{int}
     |      @param length: The maximum number of octets to send at a time.  This
     |      has the effect of turning a single call to msg() into multiple
     |      commands to the server.  This is useful when long messages may be
     |      sent that would otherwise cause the server to kick us off or silently
     |      truncate the text we are sending.  If None is passed, the entire
     |      message is always send in one command.
     |  
     |  myInfo(self, servername, version, umodes, cmodes)
     |      Called with information about the server, usually at logon.
     |      
     |      @type servername: C{str}
     |      @param servername: The hostname of this server.
     |      
     |      @type version: C{str}
     |      @param version: A description of what software this server runs.
     |      
     |      @type umodes: C{str}
     |      @param umodes: All the available user modes.
     |      
     |      @type cmodes: C{str}
     |      @param cmodes: All the available channel modes.
     |  
     |  nickChanged(self, nick)
     |      Called when my nick has been changed.
     |  
     |  notice(self, user, message)
     |  
     |  noticed(self, user, channel, message)
     |      Called when I have a notice from a user to me or a channel.
     |      
     |      By default, this is equivalent to IRCClient.privmsg, but if your
     |      client makes any automated replies, you must override this!
     |      From the RFC::
     |      
     |          The difference between NOTICE and PRIVMSG is that
     |          automatic replies MUST NEVER be sent in response to a
     |          NOTICE message. [...] The object of this rule is to avoid
     |          loops between clients automatically sending something in
     |          response to something it received.
     |  
     |  part = leave(self, channel, reason=None)
     |  
     |  ping(self, user, text=None)
     |      Measure round-trip delay to another IRC client.
     |  
     |  pong(self, user, secs)
     |      Called with the results of a CTCP PING query.
     |  
     |  quirkyMessage(self, s)
     |      This is called when I receive a message which is peculiar,
     |      but not wholly indecipherable.
     |  
     |  quit(self, message='')
     |  
     |  receivedMOTD(self, motd)
     |      I received a message-of-the-day banner from the server.
     |      
     |      motd is a list of strings, where each string was sent as a seperate
     |      message from the server. To display, you might want to use::
     |      
     |          string.join(motd, '\n')
     |      
     |      to get a nicely formatted string.
     |  
     |  register(self, nickname, hostname='foo', servername='bar')
     |  
     |  say(self, channel, message, length=None)
     |  
     |  sendLine(self, line)
     |  
     |  setNick(self, nickname)
     |  
     |  signedOn(self)
     |      Called after sucessfully signing on to the server.
     |  
     |  topic(self, channel, topic=None)
     |      Attempt to set the topic of the given channel, or ask what it is.
     |      
     |      If topic is None, then I sent a topic query instead of trying to set
     |      the topic. The server should respond with a TOPIC message containing
     |      the current topic of the given channel.
     |  
     |  topicUpdated(self, user, channel, newTopic)
     |      In channel, user changed the topic to newTopic.
     |      
     |      Also called when first joining a channel.
     |  
     |  userJoined(self, user, channel)
     |      Called when I see another user joining a channel.
     |  
     |  userKicked(self, kickee, channel, kicker, message)
     |      Called when I observe someone else being kicked from a channel.
     |  
     |  userLeft(self, user, channel)
     |      Called when I see another user leaving a channel.
     |  
     |  userRenamed(self, oldname, newname)
     |      A user changed their name from oldname to newname.
     |  
     |  yourHost(self, info)
     |      Called with daemon information about the server, usually at logon.
     |      
     |      @type info: C{str}
     |      @param when: A string describing what software the server is running, probably.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.protocols.irc.IRCClient:
     |  
     |  _MAX_PINGRING = 12
     |  
     |  __pychecker__ = 'unusednames=params,prefix,channel'
     |  
     |  _pings = None
     |  
     |  _queue = None
     |  
     |  _queueEmptying = None
     |  
     |  dcc_destdir = '.'
     |  
     |  dcc_sessions = None
     |  
     |  delimiter = '\n'
     |  
     |  fingerReply = None
     |  
     |  lineRate = None
     |  
     |  motd = ''
     |  
     |  nickname = 'irc'
     |  
     |  password = None
     |  
     |  performLogin = 1
     |  
     |  realname = None
     |  
     |  sourceURL = 'http://twistedmatrix.com/downloads/'
     |  
     |  userinfo = None
     |  
     |  versionEnv = None
     |  
     |  versionName = None
     |  
     |  versionNum = None
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.protocols.basic.LineReceiver:
     |  
     |  clearLineBuffer(self)
     |      Clear buffered data.
     |  
     |  lineLengthExceeded(self, line)
     |      Called when the maximum line length has been reached.
     |      Override if it needs to be dealt with in some special way.
     |  
     |  rawDataReceived(self, data)
     |      Override this for when raw data is received.
     |  
     |  setLineMode(self, extra='')
     |      Sets the line-mode of this receiver.
     |      
     |      If you are calling this from a rawDataReceived callback,
     |      you can pass in extra unhandled data, and that data will
     |      be parsed for lines.  Further data received will be sent
     |      to lineReceived rather than rawDataReceived.
     |  
     |  setRawMode(self)
     |      Sets the raw mode of this receiver.
     |      Further data received will be sent to rawDataReceived rather
     |      than lineReceived.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.protocols.basic.LineReceiver:
     |  
     |  MAX_LENGTH = 16384
     |  
     |  _LineReceiver__buffer = ''
     |  
     |  line_mode = 1
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.Protocol:
     |  
     |  connectionFailed(self)
     |      (Deprecated)
     |      
     |      This used to be called when the connection was not properly
     |      established.
     |  
     |  connectionLost(self, reason=&lt;twisted.python.failure.Failure twisted.internet.error.ConnectionDone&gt;)
     |      Called when the connection is shut down.
     |      
     |      Clear any circular references here, and any external references
     |      to this Protocol.  The connection has been closed.
     |      
     |      @type reason: L{twisted.python.failure.Failure}
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.Protocol:
     |  
     |  __implements__ = (&lt;class 'twisted.internet.interfaces.IProtocol'&gt;,)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.internet.protocol.BaseProtocol:
     |  
     |  makeConnection(self, transport)
     |      Make a connection to a transport and a server.
     |      
     |      This sets the 'transport' attribute of this Protocol, and calls the
     |      connectionMade() callback.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.internet.protocol.BaseProtocol:
     |  
     |  connected = 0
     |  
     |  transport = None
    
    class PerspectiveFingerFromService(twisted.spread.flavors.Root)
     |  Method resolution order:
     |      PerspectiveFingerFromService
     |      twisted.spread.flavors.Root
     |      twisted.spread.flavors.Referenceable
     |      twisted.spread.flavors.Serializable
     |      twisted.spread.jelly.Jellyable
     |  
     |  Methods defined here:
     |  
     |  __init__(self, service)
     |  
     |  remote_getUser(self, username)
     |  
     |  remote_getUsers(self)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __implements__ = ((&lt;class 'twisted.spread.flavors.IPBRoot'&gt;,), &lt;class ...
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.spread.flavors.Root:
     |  
     |  rootObject(self, broker)
     |      A L{pb.BrokerFactory} is requesting to publish me as a root object.
     |      
     |      When a L{pb.BrokerFactory} is sending me as the root object, this
     |      method will be invoked to allow per-broker versions of an
     |      object.  By default I return myself.
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.spread.flavors.Referenceable:
     |  
     |  jellyFor(self, jellier)
     |      (internal)
     |      
     |      Return a tuple which will be used as the s-expression to
     |      serialize this to a peer.
     |  
     |  remoteMessageReceived(self, broker, message, args, kw)
     |      A remote message has been received.  Dispatch it appropriately.
     |      
     |      The default implementation is to dispatch to a method called
     |      'remote_messagename' and call it with the same arguments.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.spread.flavors.Referenceable:
     |  
     |  perspective = None
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.spread.flavors.Serializable:
     |  
     |  processUniqueID(self)
     |      Return an ID which uniquely represents this object for this process.
     |      
     |      By default, this uses the 'id' builtin, but can be overridden to
     |      indicate that two values are identity-equivalent (such as proxies
     |      for the same object).
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.spread.jelly.Jellyable:
     |  
     |  getStateFor(self, jellier)
    
    class ServerContextFactory
     |  Methods defined here:
     |  
     |  getContext(self)
     |      Create an SSL context.
     |      
     |      This is a sample implementation that loads a certificate from a file
     |      called 'server.pem'.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
    
    class UserStatus(twisted.web.woven.page.Page)
     |  Method resolution order:
     |      UserStatus
     |      twisted.web.woven.page.Page
     |      twisted.web.woven.model.MethodModel
     |      twisted.web.woven.model.Model
     |      twisted.web.woven.controller.Controller
     |      twisted.web.resource.Resource
     |      twisted.web.woven.view.View
     |  
     |  Methods defined here:
     |  
     |  initialize(self, **kwargs)
     |  
     |  wmfactory_status(self, request)
     |  
     |  wmfactory_user(self, request)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  template = '&lt;html&gt;&lt;head&gt;&lt;title view="Text" model="user"/&gt;&lt;/h... model=...
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.page.Page:
     |  
     |  __init__(self, *args, **kwargs)
     |  
     |  getChild(self, name, request)
     |  
     |  renderView(self, request)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.page.Page:
     |  
     |  __implements__ = (&lt;class 'twisted.web.woven.interfaces.IModel'&gt;, (&lt;cla...
     |  
     |  appRoot = 0
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.model.MethodModel:
     |  
     |  getSubmodel(self, request=None, name=None)
     |  
     |  submodelCheck(self, request, name)
     |      Allow any submodel for which I have a submodel.
     |  
     |  submodelFactory(self, request, name)
     |      Call a wmfactory_name method on this model.
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.model.Model:
     |  
     |  __getstate__(self)
     |  
     |  addSubview(self, name, subview)
     |  
     |  addView(self, view)
     |      Add a view for the model to keep track of.
     |  
     |  dataWillChange(self)
     |  
     |  getData(self, request)
     |  
     |  invalidateCache(self)
     |      Invalidate the cache for this object, so the next time
     |      getData is called, it's getter method is called again.
     |  
     |  lookupSubmodel(self, request, submodelName)
     |      Look up a full submodel name. I will split on `/' and call
     |      L{getSubmodel} on each element in the 'path'.
     |      
     |      Override me if you don't want 'traversing'-style lookup, but
     |      would rather like to look up a model based on the entire model
     |      name specified.
     |      
     |      If you override me to return Deferreds, make sure I look up
     |      values in a cache (created by L{setSubmodel}) before doing a
     |      regular Deferred lookup.
     |      
     |      XXX: Move bits of this docstring to interfaces.py
     |  
     |  notify(self, changed=None)
     |      Notify all views that something was changed on me.
     |      Passing a dictionary of {'attribute': 'new value'} in changed
     |      will pass this dictionary to the view for increased performance.
     |      If you don't want to do this, don't, and just use the traditional
     |      MVC paradigm of querying the model for things you're interested
     |      in.
     |  
     |  removeView(self, view)
     |      Remove a view that the model no longer should keep track of.
     |  
     |  setData(self, request, data)
     |  
     |  setGetter(self, getter)
     |  
     |  setSetter(self, setter)
     |  
     |  setSubmodel(self, request=None, name=None, value=None)
     |      Set a submodel on this model. If getSubmodel or lookupSubmodel
     |      ever return a Deferred, I ought to set this in a place that
     |      lookupSubmodel/getSubmodel know about, so they can use it as a
     |      cache.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.model.Model:
     |  
     |  allowed_names = []
     |  
     |  protected_names = ['initialize', 'addView', 'addSubview', 'removeView'...
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.controller.Controller:
     |  
     |  aggregateInvalid(self, request, input, data)
     |  
     |  aggregateValid(self, request, input, data)
     |  
     |  domChanged(self, request, widget, node)
     |  
     |  exit(self, request)
     |      We are done handling the node to which this controller was attached.
     |  
     |  gatheredControllers(self, v, d, request)
     |  
     |  getDynamicChild(self, name, request)
     |      This method is called when getChild cannot find a matching wchild_*
     |      method in the Controller. Override me if you wish to have dynamic
     |      handling of child pages. Should return a Resource if appropriate.
     |      Return None to indicate no resource found.
     |      
     |      @param name: The name of the child being requested.
     |      @type name: string
     |      @param request: The HTTP request being handled.
     |      @type request: L{twisted.web.server.Request}
     |  
     |  getSubcontroller(self, request, node, model, controllerName)
     |  
     |  handle(self, request)
     |      By default, we don't do anything
     |  
     |  importControllerLibrary(self, namespace)
     |  
     |  makeView(self, model, templateFile=None, parentCount=0)
     |  
     |  pageRenderComplete(self, request)
     |      Override this to recieve notification when the view rendering
     |      process is complete.
     |  
     |  process(self, request, **kwargs)
     |  
     |  render(self, request)
     |      Trigger any inputhandlers that were passed in to this Page,
     |      then delegate to the View for traversing the DOM. Finally,
     |      call gatheredControllers to deal with any InputHandlers that
     |      were constructed from any controller= tags in the
     |      DOM. gatheredControllers will render the page to the browser
     |      when it is done.
     |  
     |  setNode(self, node)
     |  
     |  setSubcontrollerFactory(self, name, factory, setup=None)
     |  
     |  setUp(self, request, *args)
     |      @type request: L{twisted.web.server.Request}
     |  
     |  setView(self, view)
     |  
     |  setupControllerStack(self)
     |  
     |  wchild_index(self, request)
     |      By default, we return ourself as the index.
     |      Override this to provide different behavior
     |      for a URL that ends in a slash.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.controller.Controller:
     |  
     |  addSlash = 1
     |  
     |  controllerLibraries = [&lt;module 'twisted.web.woven.input' from '/usr/li...
     |  
     |  setupStacks = 1
     |  
     |  templateDirectory = ''
     |  
     |  viewFactory = None
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.resource.Resource:
     |  
     |  delEntity(self, name)
     |  
     |  getChildForRequest(self, request)
     |  
     |  getChildWithDefault(self, path, request)
     |      Retrieve a static or dynamically generated child resource from me.
     |      
     |      First checks if a resource was added manually by putChild, and then
     |      call getChild to check for dynamic resources. Only override if you want
     |      to affect behaviour of all child lookups, rather than just dynamic
     |      ones.
     |      
     |      This will check to see if I have a pre-registered child resource of the
     |      given name, and call getChild if I do not.
     |  
     |  getDynamicEntity(self, name, request)
     |  
     |  getStaticEntity(self, name)
     |  
     |  listDynamicEntities(self, request=None)
     |  
     |  listDynamicNames(self)
     |  
     |  listEntities(self)
     |  
     |  listNames(self)
     |  
     |  listStaticEntities(self)
     |  
     |  listStaticNames(self)
     |  
     |  putChild(self, path, child)
     |      Register a static child.
     |      
     |      You almost certainly don't want '/' in your path. If you
     |      intended to have the root of a folder, e.g. /foo/, you want
     |      path to be ''.
     |  
     |  reallyPutEntity(self, name, entity)
     |  
     |  render_HEAD(self, request)
     |      Default handling of HEAD method.
     |      
     |      I just return self.render_GET(request). When method is HEAD,
     |      the framework will handle this correctly.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.resource.Resource:
     |  
     |  entityType = &lt;class 'twisted.web.resource.IResource'&gt;
     |      A web resource.
     |  
     |  isLeaf = 0
     |  
     |  server = None
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.view.View:
     |  
     |  __setitem__(self, key, value)
     |  
     |  dispatchResult(self, request, node, result)
     |      Check a given result from handling a node and look up a NodeMutator
     |      adapter which will convert the result into a node and insert it
     |      into the DOM tree. Return the new node.
     |  
     |  dispatchResultCallback(self, result, request, node)
     |      Deal with a callback from a deferred, checking to see if it is
     |      ok to send the page yet or not.
     |  
     |  generate(self, request, node)
     |      Allow a view to be used like a widget. Will look up the template
     |      file and return it in place of the incoming node.
     |  
     |  getNodeController(self, request, node, submodel, model)
     |      Get a controller object to handle this node. If the node has no
     |      controller= attribute, first check to see if there is an IController
     |      adapter for our model.
     |  
     |  getNodeModel(self, request, node, submodel)
     |      Get the model object associated with this node. If this node has a
     |      model= attribute, call getSubmodel on the current model object.
     |      If not, return the top of the model stack.
     |  
     |  getNodeView(self, request, node, submodel, model)
     |  
     |  getSubview(self, request, node, model, viewName)
     |      Get a sub-view from me.
     |      
     |      @returns: L{widgets.Widget}
     |  
     |  getTemplate(self, request)
     |      Override this if you want to have your subclass look up its template
     |      using a different method.
     |  
     |  handleControllerResults(self, controllerResult, request, node, controller, view)
     |      Handle a deferred from a controller.
     |  
     |  handleDocument(self, request, document)
     |      Handle the root node, and send the page if there are no
     |      outstanding callbacks when it returns.
     |  
     |  handleNewNode(self, request, returnNode)
     |  
     |  handleNode(self, request, node)
     |  
     |  handleOutstanding(self, request)
     |  
     |  importViewLibrary(self, namespace)
     |  
     |  lookupTemplate(self, request)
     |      Use acquisition to look up the template named by self.templateFile,
     |      located anywhere above this object in the heirarchy, and use it
     |      as the template. The first time the template is used it is cached
     |      for speed.
     |  
     |  modelChanged(self, changed)
     |      Rerender this view, because our model has changed.
     |  
     |  recurseChildren(self, request, node)
     |      If this node has children, handle them.
     |  
     |  renderFailure(self, failure, request)
     |  
     |  sendPage(self, request)
     |      Check to see if handlers recorded any errors before sending the page
     |  
     |  setController(self, controller)
     |  
     |  setSubviewFactory(self, name, factory, setup=None, *args, **kwargs)
     |  
     |  setupAllStacks(self)
     |  
     |  setupViewStack(self)
     |  
     |  unlinkViews(self)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.view.View:
     |  
     |  doneCallback = None
     |  
     |  livePage = 0
     |  
     |  templateFile = ''
     |  
     |  templateNode = None
     |  
     |  viewLibraries = []
     |  
     |  wantsAllNotifications = 0
    
    class UserStatusTree(twisted.web.woven.page.Page)
     |  Method resolution order:
     |      UserStatusTree
     |      twisted.web.woven.page.Page
     |      twisted.web.woven.model.MethodModel
     |      twisted.web.woven.model.Model
     |      twisted.web.woven.controller.Controller
     |      twisted.web.resource.Resource
     |      twisted.web.woven.view.View
     |  
     |  Methods defined here:
     |  
     |  getDynamicChild(self, path, request)
     |  
     |  initialize(self, *args, **kwargs)
     |  
     |  wchild_RPC2(self, request)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  template = '&lt;html&gt;&lt;head&gt;&lt;title&gt;Users&lt;/title&gt;&lt;/head&gt;&lt;body&gt;\n  ...&gt;&lt;a vi...
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.page.Page:
     |  
     |  __init__(self, *args, **kwargs)
     |  
     |  getChild(self, name, request)
     |  
     |  renderView(self, request)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.page.Page:
     |  
     |  __implements__ = (&lt;class 'twisted.web.woven.interfaces.IModel'&gt;, (&lt;cla...
     |  
     |  appRoot = 0
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.model.MethodModel:
     |  
     |  getSubmodel(self, request=None, name=None)
     |  
     |  submodelCheck(self, request, name)
     |      Allow any submodel for which I have a submodel.
     |  
     |  submodelFactory(self, request, name)
     |      Call a wmfactory_name method on this model.
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.model.Model:
     |  
     |  __getstate__(self)
     |  
     |  addSubview(self, name, subview)
     |  
     |  addView(self, view)
     |      Add a view for the model to keep track of.
     |  
     |  dataWillChange(self)
     |  
     |  getData(self, request)
     |  
     |  invalidateCache(self)
     |      Invalidate the cache for this object, so the next time
     |      getData is called, it's getter method is called again.
     |  
     |  lookupSubmodel(self, request, submodelName)
     |      Look up a full submodel name. I will split on `/' and call
     |      L{getSubmodel} on each element in the 'path'.
     |      
     |      Override me if you don't want 'traversing'-style lookup, but
     |      would rather like to look up a model based on the entire model
     |      name specified.
     |      
     |      If you override me to return Deferreds, make sure I look up
     |      values in a cache (created by L{setSubmodel}) before doing a
     |      regular Deferred lookup.
     |      
     |      XXX: Move bits of this docstring to interfaces.py
     |  
     |  notify(self, changed=None)
     |      Notify all views that something was changed on me.
     |      Passing a dictionary of {'attribute': 'new value'} in changed
     |      will pass this dictionary to the view for increased performance.
     |      If you don't want to do this, don't, and just use the traditional
     |      MVC paradigm of querying the model for things you're interested
     |      in.
     |  
     |  removeView(self, view)
     |      Remove a view that the model no longer should keep track of.
     |  
     |  setData(self, request, data)
     |  
     |  setGetter(self, getter)
     |  
     |  setSetter(self, setter)
     |  
     |  setSubmodel(self, request=None, name=None, value=None)
     |      Set a submodel on this model. If getSubmodel or lookupSubmodel
     |      ever return a Deferred, I ought to set this in a place that
     |      lookupSubmodel/getSubmodel know about, so they can use it as a
     |      cache.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.model.Model:
     |  
     |  allowed_names = []
     |  
     |  protected_names = ['initialize', 'addView', 'addSubview', 'removeView'...
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.controller.Controller:
     |  
     |  aggregateInvalid(self, request, input, data)
     |  
     |  aggregateValid(self, request, input, data)
     |  
     |  domChanged(self, request, widget, node)
     |  
     |  exit(self, request)
     |      We are done handling the node to which this controller was attached.
     |  
     |  gatheredControllers(self, v, d, request)
     |  
     |  getSubcontroller(self, request, node, model, controllerName)
     |  
     |  handle(self, request)
     |      By default, we don't do anything
     |  
     |  importControllerLibrary(self, namespace)
     |  
     |  makeView(self, model, templateFile=None, parentCount=0)
     |  
     |  pageRenderComplete(self, request)
     |      Override this to recieve notification when the view rendering
     |      process is complete.
     |  
     |  process(self, request, **kwargs)
     |  
     |  render(self, request)
     |      Trigger any inputhandlers that were passed in to this Page,
     |      then delegate to the View for traversing the DOM. Finally,
     |      call gatheredControllers to deal with any InputHandlers that
     |      were constructed from any controller= tags in the
     |      DOM. gatheredControllers will render the page to the browser
     |      when it is done.
     |  
     |  setNode(self, node)
     |  
     |  setSubcontrollerFactory(self, name, factory, setup=None)
     |  
     |  setUp(self, request, *args)
     |      @type request: L{twisted.web.server.Request}
     |  
     |  setView(self, view)
     |  
     |  setupControllerStack(self)
     |  
     |  wchild_index(self, request)
     |      By default, we return ourself as the index.
     |      Override this to provide different behavior
     |      for a URL that ends in a slash.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.controller.Controller:
     |  
     |  addSlash = 1
     |  
     |  controllerLibraries = [&lt;module 'twisted.web.woven.input' from '/usr/li...
     |  
     |  setupStacks = 1
     |  
     |  templateDirectory = ''
     |  
     |  viewFactory = None
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.resource.Resource:
     |  
     |  delEntity(self, name)
     |  
     |  getChildForRequest(self, request)
     |  
     |  getChildWithDefault(self, path, request)
     |      Retrieve a static or dynamically generated child resource from me.
     |      
     |      First checks if a resource was added manually by putChild, and then
     |      call getChild to check for dynamic resources. Only override if you want
     |      to affect behaviour of all child lookups, rather than just dynamic
     |      ones.
     |      
     |      This will check to see if I have a pre-registered child resource of the
     |      given name, and call getChild if I do not.
     |  
     |  getDynamicEntity(self, name, request)
     |  
     |  getStaticEntity(self, name)
     |  
     |  listDynamicEntities(self, request=None)
     |  
     |  listDynamicNames(self)
     |  
     |  listEntities(self)
     |  
     |  listNames(self)
     |  
     |  listStaticEntities(self)
     |  
     |  listStaticNames(self)
     |  
     |  putChild(self, path, child)
     |      Register a static child.
     |      
     |      You almost certainly don't want '/' in your path. If you
     |      intended to have the root of a folder, e.g. /foo/, you want
     |      path to be ''.
     |  
     |  reallyPutEntity(self, name, entity)
     |  
     |  render_HEAD(self, request)
     |      Default handling of HEAD method.
     |      
     |      I just return self.render_GET(request). When method is HEAD,
     |      the framework will handle this correctly.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.resource.Resource:
     |  
     |  entityType = &lt;class 'twisted.web.resource.IResource'&gt;
     |      A web resource.
     |  
     |  isLeaf = 0
     |  
     |  server = None
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.view.View:
     |  
     |  __setitem__(self, key, value)
     |  
     |  dispatchResult(self, request, node, result)
     |      Check a given result from handling a node and look up a NodeMutator
     |      adapter which will convert the result into a node and insert it
     |      into the DOM tree. Return the new node.
     |  
     |  dispatchResultCallback(self, result, request, node)
     |      Deal with a callback from a deferred, checking to see if it is
     |      ok to send the page yet or not.
     |  
     |  generate(self, request, node)
     |      Allow a view to be used like a widget. Will look up the template
     |      file and return it in place of the incoming node.
     |  
     |  getNodeController(self, request, node, submodel, model)
     |      Get a controller object to handle this node. If the node has no
     |      controller= attribute, first check to see if there is an IController
     |      adapter for our model.
     |  
     |  getNodeModel(self, request, node, submodel)
     |      Get the model object associated with this node. If this node has a
     |      model= attribute, call getSubmodel on the current model object.
     |      If not, return the top of the model stack.
     |  
     |  getNodeView(self, request, node, submodel, model)
     |  
     |  getSubview(self, request, node, model, viewName)
     |      Get a sub-view from me.
     |      
     |      @returns: L{widgets.Widget}
     |  
     |  getTemplate(self, request)
     |      Override this if you want to have your subclass look up its template
     |      using a different method.
     |  
     |  handleControllerResults(self, controllerResult, request, node, controller, view)
     |      Handle a deferred from a controller.
     |  
     |  handleDocument(self, request, document)
     |      Handle the root node, and send the page if there are no
     |      outstanding callbacks when it returns.
     |  
     |  handleNewNode(self, request, returnNode)
     |  
     |  handleNode(self, request, node)
     |  
     |  handleOutstanding(self, request)
     |  
     |  importViewLibrary(self, namespace)
     |  
     |  lookupTemplate(self, request)
     |      Use acquisition to look up the template named by self.templateFile,
     |      located anywhere above this object in the heirarchy, and use it
     |      as the template. The first time the template is used it is cached
     |      for speed.
     |  
     |  modelChanged(self, changed)
     |      Rerender this view, because our model has changed.
     |  
     |  recurseChildren(self, request, node)
     |      If this node has children, handle them.
     |  
     |  renderFailure(self, failure, request)
     |  
     |  sendPage(self, request)
     |      Check to see if handlers recorded any errors before sending the page
     |  
     |  setController(self, controller)
     |  
     |  setSubviewFactory(self, name, factory, setup=None, *args, **kwargs)
     |  
     |  setupAllStacks(self)
     |  
     |  setupViewStack(self)
     |  
     |  unlinkViews(self)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.view.View:
     |  
     |  doneCallback = None
     |  
     |  livePage = 0
     |  
     |  templateFile = ''
     |  
     |  templateNode = None
     |  
     |  viewLibraries = []
     |  
     |  wantsAllNotifications = 0
    
    class UserStatusXR(twisted.web.xmlrpc.XMLRPC)
     |  Method resolution order:
     |      UserStatusXR
     |      twisted.web.xmlrpc.XMLRPC
     |      twisted.web.resource.Resource
     |  
     |  Methods defined here:
     |  
     |  __init__(self, service)
     |  
     |  xmlrpc_getUser(self, user)
     |  
     |  xmlrpc_getUsers(self)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.xmlrpc.XMLRPC:
     |  
     |  _cbRender(self, result, request)
     |  
     |  _ebRender(self, failure)
     |  
     |  _getFunction(self, functionPath)
     |      Given a string, return a function, or raise NoSuchFunction.
     |      
     |      This returned function will be called, and should return the result
     |      of the call, a Deferred, or a Fault instance.
     |      
     |      Override in subclasses if you want your own policy. The default
     |      policy is that given functionPath 'foo', return the method at
     |      self.xmlrpc_foo, i.e. getattr(self, "xmlrpc_" + functionPath).
     |      If functionPath contains self.separator, the sub-handler for
     |      the initial prefix is used to search for the remaining path.
     |  
     |  _listFunctions(self)
     |      Return a list of the names of all xmlrpc methods.
     |  
     |  getSubHandler(self, prefix)
     |  
     |  getSubHandlerPrefixes(self)
     |  
     |  putSubHandler(self, prefix, handler)
     |  
     |  render(self, request)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.xmlrpc.XMLRPC:
     |  
     |  FAILURE = 8002
     |  
     |  NOT_FOUND = 8001
     |  
     |  isLeaf = 1
     |  
     |  separator = '.'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.resource.Resource:
     |  
     |  delEntity(self, name)
     |  
     |  getChild(self, path, request)
     |      Retrieve a 'child' resource from me.
     |      
     |      Implement this to create dynamic resource generation -- resources which
     |      are always available may be registered with self.putChild().
     |      
     |      This will not be called if the class-level variable 'isLeaf' is set in
     |      your subclass; instead, the 'postpath' attribute of the request will be
     |      left as a list of the remaining path elements.
     |      
     |      For example, the URL /foo/bar/baz will normally be::
     |      
     |        | site.resource.getChild('foo').getChild('bar').getChild('baz').
     |      
     |      However, if the resource returned by 'bar' has isLeaf set to true, then
     |      the getChild call will never be made on it.
     |      
     |      @param path: a string, describing the child
     |      
     |      @param request: a twisted.web.server.Request specifying meta-information
     |                      about the request that is being made for this child.
     |  
     |  getChildForRequest(self, request)
     |  
     |  getChildWithDefault(self, path, request)
     |      Retrieve a static or dynamically generated child resource from me.
     |      
     |      First checks if a resource was added manually by putChild, and then
     |      call getChild to check for dynamic resources. Only override if you want
     |      to affect behaviour of all child lookups, rather than just dynamic
     |      ones.
     |      
     |      This will check to see if I have a pre-registered child resource of the
     |      given name, and call getChild if I do not.
     |  
     |  getDynamicEntity(self, name, request)
     |  
     |  getStaticEntity(self, name)
     |  
     |  listDynamicEntities(self, request=None)
     |  
     |  listDynamicNames(self)
     |  
     |  listEntities(self)
     |  
     |  listNames(self)
     |  
     |  listStaticEntities(self)
     |  
     |  listStaticNames(self)
     |  
     |  putChild(self, path, child)
     |      Register a static child.
     |      
     |      You almost certainly don't want '/' in your path. If you
     |      intended to have the root of a folder, e.g. /foo/, you want
     |      path to be ''.
     |  
     |  reallyPutEntity(self, name, entity)
     |  
     |  render_HEAD(self, request)
     |      Default handling of HEAD method.
     |      
     |      I just return self.render_GET(request). When method is HEAD,
     |      the framework will handle this correctly.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.resource.Resource:
     |  
     |  __implements__ = (&lt;class 'twisted.web.resource.IResource'&gt;,)
     |  
     |  entityType = &lt;class 'twisted.web.resource.IResource'&gt;
     |      A web resource.
     |  
     |  server = None
    
    class UsersModel(twisted.web.woven.model.MethodModel)
     |  Method resolution order:
     |      UsersModel
     |      twisted.web.woven.model.MethodModel
     |      twisted.web.woven.model.Model
     |  
     |  Methods defined here:
     |  
     |  initialize(self, *args, **kwargs)
     |  
     |  wmfactory_users(self, request)
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions defined here:
     |  
     |  __doc__ = None
     |  
     |  __module__ = 'finger22'
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.model.MethodModel:
     |  
     |  getSubmodel(self, request=None, name=None)
     |  
     |  submodelCheck(self, request, name)
     |      Allow any submodel for which I have a submodel.
     |  
     |  submodelFactory(self, request, name)
     |      Call a wmfactory_name method on this model.
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from twisted.web.woven.model.Model:
     |  
     |  __getstate__(self)
     |  
     |  __init__(self, *args, **kwargs)
     |  
     |  addSubview(self, name, subview)
     |  
     |  addView(self, view)
     |      Add a view for the model to keep track of.
     |  
     |  dataWillChange(self)
     |  
     |  getData(self, request)
     |  
     |  invalidateCache(self)
     |      Invalidate the cache for this object, so the next time
     |      getData is called, it's getter method is called again.
     |  
     |  lookupSubmodel(self, request, submodelName)
     |      Look up a full submodel name. I will split on `/' and call
     |      L{getSubmodel} on each element in the 'path'.
     |      
     |      Override me if you don't want 'traversing'-style lookup, but
     |      would rather like to look up a model based on the entire model
     |      name specified.
     |      
     |      If you override me to return Deferreds, make sure I look up
     |      values in a cache (created by L{setSubmodel}) before doing a
     |      regular Deferred lookup.
     |      
     |      XXX: Move bits of this docstring to interfaces.py
     |  
     |  notify(self, changed=None)
     |      Notify all views that something was changed on me.
     |      Passing a dictionary of {'attribute': 'new value'} in changed
     |      will pass this dictionary to the view for increased performance.
     |      If you don't want to do this, don't, and just use the traditional
     |      MVC paradigm of querying the model for things you're interested
     |      in.
     |  
     |  removeView(self, view)
     |      Remove a view that the model no longer should keep track of.
     |  
     |  setData(self, request, data)
     |  
     |  setGetter(self, getter)
     |  
     |  setSetter(self, setter)
     |  
     |  setSubmodel(self, request=None, name=None, value=None)
     |      Set a submodel on this model. If getSubmodel or lookupSubmodel
     |      ever return a Deferred, I ought to set this in a place that
     |      lookupSubmodel/getSubmodel know about, so they can use it as a
     |      cache.
     |  
     |  ----------------------------------------------------------------------
     |  Data and non-method functions inherited from twisted.web.woven.model.Model:
     |  
     |  __implements__ = &lt;class 'twisted.web.woven.interfaces.IModel'&gt;
     |      A MVC Model.
     |  
     |  allowed_names = []
     |  
     |  protected_names = ['initialize', 'addView', 'addSubview', 'removeView'...

FUNCTIONS
    catchError(err)

DATA
    __file__ = './finger22.pyc'
    __name__ = 'finger22'
    application = &lt;twisted.python.components.Componentized instance&gt;
    f = &lt;finger22.FingerService instance&gt;
    i = &lt;finger22.IRCClientFactoryFromService instance&gt;
    reactor = &lt;twisted.internet.default.SelectReactor instance&gt;
    serviceCollection = &lt;twisted.application.service.MultiService instance...
    site = &lt;twisted.web.server.Site instance&gt;

</t>
<t tx="root.20050203131715">
def hello():
    print "hello world"</t>
<t tx="root.20050203131715.1">import myModule
myModule.hello()</t>
<t tx="root.20050203132703">You can embed easily Python as the scripting language for your project of choice.
Example:
    Using Python as the scripting engine for a MMORPG platform implemented in a lower level language.
Resource:    
http://www.charlesriver.com/titles/pythongame.html</t>
<t tx="root.20050203133504">http://www.garshol.priv.no/download/text/perl.html</t>
<t tx="root.20050203133504.1">http://www.prescod.net/python/why.html</t>
<t tx="root.20050203133504.2">http://www.linuxjournal.com/article/3882</t>
<t tx="root.20050203133504.3">http://www.python.org/doc/essays/comparisons.html</t>
<t tx="root.20050203133504.4">http://page.mi.fu-berlin.de/~prechelt/Biblio/jccpprt_computer2000.pdf</t>
</tnodes>
</leo_file>
