summaryrefslogtreecommitdiff
path: root/pypers/pep318
diff options
context:
space:
mode:
authormichele.simionato <devnull@localhost>2007-12-02 11:13:11 +0000
committermichele.simionato <devnull@localhost>2007-12-02 11:13:11 +0000
commit20ce686b0193d67ea56823a30551140f88b3aee1 (patch)
tree76015e7e4dc0b000bd857a2bdba6fb7976ac29a7 /pypers/pep318
parentf08f40335ad7f0ac961f25dabaaed34c4d4bcc44 (diff)
downloadmicheles-20ce686b0193d67ea56823a30551140f88b3aee1.tar.gz
Commited all py papers into Google code
Diffstat (limited to 'pypers/pep318')
-rwxr-xr-xpypers/pep318/Makefile23
-rwxr-xr-xpypers/pep318/README.txt48
-rwxr-xr-xpypers/pep318/__main__.html61
-rwxr-xr-xpypers/pep318/addtests.txt232
-rwxr-xr-xpypers/pep318/bug.py50
-rwxr-xr-xpypers/pep318/bug.txt22
-rwxr-xr-xpypers/pep318/chatty.py28
-rwxr-xr-xpypers/pep318/chatty1.py21
-rwxr-xr-xpypers/pep318/chatty2.py28
-rwxr-xr-xpypers/pep318/chatty3.py13
-rwxr-xr-xpypers/pep318/customdec.py68
-rwxr-xr-xpypers/pep318/decorators.html1534
-rwxr-xr-xpypers/pep318/decorators.py184
-rwxr-xr-xpypers/pep318/decorators.tex1733
-rwxr-xr-xpypers/pep318/decorators.txt1413
-rwxr-xr-xpypers/pep318/example.py16
-rwxr-xr-xpypers/pep318/example1.py29
-rwxr-xr-xpypers/pep318/example2.py22
-rwxr-xr-xpypers/pep318/example3.py22
-rwxr-xr-xpypers/pep318/example4.py20
-rwxr-xr-xpypers/pep318/example5.py20
-rwxr-xr-xpypers/pep318/example6.py14
-rwxr-xr-xpypers/pep318/example7.py15
-rwxr-xr-xpypers/pep318/example8.py16
-rwxr-xr-xpypers/pep318/example9.py19
-rwxr-xr-xpypers/pep318/lessmeta/decorators.py210
-rwxr-xr-xpypers/pep318/logged.py8
-rwxr-xr-xpypers/pep318/mod.py11
-rwxr-xr-xpypers/pep318/module.py13
-rwxr-xr-xpypers/pep318/moduledec.py51
-rwxr-xr-xpypers/pep318/moduledec.txt97
-rwxr-xr-xpypers/pep318/mydoc.html51
-rwxr-xr-xpypers/pep318/nonrecognized.py23
-rwxr-xr-xpypers/pep318/oopp.html324
-rwxr-xr-xpypers/pep318/oopp.tex573
-rwxr-xr-xpypers/pep318/post.txt21
-rwxr-xr-xpypers/pep318/printerr.py7
-rwxr-xr-xpypers/pep318/prnt.py7
-rwxr-xr-xpypers/pep318/pro.py28
-rwxr-xr-xpypers/pep318/pro1.py7
-rwxr-xr-xpypers/pep318/pro1.txt10
-rwxr-xr-xpypers/pep318/pro2.py24
-rwxr-xr-xpypers/pep318/pro2.txt3
-rwxr-xr-xpypers/pep318/psyco.tex201
-rwxr-xr-xpypers/pep318/pydoc.html508
-rwxr-xr-xpypers/pep318/safetype.html33
-rwxr-xr-xpypers/pep318/safetype.tex61
-rwxr-xr-xpypers/pep318/tracing.py25
-rwxr-xr-xpypers/pep318/working/README.txt45
-rwxr-xr-xpypers/pep318/working/chatty2.py27
-rwxr-xr-xpypers/pep318/working/customdec.py67
-rwxr-xr-xpypers/pep318/working/debugger.py17
-rwxr-xr-xpypers/pep318/working/decorators.html1337
-rwxr-xr-xpypers/pep318/working/decorators.py173
-rwxr-xr-xpypers/pep318/working/decorators.txt1346
-rwxr-xr-xpypers/pep318/working/doct.py60
-rwxr-xr-xpypers/pep318/working/example.py16
-rwxr-xr-xpypers/pep318/working/example1.py29
-rwxr-xr-xpypers/pep318/working/example2.py36
-rwxr-xr-xpypers/pep318/working/example4.py22
-rwxr-xr-xpypers/pep318/working/example5.py20
-rwxr-xr-xpypers/pep318/working/example6.py14
-rwxr-xr-xpypers/pep318/working/example9.py19
-rwxr-xr-xpypers/pep318/working/logged.py8
-rwxr-xr-xpypers/pep318/working/noconflict.py64
-rwxr-xr-xpypers/pep318/working/pep318.html1046
-rwxr-xr-xpypers/pep318/working/pep318.txt1048
-rwxr-xr-xpypers/pep318/working/pydoc.html504
-rwxr-xr-xpypers/pep318/working/tracing.py20
-rwxr-xr-xpypers/pep318/x.py17
-rwxr-xr-xpypers/pep318/x.txt7
71 files changed, 13889 insertions, 0 deletions
diff --git a/pypers/pep318/Makefile b/pypers/pep318/Makefile
new file mode 100755
index 0000000..9249fb8
--- /dev/null
+++ b/pypers/pep318/Makefile
@@ -0,0 +1,23 @@
+decorators.rst: decorators.py $S/minidoc.py
+ $S/minidoc.py -r decorators -r
+decorators.html: decorators.txt decorators.png decorators.rst
+ $S/rst.py decorators.html
+decorators.dvi: decorators.txt decorators.rst
+ $S/rst.py -t decorators.tex
+ perl -pi -e 's/\(non-strict/\n(non-strict/' decorators.tex
+ perl -pi -e 's/as first/\nas first/' decorators.tex
+ $S/rst.py -d decorators.dvi
+decorators.pdf: decorators.dvi decorators.ps
+ dvipdf decorators
+decorators.ps: makegraph.dot
+ dot makegraph.dot -Tps -o decorators.ps -Gsize="5.5,6"
+decorators.png: makegraph.dot
+ dot makegraph.dot -Tpng -o decorators.png -Gsize="5.5,6"
+decorators.zip: decorators.html decorators.pdf \
+ decorators.py README.txt $S/safetype.py $S/doct.py
+ zip -j decorators decorators.py decorators.png decorators.ps \
+ decorators.html decorators.txt decorators.pdf decorators.rst\
+ README.txt makegraph.dot $S/safetype.py $S/doct.py
+dist: decorators.zip
+working: decorators.zip
+ unzip -o decorators.zip -d working
diff --git a/pypers/pep318/README.txt b/pypers/pep318/README.txt
new file mode 100755
index 0000000..341bf64
--- /dev/null
+++ b/pypers/pep318/README.txt
@@ -0,0 +1,48 @@
+DECORATORS README
+========================================================================
+
+The ``decorators`` distribution contains the following files:
+
+1. README.txt (your are reading it)
+
+2. decorators.txt (the documentation in ReStructuredText format)
+
+3. decorators.html (the documentation in HTML format)
+
+4. decorators.pdf (the documentation in pdf format)
+
+5. decorators.py (the heart of the distribution)
+
+6. noconflict.py (imported by decorators, resolves metaclass conflicts)
+
+7. doct.py (utility to extract tests from the documentation)
+
+8. decorators.ps (a figure included in decorators.pdf)
+
+9. decorators.png (a figure included in decorators.html)
+
+10. makegraph.dot (DOT script generating the figure)
+
+11. decorators.rst (the quick reference to decorators.py)
+
+12. safetype.rst (the quick reference to safetype.py)
+
+``noconflict`` and ``doct`` can be used as standalone
+modules too. They are documented in the on-line Python cookbook.
+
+After running ``python doct.py decorators.txt`` a number of files will be
+generated, including a module ``customdec.py`` containing the examples
+of custom decorators discussed in the documentation.
+
+If the tests fail, then there is something wrong with your Python
+installation, and I cannot help you since I don't have your machine
+at my disposal :-( It works for me both under Red Hat 7.3 and
+Windows 98SE. Notice that Python 2.3 is required.
+
+If you use the decorators module in your code (of course, you should
+not use it in production software!) and you find some bug of unexpected
+behaviour, please send a bug report to me:
+
+ MicheleSimionato@libero.it
+
+That's all, folks. Enjoy!
diff --git a/pypers/pep318/__main__.html b/pypers/pep318/__main__.html
new file mode 100755
index 0000000..06494a9
--- /dev/null
+++ b/pypers/pep318/__main__.html
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.2.9: http://docutils.sourceforge.net/" />
+<title>Documentation of the __main__ module</title>
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="documentation-of-the-main-module">
+<h1 class="title">Documentation of the __main__ module</h1>
+<p>Short utility to extract documentation from a module</p>
+<div class="section" id="documented-metaclasses">
+<h1><a name="documented-metaclasses">Documented metaclasses</a></h1>
+<div class="system-message">
+<p class="system-message-title">System Message: ERROR/3 (<tt>__main__.rst</tt>, line 6)</p>
+Section empty; must have contents.</div>
+</div>
+<div class="section" id="documented-classes">
+<h1><a name="documented-classes">Documented classes</a></h1>
+<div class="system-message">
+<p class="system-message-title">System Message: ERROR/3 (<tt>__main__.rst</tt>, line 10)</p>
+Section empty; must have contents.</div>
+</div>
+<div class="section" id="documented-functions">
+<h1><a name="documented-functions">Documented functions</a></h1>
+<p><tt class="literal"><span class="pre">publish_cmdline(reader=None,</span> <span class="pre">reader_name='standalone'</span></tt></p>
+<p>Set up &amp; run a <cite>Publisher</cite>. For command-line front ends.</p>
+<p>Parameters:</p>
+<ul class="simple">
+<li><cite>reader</cite>: A <cite>docutils.readers.Reader</cite> object.</li>
+<li><cite>reader_name</cite>: Name or alias of the Reader class to be instantiated if
+no <cite>reader</cite> supplied.</li>
+<li><cite>parser</cite>: A <cite>docutils.parsers.Parser</cite> object.</li>
+<li><cite>parser_name</cite>: Name or alias of the Parser class to be instantiated if
+no <cite>parser</cite> supplied.</li>
+<li><cite>writer</cite>: A <cite>docutils.writers.Writer</cite> object.</li>
+<li><cite>writer_name</cite>: Name or alias of the Writer class to be instantiated if
+no <cite>writer</cite> supplied.</li>
+<li><cite>settings</cite>: Runtime settings object.</li>
+<li><cite>settings_spec</cite>: Extra settings specification; a <cite>docutils.SettingsSpec</cite>
+subclass. Used only if no <cite>settings</cite> specified.</li>
+<li><cite>settings_overrides</cite>: A dictionary containing program-specific overrides
+of component settings.</li>
+<li><cite>argv</cite>: Command-line argument list to use instead of <tt class="literal"><span class="pre">sys.argv[1:]</span></tt>.</li>
+<li><cite>usage</cite>: Usage string, output if there's a problem parsing the command
+line.</li>
+<li><cite>description</cite>: Program description, output for the &quot;--help&quot; option
+(along with command-line option descriptions).</li>
+</ul>
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="__main__.rst">View document source</a>.
+Generated on: 2003-09-20 09:39 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/pypers/pep318/addtests.txt b/pypers/pep318/addtests.txt
new file mode 100755
index 0000000..67d96d2
--- /dev/null
+++ b/pypers/pep318/addtests.txt
@@ -0,0 +1,232 @@
+Additional tests
+=======================================================================
+
+You cannot add magic methods magically *after*:
+
+>>> from customdec import *
+>>> enhance_classes()
+
+
+>>> class C:
+... "[Decorated]"
+...
+>>> identity=lambda x:x
+>>> C.identity=identity
+>>> C.identity(1)
+Traceback (most recent call last):
+ ...
+TypeError: unbound method <lambda>() must be called with C instance as first argument (got int instance instead)
+
+(it could be done by modifying ``__setattr__`` in ``Decorated``).
+
+
+Usage of decorator
+------------------------------------------------------------------------
+
+>>> decorator(1)
+
+
+Printing representation
+------------------------------------------------------------------------
+
+A delicate point: inverting the docstring with __metaclass__
+
+>>> class M(type):
+... def __str__(cls):
+... return cls.__name__
+>>> class C(object):
+... __metaclass__=M
+... "[Decorated]" # not considered docstring!
+... def __str__(self):
+... return '<C>'
+>>> print C.__doc__
+None
+>>> C=decorator(C)
+>>> print type(C),C,C()
+<class 'safetype.MClassDecorator'> C <C>
+
+
+>>> class C(object):
+... "[Decorated]"
+... __metaclass__=M
+... def __str__(self):
+... return '<C>'
+>>> C=decorator(C)
+>>> print type(C),C,C()
+<class 'safetype.MClassDecoratorDecorated'> C <C>
+>>> #from MROgraph import MROgraph; g=MROgraph(type(C))
+
+Tricky ways of passing parameters to decorators
+------------------------------------------------------------------------
+
+This can be avoided by converting ``logfile`` from a class variable
+to an instance variable in the ``__init__`` method:
+
+ ::
+
+ #<chatty1.py>
+
+ import sys,customdec,decorators
+
+ class chattymethod1(customdec.chattymethod):
+ def __init__(self,func):
+ super(chattymethod1,self).__init__(func)
+ self.logfile=self.logfile # class variable -> instance variable
+
+ class D:
+ chattymethod1.logfile=sys.stdout
+ def f(self): pass
+ f=chattymethod1(f)
+
+ chattymethod1.logfile=file('file.log','w')
+ def g(self): pass
+ g=chattymethod1(g)
+
+ d=D()
+
+ #</chatty1.py>
+
+Here is the testing:
+
+>>> from chatty1 import D,d
+>>> D.f(d)
+calling <chattymethod1:f> from chatty1.D
+
+>>> D.g(d) # message written in file.log
+>>> D.f(d) # message correctly written in stdout, not in file.log
+calling <chattymethod1:f> from chatty1.D
+
+This works as it is but it is really ugly and fragile: for instance
+the magic docstring syntax
+
+ ::
+
+ class D:
+ "[Decorated]"
+ chattymethod1.logfile=sys.stdout
+ def f(self): "[chattymethod1]"
+
+ chattymethod1.logfile=file('file.log','w')
+ def g(self):"[chattymethod1]"
+
+
+will not work since the logfile attribute will be modified *before*
+the conversion in decorators, so both ``f`` and ``g`` will output to
+'file.log'.
+
+Tests on method wrappers
+-------------------------------------------------------
+
+>>> class C: pass
+...
+>>> c=C()
+>>> def f(x): return x
+...
+>>> sm=staticmethod(f)
+>>> C.sm=sm
+>>> C.sm.im_func # correct
+Traceback (most recent call last):
+ ...
+AttributeError: 'function' object has no attribute 'im_func'
+
+(idem for ``c.sm.im_func``). On the other hand
+
+>>> cm=classmethod(f)
+>>> C.cm=cm
+>>> assert C.cm.im_func is f
+>>> assert c.cm.im_func is f
+>>> assert C.cm.im_class is C
+>>> assert c.cm.im_class is C
+>>> assert C.cm.im_self is C
+>>> assert c.cm.im_self is C
+
+Test on tracedmethod from the instance
+-------------------------------------------------
+
+>>> from example6 import C
+>>> print C.__dict__['fact']
+<classmethodtracedmethod:fact>
+>>> C().fact(2)
+Calling 'C.fact' with arguments <class C[Decorated]>(2,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(1,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+
+
+Tests on composition of decorators
+-------------------------------------------------:
+
+To decorate something which is already decorated:
+
+>>> def g(x): "[tracedmethod]"
+...
+>>> tm=decorator(g) # creates a tracedmethod from f
+>>> print decorator(tm) # trying to decorate a tracedmethod
+<tracedmethod:g>
+
+Staticmethod vs classmethod.
+
+Staticmethod is non-cooperative, therefore staticmethodclassmethod
+acts as a pure staticmethod:
+
+>>> class C:
+... pass
+>>> c=C()
+>>> smcm=staticmethod(classmethod(f))
+>>> print smcm
+<staticmethodclassmethod:f>
+>>> C.smcm=smcm
+>>> C.smcm(1)
+1
+>>> c.smcm(1)
+1
+
+
+Classmethod vs staticmethod
+
+Idem: staticmethod gains:
+
+>>> cmsm=classmethod(staticmethod(f))
+>>> print cmsm
+<classmethodstaticmethod:f>
+>>> C.cmsm=cmsm
+>>> C.cmsm(1)
+1
+>>> c.cmsm(1)
+1
+
+
+Staticmethod vs tracedmethod works:
+
+>>> class C(object):
+... "[Decorated]"
+... def fact(n):
+... "[staticmethod, tracedmethod]"
+... if n==0: return 1
+... else: return n*C.fact(n-1)
+>>> C=decorator(C)
+
+Called from the class:
+
+>>> C.fact(2)
+Calling 'C.fact' with arguments 2(){} ...
+ Calling 'C.fact' with arguments 1(){} ...
+ Calling 'C.fact' with arguments (){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+
+Called from the instance:
+
+>>> C().fact(2)
+Calling 'C.fact' with arguments 2(){} ...
+ Calling 'C.fact' with arguments 1(){} ...
+ Calling 'C.fact' with arguments (){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
diff --git a/pypers/pep318/bug.py b/pypers/pep318/bug.py
new file mode 100755
index 0000000..f94a80f
--- /dev/null
+++ b/pypers/pep318/bug.py
@@ -0,0 +1,50 @@
+# bug.py
+
+"""
+
+Test a bug of doctest in redirecting stdout.
+
+The module prnt is as follows:
+
+# prnt.py
+import sys
+f=sys.stdout
+
+def hello():
+ print >> f, 'hello'
+
+Notice that
+
+ print >> sys.stdout, 'hello'
+
+and
+
+ print 'hello'
+
+would work instead!
+
+"""
+
+import doctest,__main__
+
+def f1():
+ """
+ First docstring saying
+
+ >>> import prnt
+ >>> prnt.hello()
+ hello
+
+ """
+
+def f2():
+ """
+ Second docstring saying
+
+ >>> import prnt
+ >>> prnt.hello()
+ hello
+
+ """
+
+doctest.testmod(__main__)
diff --git a/pypers/pep318/bug.txt b/pypers/pep318/bug.txt
new file mode 100755
index 0000000..8713044
--- /dev/null
+++ b/pypers/pep318/bug.txt
@@ -0,0 +1,22 @@
+Attention:
+
+get -> _get not possible! Why ?!
+
+
+Moreover:
+
+
+>>> from tracing import E
+>>> E.__dict__['__init__'].output=file('err','w')
+
+
+>>> e=E()
+ Calling 'B.__init__' with arguments <E instance>(){} ...
+ Calling 'D.__init__' with arguments <E instance>(){} ...
+ 'D.__init__' called with result: None
+ 'B.__init__' called with result: None
+
+
+>>> import chatty2
+>>> print file('file1.log').read().rstrip()
+calling <chattymethod2:f> from <C instance>
diff --git a/pypers/pep318/chatty.py b/pypers/pep318/chatty.py
new file mode 100755
index 0000000..432c161
--- /dev/null
+++ b/pypers/pep318/chatty.py
@@ -0,0 +1,28 @@
+# chatty.py
+
+from customdec import decorated,chattymethod
+chattymethod.logfile=file('file1.log','w')
+
+class C(object):
+ "[Decorated]"
+ def f():
+ "[chattymethod, staticmethod]"
+
+C=decorated(C)
+c=C()
+
+c.f()
+C.f()
+
+
+
+chattymethod.logfile=file('file2.log','w')
+
+def g():
+ "[chattymethod,staticmethod]"
+
+C.g=decorated(g)
+C.g # message written in file2.log
+C.f # message written in file2.log
+
+
diff --git a/pypers/pep318/chatty1.py b/pypers/pep318/chatty1.py
new file mode 100755
index 0000000..649f6f2
--- /dev/null
+++ b/pypers/pep318/chatty1.py
@@ -0,0 +1,21 @@
+# chatty1.py
+
+import sys,customdec,decorators
+
+class chattymethod1(customdec.chattymethod):
+ def __init__(self,func):
+ super(chattymethod1,self).__init__(func)
+ self.logfile=self.logfile # class variable -> instance variable
+
+class D:
+ chattymethod1.logfile=sys.stdout
+ def f(self): pass
+ f=chattymethod1(f)
+
+ chattymethod1.logfile=file('file.log','w')
+ def g(self): pass
+ g=chattymethod1(g)
+
+d=D()
+
+
diff --git a/pypers/pep318/chatty2.py b/pypers/pep318/chatty2.py
new file mode 100755
index 0000000..38be546
--- /dev/null
+++ b/pypers/pep318/chatty2.py
@@ -0,0 +1,28 @@
+# chatty2.py
+
+import customdec; customdec.enhance_classes()
+
+# sets the log files
+log1=file('file1.log','w')
+log2=file('file2.log','w')
+
+class C:
+ "[Decorated]"
+ def f(self):
+ "[chattymethod2]"
+ f.logfile=log1 # function attribute
+ def g(self):
+ "[chattymethod2]"
+ g.logfile=log2 # function attribute
+
+assert C.__dict__['f'].logfile is log1 # check the conversion
+assert C.__dict__['g'].logfile is log2 # function attr. -> decorator attr.
+
+c=C() # C instantiation
+
+c.f() # print a message in file1.log
+c.g() # print a message in file2.log
+
+log1.close(); log2.close() # finally
+
+
diff --git a/pypers/pep318/chatty3.py b/pypers/pep318/chatty3.py
new file mode 100755
index 0000000..d1895d9
--- /dev/null
+++ b/pypers/pep318/chatty3.py
@@ -0,0 +1,13 @@
+# chatty3.py
+
+"[Decorated]"
+
+import decorators,customdec; decorators.decorated()
+
+class C:
+ def f():
+ "[chattymethod2, staticmethod]"
+
+c=C()
+
+
diff --git a/pypers/pep318/customdec.py b/pypers/pep318/customdec.py
new file mode 100755
index 0000000..52a0d0d
--- /dev/null
+++ b/pypers/pep318/customdec.py
@@ -0,0 +1,68 @@
+# customdec.py
+
+from decorators import *
+
+class chattymethod(MethodDecorator):
+ logfile=sys.stdout # default
+ def get(self,obj,cls=None): # same signature as __get__
+ self.logfile.write('calling %s from %s\n' % (self,obj or cls))
+ return super(chattymethod,self).get(obj,cls)
+
+
+
+class chattymethod2(chattymethod):
+ logfile=sys.stdout # default
+ def __init__(self,objfunc):
+ super(chattymethod2,self).__init__(objfunc)
+ logfile=getattr(self.__func__,'logfile',None)
+ if logfile: self.logfile=logfile
+
+
+
+class tracedmethod(MethodDecorator):
+ "Descriptor class, converts a method in a traced method"
+ indent=0; output=sys.stdout # defaults
+
+ def __init__(self,objfunc):
+ super(tracedmethod,self).__init__(objfunc)
+ self.funcname=self.__func__.__name__
+ output=getattr(self.__func__,'output',None)
+ if output: self.output=output # func.attr. -> dec.attr.
+
+ def get(self,obj,cls):
+ clsname=self.__klass__.__name__ # definition clas
+ def tracedmeth(obj,*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write("%sCalling '%s.%s' with arguments " %
+ (i,clsname,self.funcname))
+ self.output.write("%s%s ...\n" % (obj or '',str(args)+str(kw)))
+ res=super(tracedmethod,self).get(obj,cls)(*args,**kw)
+ self.output.write("%s'%s.%s' called with result: %s\n"
+ % (i,clsname,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return tracedmeth.__get__(obj,cls) # method wrapper
+
+
+
+class Logged(ClassDecorator):
+ output=sys.stdout
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print >> cls.output,"%s created" % cls
+
+
+
+from types import FunctionType
+
+class Traced(Decorated):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType) and name!='__str__':
+ # cannot trace __str__, since it is invoked by
+ # tracedmethod and would generate infinite recursion
+ func.__doc__="[tracedmethod] " + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d) # decorates the methods
+
+
diff --git a/pypers/pep318/decorators.html b/pypers/pep318/decorators.html
new file mode 100755
index 0000000..59d584f
--- /dev/null
+++ b/pypers/pep318/decorators.html
@@ -0,0 +1,1534 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.2.9: http://docutils.sourceforge.net/" />
+<title>Implementing PEP 318 (decorators)</title>
+<meta name="author" content="Michele Simionato" />
+<meta name="date" content="September 2003" />
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="implementing-pep-318-decorators">
+<h1 class="title">Implementing PEP 318 (decorators)</h1>
+<table class="docinfo" frame="void" rules="none">
+<col class="docinfo-name" />
+<col class="docinfo-content" />
+<tbody valign="top">
+<tr class="field"><th class="docinfo-name">Module:</th><td class="field-body">decorators</td>
+</tr>
+<tr><th class="docinfo-name">Version:</th>
+<td>0.5</td></tr>
+<tr><th class="docinfo-name">Author:</th>
+<td>Michele Simionato</td></tr>
+<tr class="field"><th class="docinfo-name">e-mail:</th><td class="field-body"><a class="reference" href="mailto:MicheleSimionato&#64;libero.it">MicheleSimionato&#64;libero.it</a></td>
+</tr>
+<tr class="field"><th class="docinfo-name">Licence:</th><td class="field-body">Python-like</td>
+</tr>
+<tr><th class="docinfo-name">Date:</th>
+<td>September 2003</td></tr>
+<tr class="field"><th class="docinfo-name">Disclaimer:</th><td class="field-body">This is experimental code. Use it at your own risk!</td>
+</tr>
+</tbody>
+</table>
+<div class="contents topic" id="contents">
+<p class="topic-title"><a name="contents">Contents</a></p>
+<ul class="simple">
+<li><a class="reference" href="#using-decorators" id="id4" name="id4">Using decorators</a><ul>
+<li><a class="reference" href="#basics" id="id5" name="id5">Basics</a></li>
+<li><a class="reference" href="#decorating-methods" id="id6" name="id6">Decorating methods</a></li>
+<li><a class="reference" href="#decorating-classes" id="id7" name="id7">Decorating classes</a></li>
+<li><a class="reference" href="#adding-magic" id="id8" name="id8">Adding magic</a></li>
+<li><a class="reference" href="#defining-method-decorators" id="id9" name="id9">Defining method decorators</a></li>
+<li><a class="reference" href="#defining-class-decorators" id="id10" name="id10">Defining class decorators</a></li>
+<li><a class="reference" href="#composing-decorators" id="id11" name="id11">Composing decorators</a></li>
+<li><a class="reference" href="#diving-into-magic" id="id12" name="id12">Diving into magic</a></li>
+<li><a class="reference" href="#advanced-usage" id="id13" name="id13">Advanced usage</a></li>
+</ul>
+</li>
+<li><a class="reference" href="#the-implementation" id="id14" name="id14">The implementation</a><ul>
+<li><a class="reference" href="#module-decorators" id="id15" name="id15">Module <tt class="literal"><span class="pre">decorators</span></tt></a><ul>
+<li><a class="reference" href="#id3" id="id16" name="id16">Metaclasses</a></li>
+<li><a class="reference" href="#classes" id="id17" name="id17">Classes</a></li>
+<li><a class="reference" href="#functions" id="id18" name="id18">Functions</a></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</div>
+<div class="section" id="using-decorators">
+<h1><a class="toc-backref" href="#id4" name="using-decorators">Using decorators</a></h1>
+<p>Having plenty of free time in these days, I have finished an old
+project of mine, the implementation of <a class="reference" href="http://www.python.org/pep">PEP 318</a> in pure Python
+(2.3).</p>
+<p>Here is the rationale:</p>
+<ul class="simple">
+<li>some kind of decorator syntax is scheduled to go in Python 2.4,
+therefore it is interesting to play with the concept;</li>
+<li>it is nice to play with decorators now, without having to
+wait for one year or so;</li>
+<li>it is much easier to experiment with a pure Python implementation
+than with a C implementation;</li>
+<li>the implementation can be seen as an exercise on modern Python
+programming and may be valuable to people wanting to study the most
+advanced new constructs in Python (<a class="reference" href="http://users.rcn.com/python/download/Descriptor.htm">descriptors</a>, <a class="reference" href="http://www-106.ibm.com/developerworks/library/l-pymeta2.html">metaclasses</a>,
+<a class="reference" href="http://www.python.org/2.3/descrintro.html">cooperative methods</a>, etc.)</li>
+</ul>
+<div class="section" id="basics">
+<h2><a class="toc-backref" href="#id5" name="basics">Basics</a></h2>
+<p>PEP 318 has the goal of providing a nice syntactic sugar for expressions like</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x):
+ return x
+identity=staticmethod(identity)
+</pre>
+</blockquote>
+<p>or</p>
+<blockquote>
+<pre class="literal-block">
+def name(cls):
+ return cls.__name__
+name=classmethod(name)
+</pre>
+</blockquote>
+<p>which are pretty verbose. It is clear that having new syntax (as
+for instance the proposed square bracket notation)</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x)[staticmethod]:
+ return x
+
+def name(cls)[classmethod]:
+ return cls.__name__
+</pre>
+</blockquote>
+<p>involves changing the grammar and modifying the interpreter at the
+C level. This means a lot of work. Fortunately, it is possible to
+have the same effect without changing the Python grammar.
+The idea is to use magic docstrings like this:</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+def name(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+</pre>
+</blockquote>
+<p>The implementation is able to recognize such magic docstrings
+and automatically converts methods with magic docstrings in
+method decorators.</p>
+<p>Decorators are nothing else than a sophisticated kind of wrappers.
+The <tt class="literal"><span class="pre">decorators</span></tt> module provides support both for method decorators
+and class decorators:</p>
+<ul class="simple">
+<li><em>Method decorators</em> are classes taking a single function as input and
+producing a descriptor object as output. <tt class="literal"><span class="pre">staticmethod</span></tt> and
+<tt class="literal"><span class="pre">classmethod</span></tt> are two examples of already existing
+method decorators (actually my implementation rewrites them).
+A knowledge of descriptors <a class="footnote-reference" href="#id2" id="id1" name="id1">[1]</a> is not needed in order to use the <tt class="literal"><span class="pre">decorator</span></tt>
+module; however it is welcomed for advanced users wanting to implement
+custom method decorators.</li>
+<li><em>Class decorators</em> are metaclasses taking a class as imput and returning
+a decorated class as output. A good understanding of metaclasses is needed
+in order to be able to write custom class decorators, but no knowledge
+at all is required in order to use the pre-defined class decorators
+provided by the module.</li>
+</ul>
+<p>Notice that properties are not decorators according to my definitions,
+since they take four functions as input, <tt class="literal"><span class="pre">get,</span> <span class="pre">set,</span> <span class="pre">del_</span></tt> and <tt class="literal"><span class="pre">doc</span></tt>.
+Whereas the decorators concept could be generalized to the case of
+multiple inputs, I don't see the need for such complication, so
+properties are not implemented as method decorators. Moreover, I
+think it is much better to use them trough a class decorator.</p>
+<p>Finally, the module is meant to be extensible; so one could
+define new kind of decorators. For instance, the original version of
+the module also had the concept of module decorators; however I have cut
+down that part in order to keep the documentation short.</p>
+<p>Admittedly, the implementation
+is not for the faint of heart, nevertheless I have tried to make the
+basic usage easy and simple to understand.</p>
+<table class="footnote" frame="void" id="id2" rules="none">
+<colgroup><col class="label" /><col /></colgroup>
+<tbody valign="top">
+<tr><td class="label"><a class="fn-backref" href="#id1" name="id2">[1]</a></td><td>Descriptors are objects with a <tt class="literal"><span class="pre">__get__</span></tt> method; they are quite
+sophisticated, but fortunately they have been wonderfully explained by
+Raymond Hettinger already, so I am allowed to skip on this point ;).</td></tr>
+</tbody>
+</table>
+</div>
+<div class="section" id="decorating-methods">
+<h2><a class="toc-backref" href="#id6" name="decorating-methods">Decorating methods</a></h2>
+<p>Before talking about the implementation details, I will show
+how the <tt class="literal"><span class="pre">decorators</span></tt> module works in practice. The simplest and safest
+usage is by means of the <tt class="literal"><span class="pre">decorators.decorated()</span></tt> function, which
+takes an object (a function or a class) and checks its docstring: if
+a magic docstring is found, it returns a decorated version of the object,
+otherwise it returns the original object. Using <tt class="literal"><span class="pre">decorators.decorated()</span></tt>
+is simple but verbose, so magic shortcuts will be discussed in the next
+sections.</p>
+<p>Here, let me give an example, showing that method decorators work both for
+<a class="reference" href="http://www.python.org/2.3/descrintro.html">new style classes and old style classes</a>:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example1.py&gt;
+
+import decorators
+
+def do_nothing(self):
+ &quot;No magic docstring here&quot;
+dec_do_nothing=decorators.decorated(do_nothing)
+
+def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+dec_identity=decorators.decorated(identity)
+
+def name(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+dec_name=decorators.decorated(name)
+
+class OldStyle:
+ do_nothing=dec_do_nothing
+ identity=dec_identity
+
+class NewStyle(object):
+ name=dec_name
+
+o=OldStyle() # creates an old style instance
+n=NewStyle() # creates a new style instance
+
+#&lt;/example1.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example1 import * # for testing purposes
+</pre>
+<p>In this example, both <tt class="literal"><span class="pre">dec_identity</span></tt> and <tt class="literal"><span class="pre">dec_name</span></tt> are decorator objects,
+i.e. descriptors modifiying the attribute access. It is easy to recognize
+decorators objects in the interpreter, since they have a re-defined
+printing representation:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; print dec_identity
+&lt;staticmethod:identity&gt;
+&gt;&gt;&gt; print dec_name
+&lt;classmethod:name&gt;
+</pre>
+<p>On the other hand, <tt class="literal"><span class="pre">do_nothing</span></tt> does not have a magic
+docstring, therefore it is not converted to a decorator object;
+actually it is <em>exactly</em> the original function</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; dec_do_nothing is do_nothing # not converted
+True
+</pre>
+<p>and it works as a standard method:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; o.do_nothing() # does nothing, correct
+</pre>
+<p>On the contrary, <tt class="literal"><span class="pre">dec_</span> <span class="pre">identity</span></tt> works as a staticmethod,</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; OldStyle.identity(1) # called from the class
+1
+&gt;&gt;&gt; o.identity(1) # called from the instance
+1
+</pre>
+<p>whereas <tt class="literal"><span class="pre">dec_name</span></tt> works as a classmethod:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; NewStyle.name() # called from the class
+'NewStyle'
+&gt;&gt;&gt; n.name() # called from the instance
+'NewStyle'
+</pre>
+<p>Notice that, I have re-implemented the built-in
+<tt class="literal"><span class="pre">staticmethod</span></tt> and <tt class="literal"><span class="pre">classmethod</span></tt>, so</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; isinstance(dec_identity,staticmethod)
+False
+</pre>
+<p>and</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; isinstance(dec_name,classmethod)
+False
+</pre>
+<p>It is possible to recognize method decorators since they provides
+a couple of special attributes:</p>
+<ul>
+<li><p class="first"><tt class="literal"><span class="pre">__func__</span></tt>: returning the function from which they originated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert dec_identity.__func__ is identity
+&gt;&gt;&gt; assert dec_name.__func__ is name
+</pre>
+</li>
+<li><p class="first"><tt class="literal"><span class="pre">__klass__</span></tt>: returning the class where they where defined:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; dec_identity.__klass__
+&lt;class 'safetype.?'&gt;
+</pre>
+</li>
+</ul>
+<p>The question mark here means that the definition class is unknown.
+The <tt class="literal"><span class="pre">__klass__</span></tt> attribute can be set by hand or automatically
+with the trick explained in the next section.</p>
+</div>
+<div class="section" id="decorating-classes">
+<h2><a class="toc-backref" href="#id7" name="decorating-classes">Decorating classes</a></h2>
+<p>The problem with the approach just described
+is that it does not present any significant advantage over
+the already existing mechanism. A real step forward would be to
+have classes with the ability of automatically decorating their
+methods according to the docstrings.
+This sounds a bit of magic, but actually can be done very simply
+by adding to the class a docstring starting with &quot;[Decorated]&quot;
+and by decorating the class.
+Here is an example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example2.py&gt;
+
+from decorators import decorated
+from example1 import do_nothing,identity,name
+
+class B(object):
+ &quot;This is a regular class&quot;
+
+B=decorated(B) # does nothing
+
+class C(B):
+ &quot;[Decorated]&quot;
+ do_nothing=do_nothing
+ identity=identity
+ class Inner: # old style class
+ &quot;[Decorated]&quot; # required docstring
+ name=name
+
+C=decorated(C) # regenerates the class converting methods in decorators
+c=C()
+
+#&lt;/example2.py&gt;
+</pre>
+</blockquote>
+<p>Under the hood <tt class="literal"><span class="pre">decorators.decorated()</span></tt> recognizes the class level
+magic docstring &quot;[Decorated]&quot; and creates an instance of the
+<tt class="literal"><span class="pre">decorators.Decorated</span></tt> metaclass.
+Internally the metaclass invokes <tt class="literal"><span class="pre">decorators.decorated()</span></tt>
+on the methods of its instances: this is why they becomes decorated
+if a suitable docstring is found. Moreover, it decorates inner classes,
+if a suitable docstring is found, and it works recursively.</p>
+<p>Here is the testing:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example2 import *
+&gt;&gt;&gt; assert C.identity(1) == 1
+&gt;&gt;&gt; assert C.Inner.name() == 'Inner'
+&gt;&gt;&gt; assert c.identity(1) == 1
+&gt;&gt;&gt; assert c.Inner.name() == 'Inner'
+</pre>
+<p>Notice that adding <tt class="literal"><span class="pre">identity</span></tt> after the class creation with the syntax
+<tt class="literal"><span class="pre">C.identity=identity</span></tt> would not work;
+<tt class="literal"><span class="pre">C.identity=decorators.decorated(identity)</span></tt> is required:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.identity=decorators.decorated(identity)
+&gt;&gt;&gt; C.identity(1) # it works
+1
+</pre>
+<p>If a class misses the magic docstring, nothing happens:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; B # returns the original B
+&lt;class 'example2.B'&gt;
+</pre>
+<p>The mechanism works for old style classes too,
+since the metaclass automagically converts the old style classes in a
+new style one:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; type(C.Inner) # C.Inner is an instance of decorator.Decorated
+&lt;class 'decorators.Decorated'&gt;
+</pre>
+<p>The enhancement provided by the metaclass includes a new default
+printing representation for both the class</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; print C # returns the name of D and of its metaclass
+&lt;class C[Decorated]&gt;
+</pre>
+<p>and its instances:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; print c
+&lt;C instance&gt;
+</pre>
+<p>On the other hand, if a custom printing representation is already
+defined, the metaclass takes it without any change.</p>
+<p>One can even forget the docstring in subclasses of decorated
+classes, since metaclasses are inherited:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D(C):
+... def name(cls):
+... &quot;[classmethod]&quot;
+... return cls.__name__
+&gt;&gt;&gt; print D.name()
+D
+</pre>
+<p>Decorating whole classes presents another advantage: the decorated methods know
+the class where they were defined via the special attribute <tt class="literal"><span class="pre">__klass__</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; D.__dict__['name'].__klass__ # the class where 'name' is defined
+&lt;class 'D'&gt;
+</pre>
+<p>This is useful for introspection and debugging purposes.</p>
+</div>
+<div class="section" id="adding-magic">
+<h2><a class="toc-backref" href="#id8" name="adding-magic">Adding magic</a></h2>
+<p>The problem of the previous approach is that one must explicitely
+decorate the classes by hand, by invoking <tt class="literal"><span class="pre">decorators.decorated()</span></tt>
+each time. However, it is possible to add more magic
+and to decorate all the classes automatically.
+It is as easy as writing <tt class="literal"><span class="pre">decorators.enhance_classes()</span></tt>
+on top of you module. Then all methods in all classes with a magic docstring
+will be checked for magic docstrings and automagically decorated if needed.
+For instance, the previous example would be written</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example3.py&gt;
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ &quot;[Decorated]&quot; # magic docstring here
+ def do_nothing(self):
+ &quot;No magic docstring here&quot;
+
+ def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+class D(object):
+ &quot;Undecorated&quot; # no magic docstring here
+ def name(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+
+c=C(); d=D()
+
+#&lt;/example3.py&gt;
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">C</span></tt> has a <tt class="literal"><span class="pre">[Decorated]</span></tt> docstring, so its methods
+are automatically decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example3 import *
+&gt;&gt;&gt; assert c.do_nothing() is None
+&gt;&gt;&gt; assert C.identity(1) == 1
+&gt;&gt;&gt; assert c.identity(1) == 1
+</pre>
+<p>On the other hand, since <tt class="literal"><span class="pre">D</span></tt> misses a magic docstring,
+its <tt class="literal"><span class="pre">name</span></tt> method is not decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; hasattr(D.__dict__['name'],'__func__') # not a decorator
+False
+</pre>
+<p>Since <tt class="literal"><span class="pre">D.name</span></tt> is a regular method and not a classmethod, <tt class="literal"><span class="pre">D.name()</span></tt>
+gives an error:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; D.name()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method name() must be called with D instance as first argument (got nothing instead)
+</pre>
+<p>Under the hood, the magic works by enhancing the <tt class="literal"><span class="pre">object</span></tt> class
+of the module with a <tt class="literal"><span class="pre">decorators.ClassDecorator</span></tt> metaclass:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import example4
+&gt;&gt;&gt; type(example4.object)
+&lt;class 'decorators.ClassDecorator'&gt;
+</pre>
+<p>Notice that for safety reasons the enhancement is only on the module
+<tt class="literal"><span class="pre">object</span></tt> class, not on the <tt class="literal"><span class="pre">__builtin__.object</span></tt> class. The dangers of
+adding too much magic are discussed in the <a class="reference" href="#diving-into-magic">Diving into magic</a> section.</p>
+</div>
+<div class="section" id="defining-method-decorators">
+<h2><a class="toc-backref" href="#id9" name="defining-method-decorators">Defining method decorators</a></h2>
+<p>The <tt class="literal"><span class="pre">decorators</span></tt> module contains two predefinite method decorators,
+<tt class="literal"><span class="pre">staticmethod</span></tt> and <tt class="literal"><span class="pre">classmethod</span></tt>, which emulate the built-ins
+with the same names. However, it is possible to write your own
+custom decorators. The <tt class="literal"><span class="pre">decorators.MethodDecorator</span></tt> class which is here
+exactly for that purpose.</p>
+<p>Custom decorators are expected to be implemented by subclassing
+<tt class="literal"><span class="pre">MethodDecorator</span></tt> and by overriding its <tt class="literal"><span class="pre">get</span></tt> method. The
+<tt class="literal"><span class="pre">get</span></tt> method automagically induces a <tt class="literal"><span class="pre">__get__</span></tt> method, turning the
+class in a descriptor. The machinery is needed since <tt class="literal"><span class="pre">__get__</span></tt> cannot
+be made cooperative using the standard <tt class="literal"><span class="pre">super</span></tt> mechanism because
+there would be a confusion between <tt class="literal"><span class="pre">super.__get__</span></tt> and the decorator
+<tt class="literal"><span class="pre">__get__</span></tt>. This is a bit tricky, but the causal programmer is not
+expected to write custom decorators, and actually I don't want to make
+the access to decorators <em>too</em> easy, since they are potentially dangerous.</p>
+<p>In order to give a simple example, let me show the implementation
+of a <tt class="literal"><span class="pre">chattymethod</span></tt> that prints a message when it is called:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+from decorators import *
+
+class chattymethod(MethodDecorator):
+ logfile=sys.stdout # default
+ def get(self,obj,cls=None): # same signature as __get__
+ self.logfile.write('calling %s from %s\n' % (self,obj or cls))
+ return super(chattymethod,self).get(obj,cls)
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p>Notice the usage of the <tt class="literal"><span class="pre">super().get</span></tt> trick. This guarantees that
+<tt class="literal"><span class="pre">chattymethod</span></tt> will play well with other decorators (i.e. it
+can be nicely composed via multiple inheritance). The point will
+be fully discussed in the section on composing decorators.</p>
+<p>Here is an example of usage:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import customdec # adds chattymethod to the list of known decorators
+&gt;&gt;&gt; customdec.enhance_classes() # automagically enhances classes
+&gt;&gt;&gt; class C:
+... &quot; [Decorated] &quot;
+... def f(self):
+... &quot;&quot;&quot;
+... [ chattymethod ]
+... &quot;&quot;&quot;
+&gt;&gt;&gt; c=C()
+&gt;&gt;&gt; c.f()
+calling &lt;chattymethod:f&gt; from &lt;C instance&gt;
+</pre>
+<p>By the way, this shows that one can safely add whitespaces (including
+newlines) to the magic docstring: they are simply ignored.</p>
+<p>One can check that the syntax <tt class="literal"><span class="pre">C.f(c)</span></tt> works too:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.f(c)
+calling &lt;chattymethod:f&gt; from &lt;class C[Decorated]&gt;
+</pre>
+<p>A tricky point of the decorators mechanism is the issue of parameter passing.
+In comp.lang.python there was the proposal of allowing explicit parameter
+passing to decorators, with a syntax of kind</p>
+<blockquote>
+<pre class="literal-block">
+def f(self)[chattymethod(logfile=file('file1.log','w'))]
+</pre>
+</blockquote>
+<p>In my view, there are too many parenthesis in this syntax, and it
+becomes rapidly unreadable. Moreover, it complicates the implementation
+without any real benefit, so the <tt class="literal"><span class="pre">decorators</span></tt> module does not allow
+this kind of parameter passings. There are however viable
+workarounds, so you should not miss the syntax.</p>
+<p>A simple minded solution is to change the defaults by hand:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from customdec import chattymethod,decorated
+&gt;&gt;&gt; chattymethod.logfile=file('file.log','w')
+&gt;&gt;&gt; def g(self):
+... &quot;[chattymethod]&quot;
+&gt;&gt;&gt; C.g=decorated(g)
+&gt;&gt;&gt; c.g() # will print a message on file.log
+</pre>
+<p>This approach has the drawback that chattymethods created before changing
+the logfile will also print to the new logfile, if invoked after the
+change. Therefore</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; c.f()
+</pre>
+<p>will print a message to <tt class="literal"><span class="pre">file.log</span></tt> too, and not to standard output.
+Here is the confirmation:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; chattymethod.logfile.close()
+&gt;&gt;&gt; print file('file.log').read().rstrip()
+calling &lt;chattymethod:g&gt; from &lt;C instance&gt;
+calling &lt;chattymethod:f&gt; from &lt;C instance&gt;
+</pre>
+<p>A better solution is to pass
+parameters to method decorators as function attributes: then the function
+attributes can be converted to attributes of the decorator
+in the <tt class="literal"><span class="pre">__init__</span></tt> method. Here is an example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+class chattymethod2(chattymethod):
+ logfile=sys.stdout # default
+ def __init__(self,objfunc):
+ super(chattymethod2,self).__init__(objfunc)
+ logfile=getattr(self.__func__,'logfile',None)
+ if logfile: self.logfile=logfile
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p>Notice that the <tt class="literal"><span class="pre">__init__</span></tt> method has the signature
+<tt class="literal"><span class="pre">__init__(self,objfunc)</span></tt>, where the <tt class="literal"><span class="pre">objfunc</span></tt> object is a
+decorator object or the function to be converted in the decorator
+object, and that it is cooperative.
+This is the suggested way of overriding <tt class="literal"><span class="pre">__init__</span></tt>.</p>
+<p>Here is the testing:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;chatty2.py&gt;
+
+import customdec; customdec.enhance_classes()
+
+# sets the log files
+log1=file('file1.log','w')
+log2=file('file2.log','w')
+
+class C:
+ &quot;[Decorated]&quot;
+ def f(self):
+ &quot;[chattymethod2]&quot;
+ f.logfile=log1 # function attribute
+ def g(self):
+ &quot;[chattymethod2]&quot;
+ g.logfile=log2 # function attribute
+
+assert C.__dict__['f'].logfile is log1 # check the conversion
+assert C.__dict__['g'].logfile is log2 # function attr. -&gt; decorator attr.
+
+c=C() # C instantiation
+
+c.f() # print a message in file1.log
+c.g() # print a message in file2.log
+
+log1.close(); log2.close() # finally
+
+#&lt;/chatty2.py&gt;
+</pre>
+</blockquote>
+<p>Let me check the contents of the log files:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import chatty2
+&gt;&gt;&gt; print file('file1.log').read().rstrip()
+calling &lt;chattymethod2:f&gt; from &lt;C instance&gt;
+&gt;&gt;&gt; print file('file2.log').read().rstrip()
+calling &lt;chattymethod2:g&gt; from &lt;C instance&gt;
+</pre>
+<p><tt class="literal"><span class="pre">chattymethod</span></tt> is the poor man version of <tt class="literal"><span class="pre">tracedmethod</span></tt>, a
+sophisticated decorator for tracing methods.
+Here is the code, given for pedagogical purposes; the lazy reader can
+skip it and go directly to the usage section.</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+class tracedmethod(MethodDecorator):
+ &quot;Descriptor class, converts a method in a traced method&quot;
+ indent=0; output=sys.stdout # defaults
+
+ def __init__(self,objfunc):
+ super(tracedmethod,self).__init__(objfunc)
+ self.funcname=self.__func__.__name__
+ output=getattr(self.__func__,'output',None)
+ if output: self.output=output # func.attr. -&gt; dec.attr.
+
+ def get(self,obj,cls):
+ clsname=self.__klass__.__name__ # definition clas
+ def tracedmeth(obj,*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write(&quot;%sCalling '%s.%s' with arguments &quot; %
+ (i,clsname,self.funcname))
+ self.output.write(&quot;%s%s ...\n&quot; % (obj or '',str(args)+str(kw)))
+ res=super(tracedmethod,self).get(obj,cls)(*args,**kw)
+ self.output.write(&quot;%s'%s.%s' called with result: %s\n&quot;
+ % (i,clsname,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return tracedmeth.__get__(obj,cls) # method wrapper
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">tracedmethod.get</span></tt> returns a method wrapper object, so it is
+possible to use <tt class="literal"><span class="pre">im_func</span></tt> to retrieve the internal function
+<tt class="literal"><span class="pre">tracedmeth</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C:
+... &quot;[Decorated]&quot;
+... def f(self):
+... &quot;[tracedmethod]&quot;
+&gt;&gt;&gt; c=C(); c.f()
+Calling 'C.f' with arguments &lt;C instance&gt;(){} ...
+'C.f' called with result: None
+&gt;&gt;&gt; c.f.im_func.__name__
+'tracedmeth'
+</pre>
+<p>As soon as the <tt class="literal"><span class="pre">tracedmethod</span></tt> module is loaded, the <tt class="literal"><span class="pre">tracedmethod</span></tt> class
+is added to the list of know decorators, so one should use the
+&quot;[tracedmethod]&quot; docstring and not something like
+&quot;[customdec.tracedmethod]&quot;.</p>
+<p>Here is a less trivial example of usage, writing in a log file the
+internal working of a recursive function:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example9.py&gt;
+
+import customdec; customdec.enhance_classes()
+
+logfile=file('file3.log','w')
+
+class C(object):
+ &quot;[Decorated]&quot;
+ def fact(self,n):
+ &quot;[tracedmethod] The good old factorial.&quot;
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact.output=logfile
+
+C().fact(2) # write a message to logfile
+
+logfile.close()
+
+#&lt;/example9.py&gt;
+</pre>
+</blockquote>
+<p>Here is the content of <tt class="literal"><span class="pre">file3.log</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import example9 # creates file3.log
+&gt;&gt;&gt; print file('file3.log').read().rstrip()
+Calling 'C.fact' with arguments &lt;C instance&gt;(2,){} ...
+ Calling 'C.fact' with arguments &lt;C instance&gt;(1,){} ...
+ Calling 'C.fact' with arguments &lt;C instance&gt;(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+</pre>
+</div>
+<div class="section" id="defining-class-decorators">
+<h2><a class="toc-backref" href="#id10" name="defining-class-decorators">Defining class decorators</a></h2>
+<p>PEP 318 proposes to decorate methods by using descriptors; it is
+quite natural to extend this idea and to decorate classes by using
+class decorators implemented as metaclasses. We already saw a couple of
+class decorator at work, the metaclass <tt class="literal"><span class="pre">ClassDecorator</span></tt>, which gives
+to its instances the ability to interpret class level magic docstrings, and
+its subclass <tt class="literal"><span class="pre">Decorated</span></tt>, which converts functions in method decorators
+if suitable docstrings are found.</p>
+<p>To define a custom class decorator is easy: one defines a custom metaclass
+as usual, with the only difference of deriving from <tt class="literal"><span class="pre">ClassDecorator</span></tt> instead
+of deriving from <tt class="literal"><span class="pre">type</span></tt>.</p>
+<p>To understand how this works in practice, let me
+show how to add logging capabilities to a given class. The first
+step is to define a suitable class decorator, such as the following:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+class Logged(ClassDecorator):
+ output=sys.stdout
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print &gt;&gt; cls.output,&quot;%s created&quot; % cls
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">Logged</span></tt> is derived by the metaclass <tt class="literal"><span class="pre">ClassDecorator</span></tt>,
+which provides a certain amount of magic under the hood (in particular
+its printing representation and its calling syntax are redefined by its
+(meta-)metaclass <tt class="literal"><span class="pre">MetaDecorator</span></tt>).
+Logging capabilities can be added to a class
+by simply using the magic docstring syntax:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;logged.py&gt;
+
+import customdec; customdec.enhance_classes()
+
+class D(object): # will print a message at D creation
+ &quot;[Logged]&quot;
+
+#&lt;/logged.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; import logged
+&lt;class 'logged.D'&gt; created
+</pre>
+<p>Notice that the printing representation of <tt class="literal"><span class="pre">D</span></tt> involves the name
+of <tt class="literal"><span class="pre">D</span></tt> preceded by the name of its metaclass, which in this case
+is <tt class="literal"><span class="pre">Logged</span></tt></p>
+<p>Each time an instance of <tt class="literal"><span class="pre">Logged</span></tt> is created, a similar message is printed:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E(logged.D):
+... pass
+&lt;class 'E'&gt; created
+</pre>
+<p>Notice that <tt class="literal"><span class="pre">E</span></tt> does not have any magic docstring</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.__doc__ # no docstring
+</pre>
+<p>but still it inherits its magic from <tt class="literal"><span class="pre">D</span></tt>.</p>
+<p>Another simple example of class decorator is the following metaclass
+which modifies the docstrings of the methods of its instances,
+by magically inducing tracing capabilities on them:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+from types import FunctionType
+
+class Traced(Decorated):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType) and name!='__str__':
+ # cannot trace __str__, since it is invoked by
+ # tracedmethod and would generate infinite recursion
+ func.__doc__=&quot;[tracedmethod] &quot; + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d) # decorates the methods
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p>Here is an example of usage:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C(object):
+... &quot;&quot;&quot;[Traced] The class decorator adds the magic docstring
+... '[tracedmethod]' to f1 and f2, which are then converted
+... in method decorator objects.&quot;&quot;&quot;
+... def f1(self): pass
+... def f2(self): pass
+...
+&gt;&gt;&gt; type(C)
+&lt;class 'customdec.Traced'&gt;
+&gt;&gt;&gt; c=C()
+&gt;&gt;&gt; c.f1()
+Calling 'C.f1' with arguments &lt;C instance&gt;(){} ...
+'C.f1' called with result: None
+&gt;&gt;&gt; c.f2()
+Calling 'C.f2' with arguments &lt;C instance&gt;(){} ...
+'C.f2' called with result: None
+</pre>
+<p>By default, the decorators module only decorates classes with a magic
+docstring (and they subclasses, even without magic docstrings).
+If all the classes of your module have the same magic docstring,
+it makes sense to decorate them all
+with a single command. It is enough to use <tt class="literal"><span class="pre">decorators.enhance_classes()</span></tt>
+with a magic docstring corresponding to a class decorator as argument,
+as in this example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example7.py&gt;
+
+from example2 import identity,name
+import inspect, decorators; decorators.enhance_classes(&quot;[Decorated]&quot;)
+
+class C1(object): # automagically converted to a decorated class
+ identity=identity
+
+class C2: # automagically converted to a decorated class
+ name=name
+
+c1=C1() # C1 instance
+c2=C2() # C2 instance
+
+#&lt;/example7.py&gt;
+</pre>
+</blockquote>
+<p>The magic works both for new style classes such as <tt class="literal"><span class="pre">C1</span></tt></p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example7 import C1,c1
+&gt;&gt;&gt; assert C1.identity(1) == 1
+&gt;&gt;&gt; assert c1.identity(1) == 1
+</pre>
+<p>and old style classes such as <tt class="literal"><span class="pre">C2</span></tt> by implicitly converting them
+to new style classes:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example7 import C2,c2
+&gt;&gt;&gt; assert C2.name() == 'C2'
+&gt;&gt;&gt; assert c2.name() == 'C2'
+</pre>
+</div>
+<div class="section" id="composing-decorators">
+<h2><a class="toc-backref" href="#id11" name="composing-decorators">Composing decorators</a></h2>
+<p>Decorators can be composed by using magic docstrings with comma-separated
+decorator names. For instance, you can trace a classmethod:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example6.py&gt;
+
+&quot;How to trace a class method&quot;
+
+import customdec; customdec.enhance_classes()
+
+class C(object):
+ &quot;[Decorated]&quot;
+ def fact(cls,n): # a traced classmethod
+ &quot;[classmethod,tracedmethod]&quot;
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+#&lt;/example6.py&gt;
+</pre>
+</blockquote>
+<p>Here is the testing:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example6 import C
+&gt;&gt;&gt; C.fact(2)
+Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(2,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(1,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+</pre>
+<p>You may easily check that calling <tt class="literal"><span class="pre">C().fact</span></tt> will work too.</p>
+<p>Under the hood the syntax</p>
+<blockquote>
+<pre class="literal-block">
+[classmethod,tracedmethod]
+</pre>
+</blockquote>
+<p>generates a <tt class="literal"><span class="pre">classmethodtracedmethod</span></tt> class obtained via
+multiple inheritance:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; type(C.__dict__['fact'])
+&lt;class 'safetype.classmethodtracedmethod'&gt;
+</pre>
+<p>Notice that the order <em>does</em> matter and using the docstring
+&quot;[tracedmethod,classmethod]&quot; will not work:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D:
+... &quot;[Decorated]&quot;
+... def f(cls):
+... &quot;[tracedmethod,classmethod]&quot;
+&gt;&gt;&gt; D.f()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with D instance as first argument (got nothing instead)
+</pre>
+<p>The problem here is that <tt class="literal"><span class="pre">tracedmethod.get</span></tt> returns a method-wrapper object
+which expects a D instance as first argument whereas it gets <tt class="literal"><span class="pre">None</span></tt> since
+it is called from the class. On the other hand,</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; D().f()
+Calling 'D.f' with arguments &lt;D instance&gt;(){} ...
+'D.f' called with result: None
+</pre>
+<p>will work. When <tt class="literal"><span class="pre">classmethod</span></tt> precedes <tt class="literal"><span class="pre">tracedmethod</span></tt>, then
+<tt class="literal"><span class="pre">classmethod</span></tt> passes to <tt class="literal"><span class="pre">tracedmeth</span></tt> a non-empty first argument,
+i.e. the calling class, even when called from the instance:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C().fact(2)
+Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(2,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(1,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+</pre>
+<p>If we try to trace a staticmethod, we will get a different error with
+the order &quot;tracedmethod, staticmethod&quot;:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class F(object):
+... &quot;[Decorated]&quot;
+... def fact(n):
+... &quot;[tracedmethod,staticmethod]&quot;
+... if n==0: return 1
+... else: return n*F.fact(n-1)
+&gt;&gt;&gt; F.fact(2)
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with F instance as first argument (got int instance instead)
+</pre>
+<p>The message is self-explanatory.</p>
+<p>On the other hand, composing the decorators in the order
+&quot;[tracedmethod,staticmethod]&quot; will work just fine.</p>
+<p>It is possible to compose class decorators just as method decorators,
+by using the docstring syntax: for instance we may create a class
+which is both <tt class="literal"><span class="pre">Decorated</span></tt> and <tt class="literal"><span class="pre">Logged</span></tt> and by trivially writing</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C:
+... &quot;[Decorated,Logged]&quot;
+... def f():
+... &quot;[staticmethod]&quot;
+... return 'it works!'
+&lt;class C[DecoratedLogged]&gt; created
+&gt;&gt;&gt; C().f()
+'it works!'
+</pre>
+</div>
+<div class="section" id="diving-into-magic">
+<h2><a class="toc-backref" href="#id12" name="diving-into-magic">Diving into magic</a></h2>
+<p>If you never use metaclasses, this part can be safely skipped. On the
+other hand, if you are a metaclass user, you <em>must</em> read this section
+in order to keep your code working.</p>
+<p>The <tt class="literal"><span class="pre">decorators</span></tt> module provide a <tt class="literal"><span class="pre">ClassDecorator</span></tt> metaclass which
+converts a regular (both old style or new style) class in a class with
+the ability to recognize magic docstrings. Under the hood, the
+<tt class="literal"><span class="pre">decorators.enhance_classes()</span></tt> trick works by decorating the
+<tt class="literal"><span class="pre">object</span></tt> class with <tt class="literal"><span class="pre">decorators.ClassDecorator</span></tt> and by setting
+the custom metaclass to <tt class="literal"><span class="pre">decorators.ClassDecorator</span></tt> and it is
+equivalent to</p>
+<blockquote>
+<pre class="literal-block">
+import decorators
+object=decorators.ClassDecorator(object) # decorates new style classes
+__metaclass__= decorators.ClassDecorator # decorates old style classes
+</pre>
+</blockquote>
+<p>If you want the magic to work only for new style classes only, you may
+forget the second line; if you want the magic to work for old style
+classes only, you may forget the first line.</p>
+<p>The <tt class="literal"><span class="pre">decorators.enhance_classes(&quot;[SomeClassDec]&quot;)</span></tt> syntax looks at the
+magic docstring and executes something like</p>
+<blockquote>
+<pre class="literal-block">
+import decorators
+object=decorators.SomeClassDec(object) # decorates all new style classes
+__metaclass__= decorators.SomeClassDec # decorates all old style classes
+</pre>
+</blockquote>
+<p>The problem with the <tt class="literal"><span class="pre">enhance_classes()</span></tt> syntaxes is that it is
+not 100% safe under metaclass conflicts. In order to explain the issue,
+let me give an example.</p>
+<p>Suppose we enhance the <tt class="literal"><span class="pre">object</span></tt> class in the interpreter namespace:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import decorators; decorators.enhance_classes()
+</pre>
+<p>making it an instance of <tt class="literal"><span class="pre">ClassDecorator</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; object.__class__
+&lt;class 'decorators.ClassDecorator'&gt;
+</pre>
+<p>Now, if we naively create a custom metaclass <tt class="literal"><span class="pre">M</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class M(type):
+... &quot;Some non-trivial code here...&quot;
+</pre>
+<p>and we try to use it to enhance a new style class <tt class="literal"><span class="pre">NwithM</span></tt>, we will get a
+conflict:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class NwithM(object): __metaclass__=M # does not work!
+...
+Traceback (most recent call last):
+ ...
+TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+</pre>
+<p>The problem is that the previous line tries to create a class <tt class="literal"><span class="pre">NwithM</span></tt>
+which should have both metaclasses <tt class="literal"><span class="pre">ClassDecorator</span></tt> and <tt class="literal"><span class="pre">M</span></tt>:
+a conflict follows.</p>
+<p>Fortunately, the decorators module imports the <tt class="literal"><span class="pre">type</span></tt> metaclass from
+my <tt class="literal"><span class="pre">safetype</span></tt> module just to avoid this kind of problems. If we
+derive <tt class="literal"><span class="pre">M</span></tt> from <tt class="literal"><span class="pre">decorators.type</span></tt> (which is really <tt class="literal"><span class="pre">safetype.type</span></tt>)
+the conflict is automagically avoided:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class M(decorators.type):
+... &quot;This metaclass is conflict-proof&quot;
+&gt;&gt;&gt; class NwithM(object): # it works!
+... __metaclass__=M
+</pre>
+<p>The reason why the conflict is avoided is that the <tt class="literal"><span class="pre">safetype</span></tt> module
+(which makes use of really <em>deep</em> metaclass magic) automatically
+creates the composed class <tt class="literal"><span class="pre">MClassDecorator</span></tt> by multiply inheriting
+from <tt class="literal"><span class="pre">M</span></tt> and from <tt class="literal"><span class="pre">ClassDecorator</span></tt>. Then, <tt class="literal"><span class="pre">NwithM</span></tt> can be safely
+created as an instance of <tt class="literal"><span class="pre">safetype.MClassDecorator</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; type(NwithM)
+&lt;class 'safetype.MClassDecorator'&gt;
+</pre>
+<p>The situation with old style classes is worse since
+apparently</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class OwithM: # old style class with metaclass M
+... __metaclass__=M
+... def sm():
+... &quot;[staticmethod]&quot;
+</pre>
+<p>gives no error, but actually <tt class="literal"><span class="pre">M</span></tt> overrides
+<tt class="literal"><span class="pre">ClassDecorator</span></tt>, so <tt class="literal"><span class="pre">OwithM</span></tt> will not recognize magic docstrings:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; type(OwithM)
+&lt;class 'M'&gt;
+&gt;&gt;&gt; OwithM.sm()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with OwithM instance as first argument (got nothing instead)
+</pre>
+<p>The simpler solution is to convert <tt class="literal"><span class="pre">OwithM</span></tt> in a new style class:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class NwithM(OwithM,object):
+... __metaclass__=M
+... def sm():
+... &quot;[staticmethod]&quot;
+&gt;&gt;&gt; type(NwithM)
+&lt;class 'safetype.MClassDecorator'&gt;
+</pre>
+<p>Now <tt class="literal"><span class="pre">NwithM</span></tt> is not decorated since it does miss a magic docstring, but
+it provides the ability to recognizing magic docstrings, so <tt class="literal"><span class="pre">NwithM</span></tt>
+subclasses with a &quot;[Decorated]&quot; docstring will be decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E(NwithM):
+... &quot;[Decorated]&quot;
+... def cm(cls):
+... &quot;[classmethod]&quot;
+... print '.cm() called from',cls
+</pre>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.cm() # it works
+.cm() called from &lt;class E[MClassDecoratorDecorated]&gt;
+</pre>
+<p>Notice that <tt class="literal"><span class="pre">sm</span></tt> was defined in <tt class="literal"><span class="pre">NwithM</span></tt>, the undecorated class: therefore
+it is not decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.sm() # correctly, does not work
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with E instance as first argument (got nothing instead)
+</pre>
+<p>The error message says that <tt class="literal"><span class="pre">sm</span></tt> is an unbound method and not a
+static method.</p>
+<p>It is possible to go even deeper in <strong>black</strong> magic, and to decorate all
+the new style classes in <em>all</em> modules, by decorating the
+<tt class="literal"><span class="pre">__builtin__.object</span></tt>. Still, naively redefining the <tt class="literal"><span class="pre">__builtin__object</span></tt>
+class is risky, since it will induce metaclass conflicts in other modules
+using metaclasses. In other words, it will work only if you import modules
+not using metaclasses, or modules using metaclasses safely, i.e. modules
+taking care of possible conflicts by using <tt class="literal"><span class="pre">safetype.type</span></tt> as base metaclass.
+If you really enjoy black magic, you may solve the problem by
+redefining the <tt class="literal"><span class="pre">__builtin__.type</span></tt> as <tt class="literal"><span class="pre">safetype.type</span></tt>.
+The <tt class="literal"><span class="pre">decorators</span></tt> module does not go so deep in dark magic, but still
+there are cases where you may want to do it. In these cases you must be
+explicit and redefine the builtins by hand, without help from the
+module. For instance, one of my original motivation for the usage
+of metaclasses/class decorators was to use them for debugging purposes.
+For instance, I wanted to trace the execution of methods in
+complicate inheritance hierarchies, <em>without changing the source code</em>.
+For simple situations, i.e. in absence of inheritance and of pre-existing
+metaclasses, the function <tt class="literal"><span class="pre">import_with_metaclass</span></tt> discussed in the
+<a class="reference" href="http://www-106.ibm.com/developerworks/library/l-pymeta.html">first paper on metaclasses</a> written in collaboration with David Mertz, works
+fine but in general the implementation of a working <tt class="literal"><span class="pre">import_with_metaclass</span></tt>
+is cumbersome. For debugging purposes, the quick and dirty way can be a
+good enough way, so let me show how we can redefine the builtins <tt class="literal"><span class="pre">object</span></tt> and
+<tt class="literal"><span class="pre">type</span></tt> <em>before</em> importing the module, in such a way to enhance <em>all</em>
+its classes with tracing capabilities.</p>
+<p>Let me start from a module using an unsafe metaclass <tt class="literal"><span class="pre">M</span></tt>, such that it
+cannot be traced trivially by decorating its classes <em>after</em> the import;
+moreover there is an inheritance hierarchy, such that it cannot be
+traced correctly by naively decorating all the classes one after the
+other (unless one modifies the original source code, but this forbidden
+by the rules of the game ;)</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;tracing.py&gt;
+
+&quot;&quot;&quot;
+This is a pre-existing module not using decorators but using multiple
+inheritance and unsafe metaclasses. We want to trace it for debugging
+purposes.
+&quot;&quot;&quot;
+
+class M(type):
+ &quot;There should be some non-trivial code here&quot;
+
+class B(object):
+ def __init__(self):
+ super(B,self).__init__()
+
+class D(object):
+ __metaclass__=M
+ def __init__(self):
+ super(D,self).__init__()
+
+class E(B,D):
+ def __init__(self):
+ super(E,self).__init__()
+
+ #&lt;/tracing.py&gt;
+</pre>
+</blockquote>
+<p>Everything works is we modify the builtins before importing the module:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import __builtin__
+&gt;&gt;&gt; __object__=__builtin__.object # the original 'object' class
+&gt;&gt;&gt; __builtin__.object=customdec.Traced('tracedobject',(),{})
+&gt;&gt;&gt; __builtin__.type=customdec.type # a safe 'type' class
+</pre>
+<p>Now, when we import the module, all the classes <tt class="literal"><span class="pre">M</span></tt>, <tt class="literal"><span class="pre">B</span></tt>, <tt class="literal"><span class="pre">D</span></tt> and <tt class="literal"><span class="pre">E</span></tt>
+will be created starting for the tricked builtins, so they will be traced
+and safe under conflicts. For instance, let me show that <tt class="literal"><span class="pre">E</span></tt> is created
+with a conflict safe <tt class="literal"><span class="pre">MTraced</span></tt> metaclass:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from tracing import E
+&gt;&gt;&gt; print E
+&lt;class E[MTraced]&gt;
+</pre>
+<p>This shows that the <tt class="literal"><span class="pre">__init__</span></tt> methods are traced indeed and shows the
+Method Resolution Order:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; e=E()
+Calling 'E.__init__' with arguments &lt;E instance&gt;(){} ...
+ Calling 'B.__init__' with arguments &lt;E instance&gt;(){} ...
+ Calling 'D.__init__' with arguments &lt;E instance&gt;(){} ...
+ 'D.__init__' called with result: None
+ 'B.__init__' called with result: None
+'E.__init__' called with result: None
+</pre>
+<p>This works, indeed. At the end, one should not forget to restore
+the standard builtins, otherwise it will trace <em>all</em> the classes
+created thereafter.</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; __builtin__.object=__object__ # restore the __builtin__
+&gt;&gt;&gt; __builtin__.type=decorators.__type__ # restore the __builtin__
+</pre>
+<p>At the end, I will notice that it is possible to solve the problem more
+nicely, without redefining the builtins, but I will discuss the solution
+elsewhere ;)</p>
+</div>
+<div class="section" id="advanced-usage">
+<h2><a class="toc-backref" href="#id13" name="advanced-usage">Advanced usage</a></h2>
+<p>Whereas the average programmer is expected to use the <tt class="literal"><span class="pre">decorated()</span></tt>
+and <tt class="literal"><span class="pre">enhance_classes()</span></tt> functions only, the <tt class="literal"><span class="pre">decorators</span></tt> module provides
+facilities which may be useful to the advanced programmer.</p>
+<p>The simplest is an utility function which retrieves the list of
+recognized decorators, <tt class="literal"><span class="pre">decorators.getdec()</span></tt>. The precise syntax is
+<tt class="literal"><span class="pre">decorators.getdec(docstring)</span></tt>, where <tt class="literal"><span class="pre">docstring</span></tt>
+is a magic docstring, i.e. a bracketed comma-separated list
+of decorator names. For instance <tt class="literal"><span class="pre">decorators.getdec('[MethodDecorator]')</span></tt>
+gives the list of all subclasses of <tt class="literal"><span class="pre">MethodDecorator</span></tt>, i.e. all method
+decorators, whereas <tt class="literal"><span class="pre">decorators.getdec('[ClassDecorator]')</span></tt>
+gives the list of the known class decorators. The utility of the function
+is that it also returns decorators that have been automagically created:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; decorators.getdec(&quot;[classmethodtracedmethod]&quot;)
+[&lt;class 'safetype.classmethodtracedmethod'&gt;]
+</pre>
+<p>It is even possible to use the comma notation:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; decorators.getdec(&quot;[classmethod,tracedmethod]&quot;)
+[&lt;class 'safetype.classmethodtracedmethod'&gt;]
+</pre>
+<p>If you mispell a decorator name you get an helpful error message:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E:
+... &quot;[Decorated]&quot;
+... def f():
+... &quot;[staticmeth]&quot;
+Traceback (most recent call last):
+ .. a cryptic traceback here ..
+UnknownDecoratorError: staticmeth
+</pre>
+<p>By design, the <tt class="literal"><span class="pre">decorated</span></tt> function is quite limited, and does not
+decorate functions without magic docstrings. This is safe and also convenient
+for internal usage of the <tt class="literal"><span class="pre">decorated</span></tt> function in the <tt class="literal"><span class="pre">Decorated</span></tt>
+metaclass. Nevertheless, advanced users may want to have the ability
+of decorating functions by hand, without invoking <cite>decorators.decorated()`</cite>
+and magic docstrings. This is possible, by calling the decorator directly.
+For instance, here is how to convert a lambda function in a staticmethod:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; do_nothing=decorators.staticmethod(lambda:None)
+&gt;&gt;&gt; print do_nothing # ``do_nothing`` is a static method
+&lt;staticmethod:&lt;lambda&gt;&gt;
+</pre>
+<p>The most convenient usage of this feature is in the composition of decorators.
+For instance, we may compose the just defined <tt class="literal"><span class="pre">staticmethod</span></tt> with a
+<tt class="literal"><span class="pre">chattymethod2</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; chattystatic=customdec.chattymethod2(do_nothing)
+&gt;&gt;&gt; print chattystatic
+&lt;chattymethod2staticmethod:&lt;lambda&gt;&gt;
+</pre>
+<p>The syntax</p>
+<blockquote>
+<tt class="literal"><span class="pre">decorator1(decorator2(obj))</span></tt></blockquote>
+<p>automagically creates a composed class <tt class="literal"><span class="pre">decorator1decorator2</span></tt> in the
+<tt class="literal"><span class="pre">safetype</span></tt> module (or recycle it, if <tt class="literal"><span class="pre">decorator1decorator2</span></tt> has
+been already created) and it is equivalent to</p>
+<blockquote>
+<tt class="literal"><span class="pre">decorator1decorator2(obj)</span></tt></blockquote>
+<p>Here is the check that everything works:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class B:
+... chattystatic=chattystatic
+&gt;&gt;&gt; B.chattystatic()
+calling &lt;chattymethod2staticmethod:&lt;lambda&gt;&gt; from &lt;class 'B'&gt;
+</pre>
+<p>Notice that <tt class="literal"><span class="pre">chattystatic</span></tt> does not know the class where it
+is defined:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; chattystatic.__klass__
+&lt;class 'safetype.?'&gt;
+</pre>
+<p>unless the <tt class="literal"><span class="pre">__klass__</span></tt> attribute is explicitly set.</p>
+<p>This is the hierarchy:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; for C in type(chattystatic).mro(): print C
+...
+&lt;class 'safetype.chattymethod2staticmethod'&gt;
+&lt;class 'customdec.chattymethod2'&gt;
+&lt;class 'customdec.chattymethod'&gt;
+&lt;class 'decorators.staticmethod'&gt;
+&lt;class 'decorators.MethodDecorator'&gt;
+&lt;class 'decorators.Decorator'&gt;
+&lt;type 'object'&gt;
+</pre>
+<p>One can also compose classes by hand, by using class decorators:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C:
+... &quot;[Logged]&quot;
+... def f(): &quot;[staticmethod]&quot;
+...
+&lt;class 'C'&gt; created
+&gt;&gt;&gt; C=customdec.Traced(C)
+&lt;class C[TracedLogged]&gt; created
+</pre>
+<p>The <tt class="literal"><span class="pre">decorators.enhance_classes(&lt;classdecorator&gt;)</span></tt> syntax performs
+the composition automagically:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example8.py&gt;
+
+from example2 import identity,name
+import inspect, decorators; decorators.enhance_classes(&quot;[Decorated]&quot;)
+
+class C1: # automagically converted to a Decorated class
+ identity=identity
+
+class C2: # automagically converted to a DecoratedLogged class
+ &quot;[Logged]&quot;
+ name=name
+
+c1=C1() # C1 instance
+c2=C2() # C2 instance
+
+#&lt;/example8.py&gt;
+</pre>
+</blockquote>
+<p>In this example the class <tt class="literal"><span class="pre">C2</span></tt> has already a magic docstring. This means that
+<tt class="literal"><span class="pre">C2</span></tt> has to be enhanced both from <tt class="literal"><span class="pre">Logged</span></tt> and from <tt class="literal"><span class="pre">Decorated</span></tt>.
+This is done by automagically creating a <tt class="literal"><span class="pre">DecoratedLogged</span></tt> class
+decorator:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example8 import C1,C2,c1,c2
+&lt;class C2[DecoratedLogged]&gt; created
+</pre>
+<p>The second line is printed because of the logging capabilities of <tt class="literal"><span class="pre">C2</span></tt>.
+Moreover, since <tt class="literal"><span class="pre">C2</span></tt> is decorated too, the following will work:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert C2.name() == 'C2'
+&gt;&gt;&gt; assert c2.name() == 'C2'
+</pre>
+<p>Idem for <tt class="literal"><span class="pre">C1</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert C1.identity(1) == 1
+&gt;&gt;&gt; assert c1.identity(1) == 1
+</pre>
+</div>
+</div>
+<div class="section" id="the-implementation">
+<h1><a class="toc-backref" href="#id14" name="the-implementation">The implementation</a></h1>
+<p>This part can be safely skipped, unless you are a <em>really</em> curious and
+you want to know how the implementation works.</p>
+<p>The module is rather short (less than 150 lines if you skip comments and
+docstrings) but far from being trivial, since it is based on extensive
+usage of metaclass wizardry. Moreover,
+it invokes the <tt class="literal"><span class="pre">safetype</span></tt> module to solve metaclass conflicts, and
+<tt class="literal"><span class="pre">safetype</span></tt> contains 50 lines of <em>really</em> deep metaclass wizardry.</p>
+<blockquote>
+<div class="figure">
+<p><img alt="decorators.png" src="decorators.png" /></p>
+</div>
+</blockquote>
+<p>The main class-metaclass hierarchy is represented in the figure, where
+boxes denote classes and ovals denote metaclasses; instantiation is
+denoted by dashed green lines whereas inheritance is denoted by continuous
+blue lines.</p>
+<p>For instance, this is the Method Resolution Order for the <tt class="literal"><span class="pre">Decorated</span></tt>
+metaclass:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; for i,c in enumerate(decorators.Decorated.__mro__):
+... print i,c,&quot;[%s]&quot; % type(c).__name__
+0 &lt;class 'decorators.Decorated'&gt; [MetaDecorator]
+1 &lt;class 'decorators.ClassDecorator'&gt; [MetaDecorator]
+2 &lt;class 'safetype.safetype'&gt; [type]
+3 &lt;type 'type'&gt; [type]
+4 &lt;class 'decorators.Decorator'&gt; [MetaDecorator]
+5 &lt;type 'object'&gt; [type]
+</pre>
+<p><tt class="literal"><span class="pre">Decorator</span></tt> is the mother of all decorators. Its main purpose it to
+provide the <tt class="literal"><span class="pre">MetaDecorator</span></tt>
+metaclass to all decorators.</p>
+<p>The <tt class="literal"><span class="pre">safetype</span></tt> metaclass, imported from the <tt class="literal"><span class="pre">safetype</span></tt> module,
+ensures that class decorators can generate classes without incurring
+in conflicts.</p>
+<p>Since class decorators are metaclasses,
+<tt class="literal"><span class="pre">MetaDecorator</span></tt> is actually a meta-metaclass with respect to
+instances of decorated classes. For this reason if</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C=decorators.ClassDecorator('C',(),{})
+</pre>
+<p>then</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.__class__
+&lt;class 'decorators.ClassDecorator'&gt;
+</pre>
+<p>but</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.__metaclass__
+&lt;class 'decorators.MetaDecorator'&gt;
+</pre>
+<p>since the <tt class="literal"><span class="pre">C.__metaclass__</span></tt> attribute is inherited from <tt class="literal"><span class="pre">Decorator</span></tt>.</p>
+<p>On the other hand, <tt class="literal"><span class="pre">MetaDecorator</span></tt> is a simple metaclass with
+respect to instances of decorated methods.</p>
+<p>The implementation is relatively smart. Consider for instance the case of
+the <tt class="literal"><span class="pre">logged</span></tt> example. In that example class <tt class="literal"><span class="pre">D</span></tt> was a subclass
+of a tricked <tt class="literal"><span class="pre">object</span></tt> class, enhanced by <tt class="literal"><span class="pre">ClassDecorator</span></tt>. Moreover <tt class="literal"><span class="pre">D</span></tt>
+had a <tt class="literal"><span class="pre">Logged</span></tt> docstring. Therefore it should have been an instance of a
+<tt class="literal"><span class="pre">ClassDecoratorLogged</span></tt> metaclass. But logged was
+a subclass of <tt class="literal"><span class="pre">ClassDecorator</span></tt>, therefore it already had all the features
+of <tt class="literal"><span class="pre">ClassDecorator</span></tt> and it would have been redundant to create
+<tt class="literal"><span class="pre">ClassDecoratorLogged</span></tt>, when``Logged`` would have been enough.
+So <tt class="literal"><span class="pre">Logged</span></tt> was used and <tt class="literal"><span class="pre">ClassDecoratorLogged</span></tt> was never created.
+All this magic is in the <tt class="literal"><span class="pre">safetype.remove_redundant(*classes)</span></tt> function.</p>
+<p>The current implementation does not make any attempt of optimization and
+there may be alternative implementations faster or more memory efficient.
+At this experimental level I didn't care to explore about performances
+issues. Probably, they do not matter unless one has to decorate
+thousands or millions of functions and classes.</p>
+<p>Finally, a word about bugs. The <tt class="literal"><span class="pre">decorators</span></tt> module is fairly sophisticated,
+therefore whereas I can guarantee that it passes my test suite (which involves
+~200 tests, most of them extracted from the documentation you are reading),
+I cannot guarantee that it is correct. If somebody finds a bug or an
+unexpected behavior, please let me know and I will fix it or document it.</p>
+<!-- References: -->
+<div class="section" id="module-decorators">
+<h2><a class="toc-backref" href="#id15" name="module-decorators">Module <tt class="literal"><span class="pre">decorators</span></tt></a></h2>
+<p>A module to implement pep318 (decorator syntax) via magic doctrings.
+For the full documentation see
+<a class="reference" href="http://www.phyast.pitt.edu/~micheles/python/decorators.html">http://www.phyast.pitt.edu/~micheles/python/decorators.html</a> .</p>
+<div class="section" id="id3">
+<h3><a class="toc-backref" href="#id16" name="id3">Metaclasses</a></h3>
+<p><tt class="literal"><span class="pre">metaclass</span> <span class="pre">ClassDecorator(type,Decorator):</span></tt></p>
+<blockquote>
+Metaclass callable with one or three arguments, having its calling
+syntax redefined by <tt class="literal"><span class="pre">MetaDecorator</span></tt>.</blockquote>
+<p><tt class="literal"><span class="pre">metaclass</span> <span class="pre">Decorated(ClassDecorator):</span></tt></p>
+<blockquote>
+<p>Metaclass which decorates the methods of its instances according
+to the docstrings. It redefines <tt class="literal"><span class="pre">__str__</span></tt> on
+its instances and the default <tt class="literal"><span class="pre">__str__</span></tt> on the instances of its
+instances.</p>
+<p><tt class="literal"><span class="pre">__str__(cls):</span></tt></p>
+<blockquote>
+Redefine the printing representation of classes</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">metaclass</span> <span class="pre">safetype(type):</span></tt></p>
+<blockquote>
+Overrides the <tt class="literal"><span class="pre">__new__</span></tt> method of the <tt class="literal"><span class="pre">type</span></tt> metaclass, making the
+generation of classes conflict-proof.</blockquote>
+<p><tt class="literal"><span class="pre">metaclass</span> <span class="pre">MetaDecorator(type):</span></tt></p>
+<blockquote>
+<p>Metaclass inducing a certain amount of magic on decorators:</p>
+<ol class="arabic simple">
+<li>Each time a decorator is defined in any module, it is stored in
+MetaDecorator.dic and MetaDecorator.ls.</li>
+<li>If the (method) decorator has a 'get' method, a '__get__' method
+is automagically created as an alias to 'get'.</li>
+<li>Decorators calls are dispatched to the decorator _call_
+classmethod.</li>
+</ol>
+<p><tt class="literal"><span class="pre">__call__(dec,*args):</span></tt></p>
+<blockquote>
+This is the heart of the module. Infers the correct decorator class
+from <tt class="literal"><span class="pre">dec</span></tt> and the docstring and creates the correct decorator object.
+Returns the original object if <tt class="literal"><span class="pre">dec</span></tt> is the trivial <tt class="literal"><span class="pre">Decorator</span></tt>
+class and no docstring is found.</blockquote>
+<p><tt class="literal"><span class="pre">__init__(dec,*args):</span></tt></p>
+<blockquote>
+Update the metaclass attributes <tt class="literal"><span class="pre">dic</span></tt> and <tt class="literal"><span class="pre">ls</span></tt>;
+alias <tt class="literal"><span class="pre">get</span></tt> to <tt class="literal"><span class="pre">__get__</span></tt>.</blockquote>
+</blockquote>
+</div>
+<div class="section" id="classes">
+<h3><a class="toc-backref" href="#id17" name="classes">Classes</a></h3>
+<p><tt class="literal"><span class="pre">class</span> <span class="pre">UnknownDecoratorError(Exception):</span></tt></p>
+<blockquote>
+The name says it all.</blockquote>
+<p><tt class="literal"><span class="pre">class</span> <span class="pre">Decorator(object):</span></tt></p>
+<blockquote>
+Instance of MetaDecorator and mothers of all decorators. When called
+in the form <tt class="literal"><span class="pre">Decorator(obj)</span></tt> with obj having a magic docstring, it returns
+a decorated object; otherwise it returns the original object.</blockquote>
+<p><tt class="literal"><span class="pre">class</span> <span class="pre">staticmethod(MethodDecorator):</span></tt></p>
+<blockquote>
+Decorator, converts a function in a staticmethod</blockquote>
+<p><tt class="literal"><span class="pre">class</span> <span class="pre">MethodDecorator(Decorator):</span></tt></p>
+<blockquote>
+<p>Descriptor class callable with a function or a descriptor object
+as argument. It defines a default printing representation on method
+decorators objects and a default <tt class="literal"><span class="pre">get</span></tt> method. All the rest is
+provided by the metaclass <tt class="literal"><span class="pre">MetaDecorator</span></tt>.</p>
+<p><tt class="literal"><span class="pre">get(self,obj,cls=None):</span></tt></p>
+<blockquote>
+aliased to __get__ by the metaclass, to be overridden</blockquote>
+<p><tt class="literal"><span class="pre">__str__(self):</span></tt></p>
+<blockquote>
+Printing representation of kind &lt;decoratorclass:functionname&gt;</blockquote>
+<p><tt class="literal"><span class="pre">__init__(self,objfunc):</span></tt></p>
+<blockquote>
+objfunc is a decorator object or a function</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">class</span> <span class="pre">classmethod(MethodDecorator):</span></tt></p>
+<blockquote>
+Decorator, converts a function in a classmethod</blockquote>
+</div>
+<div class="section" id="functions">
+<h3><a class="toc-backref" href="#id18" name="functions">Functions</a></h3>
+<p><tt class="literal"><span class="pre">enhance_classes(magicstring='[ClassDecorator]'):</span></tt></p>
+<blockquote>
+Enhances all the classes in the caller module with a metaclass
+built from the given magicstring.</blockquote>
+<p><tt class="literal"><span class="pre">remove_redundant(bases):</span></tt></p>
+<blockquote>
+<p>Returns a tuple of non-redundant base classes.
+Given a sequence of base classes, a class is redundant if it is duplicated
+or if it is implied by the others, i.e. it is an ancestor of at least one
+of the other classes. For instance, if <tt class="literal"><span class="pre">C</span></tt> is derived from <tt class="literal"><span class="pre">B</span></tt>, in the
+sequence <tt class="literal"><span class="pre">C,B</span></tt> the class <tt class="literal"><span class="pre">B</span></tt> is redundant, since all its features are
+already provided by <tt class="literal"><span class="pre">C</span></tt>. Therefore <tt class="literal"><span class="pre">B</span></tt>
+is removed and <tt class="literal"><span class="pre">remove_redundant</span></tt> returns the tuple <tt class="literal"><span class="pre">(C,)</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class B(object): pass
+...
+&gt;&gt;&gt; class C(B): pass
+...
+&gt;&gt;&gt; import safetype; safetype.remove_redundant([C,B])
+(&lt;class 'C'&gt;,)
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">compose(dclasses,*defaultclasses):</span></tt></p>
+<blockquote>
+Retrieves or creates a decorator for a tuple of decorators. If
+defaults decorators are given, they get the precedence. It removes
+redundant classes.</blockquote>
+<p><tt class="literal"><span class="pre">instance_str(self):</span></tt></p>
+<blockquote>
+Redefines the printing representation of simple objects</blockquote>
+<p><tt class="literal"><span class="pre">getdec(magicstring=&quot;[Decorator]&quot;):</span></tt></p>
+<blockquote>
+Given a magicstring describing a valid decorator name, returns the list
+of its subclasses. By default returns the full list of decorators.</blockquote>
+<p><tt class="literal"><span class="pre">decorate(objdict):</span></tt></p>
+<blockquote>
+Takes an object with a dictionary and decorates all its functions
+and classes according to their docstrings.</blockquote>
+<p><tt class="literal"><span class="pre">decorators_in(docstring):</span></tt></p>
+<blockquote>
+Takes a docstring and returns a (possibly empty) tuple of decorator
+classes.</blockquote>
+</div>
+</div>
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="decorators.txt">View document source</a>.
+Generated on: 2003-09-30 10:07 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/pypers/pep318/decorators.py b/pypers/pep318/decorators.py
new file mode 100755
index 0000000..738b403
--- /dev/null
+++ b/pypers/pep318/decorators.py
@@ -0,0 +1,184 @@
+# decorators.py
+
+"""
+A module to implement pep318 (decorator syntax) via magic doctrings.
+For the full documentation see
+http://www.phyast.pitt.edu/~micheles/python/decorators.html .
+"""
+
+import sys, re, inspect
+from types import FunctionType,ClassType
+from safetype import remove_redundant,__type__,safetype as type
+
+#from printerr import printerr
+
+############################ UTILITIES ##############################
+
+MAGICDOC=re.compile(r'\s*\[([\w_\s,]*)\]')
+#regexp to recognize magic docstrings
+
+class UnknownDecoratorError(Exception):
+ "The name says it all."
+
+class MetaDecorator(type):
+ """Metaclass inducing a certain amount of magic on decorators:
+
+ 1. each time a decorator class is defined in any module, it is stored in
+ MetaDecorator.dic and MetaDecorator.ls;
+ 2. if the decorator class has a 'get' method, a '__get__' method
+ is automagically created as an alias to 'get';
+ 3. decorators calls are dispatched to the decorator _call_
+ classmethod.
+ The net effect is that the call decoratorclass(...) returns an
+ instance of a *subclass* of decoratorclass.
+ """
+
+ dic,ls={},[]
+
+ def __init__(dec,*args):
+ super(MetaDecorator,dec).__init__(*args)
+ MetaDecorator.dic[dec.__name__]=dec
+ MetaDecorator.ls.append(dec)
+ get=dec.__dict__.get('get') # look at get
+ if get: dec.__get__=get # alias __get__ to get
+
+ def __call__(dec,*args):
+ """This is the heart of the module. Infers the correct decorator class
+ from ``dec`` and the docstring and creates the correct decorator
+ object. Returns the original object if ``dec`` is the trivial
+ ``Decorator`` class and no docstring is found."""
+ nargs=len(args)
+ if nargs==1: # simple call of kind dec(obj)
+ obj=args[0]
+ if not isinstance( # not method decorator, function or class
+ obj,(MethodDecorator,FunctionType,ClassType,__type__)):
+ return # do nothing
+ elif isinstance(obj,decorator): # compose with obj.__class__ too
+ dec=compose(decorators_in(obj.__doc__), dec, obj.__class__)
+ else: # compose with dec only
+ dec=compose(decorators_in(obj.__doc__), dec)
+ elif nargs==3: # class decorator called with three arguments
+ dec=compose(decorators_in(args[2].get('__doc__')),dec)
+ return dec._call_(*args) # dispatch to the correct _call_ classmethod
+
+def compose(dclasses,*defaultclasses):
+ """Retrieves or creates a decorator for a tuple of decorators. If
+ defaults decorators are given, they get the precedence. It removes
+ redundant classes."""
+ dclasses=remove_redundant(defaultclasses+dclasses)
+ decname=''.join([d.__name__ for d in dclasses])
+ dec=MetaDecorator.dic.get(decname)
+ if not dec: dec=type(decname,dclasses,{})
+ return dec
+
+def decorators_in(docstring):
+ """Takes a docstring and returns a (possibly empty) tuple of decorator
+ classes."""
+ match=MAGICDOC.match(docstring or '')
+ if not match: return ()
+ decnames=map(str.strip,match.group(1).split(',')) # get the names
+ try: dclasses=[MetaDecorator.dic[n] for n in decnames] # get the decorators
+ except KeyError: raise UnknownDecoratorError(n)
+ return tuple(dclasses)
+
+def decorate(objdict):
+ """Takes an object with a dictionary and decorates all its functions
+ and classes according to their docstrings."""
+ for name,obj in objdict.__dict__.items(): # works for classes too
+ #if getattr(obj,'__doc__',None): # non-empty docstring
+ dec_obj=decorator(obj)
+ if dec_obj:
+ setattr(dec_obj,'__klass__',objdict)
+ setattr(objdict,name,dec_obj)
+
+def getdec(magicstring="[decorator]"):
+ """Given a magicstring describing a valid decorator name, returns the list
+ of its subclasses. By default returns the full list of decorators."""
+ dec=compose(decorators_in(magicstring))
+ isdecorator=lambda x: issubclass(x,dec)
+ return filter(isdecorator,MetaDecorator.ls)
+
+def instance_str(self):
+ "Redefines the printing representation of simple objects"
+ return "<%s instance>" % self.__class__.__name__
+
+####################### BASIC DECORATORS ###########################
+
+class decorator(object):
+ """Instance of MetaDecorator and mothers of all decorators. When called
+ in the form ``decorator(obj)`` with obj having a magic docstring, it
+ returns a decorated object; otherwise it returns ``None``."""
+ __metaclass__=MetaDecorator
+ def _call_(dec,obj):
+ "Returns None, all the interesting stuff is in MetaDecorator.__call__"
+ _call_=classmethod(_call_)
+
+class MethodDecorator(decorator):
+ """Descriptor class callable with a function or a descriptor object
+ as argument. It defines a default printing representation on method
+ decorators objects and a default ``get`` method. All the rest is
+ provided by the metaclass ``MetaDecorator``.
+ """
+ __klass__=type('?',(),{}) # dummy definition class, to be overridden
+ def __init__(self,objfunc):
+ "objfunc is a decorator object or a function"
+ assert isinstance(objfunc,(FunctionType,decorator))
+ super(MethodDecorator,self).__init__(objfunc)
+ self.__func__=getattr(objfunc,'__func__',objfunc)
+ def get(self,obj,cls=None):
+ "aliased to __get__ by the metaclass, to be overridden"
+ return self.__func__.__get__(obj,cls)
+ def __str__(self):
+ "Printing representation of kind <decoratorclass:functionname>"
+ return '<%s:%s>' % (self.__class__.__name__,self.__func__.__name__)
+ def _call_(dec,obj):
+ "Returns a method decorator object."
+ return type.__call__(dec,obj) # calls __new__ and __init__
+ _call_=classmethod(_call_)
+
+class ClassDecorator(type,decorator):
+ """Metaclass callable with one or three arguments, having its calling
+ syntax redefined by ``MetaDecorator``."""
+ def _call_(dec,*args):
+ "Returns a decorated class"
+ a=args[0] # first argument; must be a string or a class
+ if inspect.isclass(a): args=a.__name__,a.__bases__,a.__dict__.copy()
+ return type.__call__(dec,*args) # calls __new__ and __init__
+ _call_=classmethod(_call_)
+
+class Decorated(ClassDecorator):
+ """Metaclass which decorates the methods of its instances according
+ to the docstrings. It redefines ``__str__`` on
+ its instances and the default ``__str__`` on the instances of its
+ instances."""
+ def __init__(cls,name,bases,dic):
+ super(Decorated,cls).__init__(name,bases,dic)
+ if cls.__str__ is object.__str__: cls.__str__=instance_str
+ # redefine default __str__
+ decorate(cls)
+ def __str__(cls):
+ "Redefine the printing representation of classes"
+ return '<class %s[%s]>' % (cls.__name__,cls.__class__.__name__)
+
+#################### Built-in Method decorators ######################
+
+class staticmethod(MethodDecorator):
+ "Decorator, converts a function in a staticmethod"
+ def get(self,obj,cls=None):
+ return super(staticmethod,self).get(obj,cls).im_func
+
+class classmethod(MethodDecorator):
+ "Decorator, converts a function in a classmethod"
+ def get(self,obj,cls=None):
+ if cls is None: cls=type(obj)
+ return super(classmethod,self).get(cls,cls)
+
+#################### functions of the API #################################
+
+def enhance_classes(magicstring='[ClassDecorator]'):
+ """Enhances all the classes in the caller module with a metaclass
+ built from the given magicstring."""
+ callerglobals=sys._getframe(1).f_globals
+ dec=compose(decorators_in(magicstring))
+ callerglobals['__metaclass__']=dec
+ callerglobals['object']=dec('object',(),{})
diff --git a/pypers/pep318/decorators.tex b/pypers/pep318/decorators.tex
new file mode 100755
index 0000000..7dbc220
--- /dev/null
+++ b/pypers/pep318/decorators.tex
@@ -0,0 +1,1733 @@
+\documentclass[11pt,english]{article}
+\usepackage{babel}
+\usepackage{shortvrb}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\usepackage{longtable}
+\setlength{\extrarowheight}{2pt}
+\usepackage{amsmath}
+\usepackage{graphicx}
+\usepackage{color}
+\usepackage{multirow}
+\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+\usepackage[a4paper,margin=2cm]{geometry}
+%% generator Docutils: http://docutils.sourceforge.net/
+\newlength{\admonitionwidth}
+\setlength{\admonitionwidth}{0.9\textwidth}
+\newlength{\docinfowidth}
+\setlength{\docinfowidth}{0.9\textwidth}
+\newcommand{\optionlistlabel}[1]{\bf #1 \hfill}
+\newenvironment{optionlist}[1]
+{\begin{list}{}
+ {\setlength{\labelwidth}{#1}
+ \setlength{\rightmargin}{1cm}
+ \setlength{\leftmargin}{\rightmargin}
+ \addtolength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \renewcommand{\makelabel}{\optionlistlabel}}
+}{\end{list}}
+% begin: floats for footnotes tweaking.
+\setlength{\floatsep}{0.5em}
+\setlength{\textfloatsep}{\fill}
+\addtolength{\textfloatsep}{3em}
+\renewcommand{\textfraction}{0.5}
+\renewcommand{\topfraction}{0.5}
+\renewcommand{\bottomfraction}{0.5}
+\setcounter{totalnumber}{50}
+\setcounter{topnumber}{50}
+\setcounter{bottomnumber}{50}
+% end floats for footnotes
+% some commands, that could be overwritten in the style file.
+\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}}
+% end of "some commands"
+\input{/mnt/exp/MyDocs/pypers/style.tex}
+\title{Implementing PEP 318 (decorators)}
+\author{}
+\date{}
+\hypersetup{
+pdftitle={Implementing PEP 318 (decorators)},
+pdfauthor={Michele Simionato}
+}
+\raggedbottom
+\begin{document}
+\maketitle
+
+%___________________________________________________________________________
+\begin{center}
+\begin{tabularx}{\docinfowidth}{lX}
+\textbf{Module}: &
+ decorators \\
+\textbf{Version}: &
+ 0.5 \\
+\textbf{Author}: &
+ Michele Simionato \\
+\textbf{e-mail}: &
+ MicheleSimionato@libero.it \\
+\textbf{Licence}: &
+ Python-like \\
+\textbf{Date}: &
+ September 2003 \\
+\textbf{Disclaimer}: &
+ This is experimental code. Use it at your own risk! \\
+\end{tabularx}
+\end{center}
+
+
+
+
+\hypertarget{contents}{}\subsection*{~\hfill Contents\hfill ~}
+\pdfbookmark[0]{Contents}{contents}
+\begin{list}{}{}
+\item \href{#using-decorators}{Using decorators}
+\begin{list}{}{}
+\item \href{#basics}{Basics}
+
+\item \href{#decorating-methods}{Decorating methods}
+
+\item \href{#decorating-classes}{Decorating classes}
+
+\item \href{#adding-magic}{Adding magic}
+
+\item \href{#defining-method-decorators}{Defining method decorators}
+
+\item \href{#defining-class-decorators}{Defining class decorators}
+
+\item \href{#composing-decorators}{Composing decorators}
+
+\item \href{#diving-into-magic}{Diving into magic}
+
+\item \href{#advanced-usage}{Advanced usage}
+
+\end{list}
+
+\item \href{#the-implementation}{The implementation}
+\begin{list}{}{}
+\item \href{#module-decorators}{Module \texttt{decorators}}
+\begin{list}{}{}
+\item \href{#id3}{Metaclasses}
+
+\item \href{#classes}{Classes}
+
+\item \href{#functions}{Functions}
+
+\end{list}
+
+\end{list}
+
+\end{list}
+
+
+
+%___________________________________________________________________________
+
+\hypertarget{using-decorators}{}
+\section*{Using decorators}
+\pdfbookmark[0]{Using decorators}{using-decorators}
+
+Having plenty of free time in these days, I have finished an old
+project of mine, the implementation of \href{http://www.python.org/pep}{PEP 318} in pure Python
+(2.3).
+
+Here is the rationale:
+\begin{itemize}
+\item
+some kind of decorator syntax is scheduled to go in Python 2.4,
+therefore it is interesting to play with the concept;
+
+\item
+it is nice to play with decorators now, without having to
+wait for one year or so;
+
+\item
+it is much easier to experiment with a pure Python implementation
+than with a C implementation;
+
+\item
+the implementation can be seen as an exercise on modern Python
+programming and may be valuable to people wanting to study the most
+advanced new constructs in Python (\href{http://users.rcn.com/python/download/Descriptor.htm}{descriptors}, \href{http://www-106.ibm.com/developerworks/library/l-pymeta2.html}{metaclasses},
+\href{http://www.python.org/2.3/descrintro.html}{cooperative methods}, etc.)
+
+\end{itemize}
+
+
+%___________________________________________________________________________
+
+\hypertarget{basics}{}
+\subsection*{Basics}
+\pdfbookmark[1]{Basics}{basics}
+
+PEP 318 has the goal of providing a nice syntactic sugar for expressions like
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{def~identity(x):}\\
+\mbox{~~~~return~x}\\
+\mbox{identity=staticmethod(identity)}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+or
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{def~name(cls):}\\
+\mbox{~~~return~cls.{\_}{\_}name{\_}{\_}}\\
+\mbox{name=classmethod(name)}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+which are pretty verbose. It is clear that having new syntax (as
+for instance the proposed square bracket notation)
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{def~identity(x)[staticmethod]:}\\
+\mbox{~~~~return~x}\\
+\mbox{}\\
+\mbox{def~name(cls)[classmethod]:}\\
+\mbox{~~~~return~cls.{\_}{\_}name{\_}{\_}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+involves changing the grammar and modifying the interpreter at the
+C level. This means a lot of work. Fortunately, it is possible to
+have the same effect without changing the Python grammar.
+The idea is to use magic docstrings like this:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{def~identity(x):}\\
+\mbox{~~~~"[staticmethod]"}\\
+\mbox{~~~~return~x}\\
+\mbox{}\\
+\mbox{def~name(cls):}\\
+\mbox{~~~~"[classmethod]"}\\
+\mbox{~~~~return~cls.{\_}{\_}name{\_}{\_}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+The implementation is able to recognize such magic docstrings
+and automatically converts methods with magic docstrings in
+method decorators.
+
+Decorators are nothing else than a sophisticated kind of wrappers.
+The \texttt{decorators} module provides support both for method decorators
+and class decorators:
+\begin{itemize}
+\item
+\emph{Method decorators} are classes taking a single function as input and
+producing a descriptor object as output. \texttt{staticmethod} and
+\texttt{classmethod} are two examples of already existing
+method decorators (actually my implementation rewrites them).
+A knowledge of descriptors [\hyperlink{id2}{1}] is not needed in order to use the \texttt{decorator}
+module; however it is welcomed for advanced users wanting to implement
+custom method decorators.
+
+\item
+\emph{Class decorators} are metaclasses taking a class as imput and returning
+a decorated class as output. A good understanding of metaclasses is needed
+in order to be able to write custom class decorators, but no knowledge
+at all is required in order to use the pre-defined class decorators
+provided by the module.
+
+\end{itemize}
+
+Notice that properties are not decorators according to my definitions,
+since they take four functions as input, \texttt{get, set, del{\_}} and \texttt{doc}.
+Whereas the decorators concept could be generalized to the case of
+multiple inputs, I don't see the need for such complication, so
+properties are not implemented as method decorators. Moreover, I
+think it is much better to use them trough a class decorator.
+
+Finally, the module is meant to be extensible; so one could
+define new kind of decorators. For instance, the original version of
+the module also had the concept of module decorators; however I have cut
+down that part in order to keep the documentation short.
+
+Admittedly, the implementation
+is not for the faint of heart, nevertheless I have tried to make the
+basic usage easy and simple to understand.
+\begin{figure}[b]\hypertarget{id2}[1]
+Descriptors are objects with a \texttt{{\_}{\_}get{\_}{\_}} method; they are quite
+sophisticated, but fortunately they have been wonderfully explained by
+Raymond Hettinger already, so I am allowed to skip on this point ;).
+\end{figure}
+
+
+%___________________________________________________________________________
+
+\hypertarget{decorating-methods}{}
+\subsection*{Decorating methods}
+\pdfbookmark[1]{Decorating methods}{decorating-methods}
+
+Before talking about the implementation details, I will show
+how the \texttt{decorators} module works in practice. The simplest and safest
+usage is by means of the \texttt{decorators.decorated()} function, which
+takes an object (a function or a class) and checks its docstring: if
+a magic docstring is found, it returns a decorated version of the object,
+otherwise it returns the original object. Using \texttt{decorators.decorated()}
+is simple but verbose, so magic shortcuts will be discussed in the next
+sections.
+
+Here, let me give an example, showing that method decorators work both for
+\href{http://www.python.org/2.3/descrintro.html}{new style classes and old style classes}:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}example1.py{$>$}}\\
+\mbox{}\\
+\mbox{import~decorators}\\
+\mbox{}\\
+\mbox{def~do{\_}nothing(self):}\\
+\mbox{~~~"No~magic~docstring~here"}\\
+\mbox{dec{\_}do{\_}nothing=decorators.decorated(do{\_}nothing)}\\
+\mbox{}\\
+\mbox{def~identity(x):}\\
+\mbox{~~~~"[staticmethod]"}\\
+\mbox{~~~~return~x}\\
+\mbox{dec{\_}identity=decorators.decorated(identity)~}\\
+\mbox{}\\
+\mbox{def~name(cls):}\\
+\mbox{~~~~"[classmethod]"}\\
+\mbox{~~~~return~cls.{\_}{\_}name{\_}{\_}}\\
+\mbox{dec{\_}name=decorators.decorated(name)}\\
+\mbox{}\\
+\mbox{class~OldStyle:}\\
+\mbox{~~~~do{\_}nothing=dec{\_}do{\_}nothing}\\
+\mbox{~~~~identity=dec{\_}identity}\\
+\mbox{}\\
+\mbox{class~NewStyle(object):}\\
+\mbox{~~~~name=dec{\_}name}\\
+\mbox{}\\
+\mbox{o=OldStyle()~{\#}~creates~an~old~style~instance}\\
+\mbox{n=NewStyle()~{\#}~creates~a~new~style~instance}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/example1.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+\begin{verbatim}>>> from example1 import * # for testing purposes\end{verbatim}
+
+In this example, both \texttt{dec{\_}identity} and \texttt{dec{\_}name} are decorator objects,
+i.e. descriptors modifiying the attribute access. It is easy to recognize
+decorators objects in the interpreter, since they have a re-defined
+printing representation:
+\begin{verbatim}>>> print dec_identity
+<staticmethod:identity>
+>>> print dec_name
+<classmethod:name>\end{verbatim}
+
+On the other hand, \texttt{do{\_}nothing} does not have a magic
+docstring, therefore it is not converted to a decorator object;
+actually it is \emph{exactly} the original function
+\begin{verbatim}>>> dec_do_nothing is do_nothing # not converted
+True\end{verbatim}
+
+and it works as a standard method:
+\begin{verbatim}>>> o.do_nothing() # does nothing, correct\end{verbatim}
+
+On the contrary, \texttt{dec{\_} identity} works as a staticmethod,
+\begin{verbatim}>>> OldStyle.identity(1) # called from the class
+1
+>>> o.identity(1) # called from the instance
+1\end{verbatim}
+
+whereas \texttt{dec{\_}name} works as a classmethod:
+\begin{verbatim}>>> NewStyle.name() # called from the class
+'NewStyle'
+>>> n.name() # called from the instance
+'NewStyle'\end{verbatim}
+
+Notice that, I have re-implemented the built-in
+\texttt{staticmethod} and \texttt{classmethod}, so
+\begin{verbatim}>>> isinstance(dec_identity,staticmethod)
+False\end{verbatim}
+
+and
+\begin{verbatim}>>> isinstance(dec_name,classmethod)
+False\end{verbatim}
+
+It is possible to recognize method decorators since they provides
+a couple of special attributes:
+\begin{itemize}
+\item
+\texttt{{\_}{\_}func{\_}{\_}}: returning the function from which they originated:
+\begin{verbatim}>>> assert dec_identity.__func__ is identity
+>>> assert dec_name.__func__ is name\end{verbatim}
+
+\item
+\texttt{{\_}{\_}klass{\_}{\_}}: returning the class where they where defined:
+\begin{verbatim}>>> dec_identity.__klass__
+<class 'safetype.?'>\end{verbatim}
+
+\end{itemize}
+
+The question mark here means that the definition class is unknown.
+The \texttt{{\_}{\_}klass{\_}{\_}} attribute can be set by hand or automatically
+with the trick explained in the next section.
+
+
+%___________________________________________________________________________
+
+\hypertarget{decorating-classes}{}
+\subsection*{Decorating classes}
+\pdfbookmark[1]{Decorating classes}{decorating-classes}
+
+The problem with the approach just described
+is that it does not present any significant advantage over
+the already existing mechanism. A real step forward would be to
+have classes with the ability of automatically decorating their
+methods according to the docstrings.
+This sounds a bit of magic, but actually can be done very simply
+by adding to the class a docstring starting with ``[Decorated]''
+and by decorating the class.
+Here is an example:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}example2.py{$>$}}\\
+\mbox{}\\
+\mbox{from~decorators~import~decorated}\\
+\mbox{from~example1~import~do{\_}nothing,identity,name}\\
+\mbox{}\\
+\mbox{class~B(object):}\\
+\mbox{~~~~"This~is~a~regular~class"}\\
+\mbox{}\\
+\mbox{B=decorated(B)~{\#}~does~nothing}\\
+\mbox{}\\
+\mbox{class~C(B):}\\
+\mbox{~~~"[Decorated]"}\\
+\mbox{~~~do{\_}nothing=do{\_}nothing}\\
+\mbox{~~~identity=identity}\\
+\mbox{~~~class~Inner:~{\#}~old~style~class}\\
+\mbox{~~~~~~~"[Decorated]"~{\#}~required~docstring~~~}\\
+\mbox{~~~~~~~name=name}\\
+\mbox{}\\
+\mbox{C=decorated(C)~{\#}~regenerates~the~class~converting~methods~in~decorators}\\
+\mbox{c=C()}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/example2.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Under the hood \texttt{decorators.decorated()} recognizes the class level
+magic docstring ``[Decorated]'' and creates an instance of the
+\texttt{decorators.Decorated} metaclass.
+Internally the metaclass invokes \texttt{decorators.decorated()}
+on the methods of its instances: this is why they becomes decorated
+if a suitable docstring is found. Moreover, it decorates inner classes,
+if a suitable docstring is found, and it works recursively.
+
+Here is the testing:
+\begin{verbatim}>>> from example2 import *
+>>> assert C.identity(1) == 1
+>>> assert C.Inner.name() == 'Inner'
+>>> assert c.identity(1) == 1
+>>> assert c.Inner.name() == 'Inner' \end{verbatim}
+
+Notice that adding \texttt{identity} after the class creation with the syntax
+\texttt{C.identity=identity} would not work;
+\texttt{C.identity=decorators.decorated(identity)} is required:
+\begin{verbatim}>>> C.identity=decorators.decorated(identity)
+>>> C.identity(1) # it works
+1\end{verbatim}
+
+If a class misses the magic docstring, nothing happens:
+\begin{verbatim}>>> B # returns the original B
+<class 'example2.B'>\end{verbatim}
+
+The mechanism works for old style classes too,
+since the metaclass automagically converts the old style classes in a
+new style one:
+\begin{verbatim}>>> type(C.Inner) # C.Inner is an instance of decorator.Decorated
+<class 'decorators.Decorated'>\end{verbatim}
+
+The enhancement provided by the metaclass includes a new default
+printing representation for both the class
+\begin{verbatim}>>> print C # returns the name of D and of its metaclass
+<class C[Decorated]>\end{verbatim}
+
+and its instances:
+\begin{verbatim}>>> print c
+<C instance>\end{verbatim}
+
+On the other hand, if a custom printing representation is already
+defined, the metaclass takes it without any change.
+
+One can even forget the docstring in subclasses of decorated
+classes, since metaclasses are inherited:
+\begin{verbatim}>>> class D(C):
+... def name(cls):
+... "[classmethod]"
+... return cls.__name__
+>>> print D.name()
+D\end{verbatim}
+
+Decorating whole classes presents another advantage: the decorated methods know
+the class where they were defined via the special attribute \texttt{{\_}{\_}klass{\_}{\_}}:
+\begin{verbatim}>>> D.__dict__['name'].__klass__ # the class where 'name' is defined
+<class 'D'>\end{verbatim}
+
+This is useful for introspection and debugging purposes.
+
+
+%___________________________________________________________________________
+
+\hypertarget{adding-magic}{}
+\subsection*{Adding magic}
+\pdfbookmark[1]{Adding magic}{adding-magic}
+
+The problem of the previous approach is that one must explicitely
+decorate the classes by hand, by invoking \texttt{decorators.decorated()}
+each time. However, it is possible to add more magic
+and to decorate all the classes automatically.
+It is as easy as writing \texttt{decorators.enhance{\_}classes()}
+on top of you module. Then all methods in all classes with a magic docstring
+will be checked for magic docstrings and automagically decorated if needed.
+For instance, the previous example would be written
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}example3.py{$>$}}\\
+\mbox{}\\
+\mbox{import~decorators;~decorators.enhance{\_}classes()}\\
+\mbox{}\\
+\mbox{class~C:}\\
+\mbox{~~~~"[Decorated]"~{\#}~magic~docstring~here~}\\
+\mbox{~~~~def~do{\_}nothing(self):}\\
+\mbox{~~~~~~~"No~magic~docstring~here"}\\
+\mbox{}\\
+\mbox{~~~~def~identity(x):}\\
+\mbox{~~~~~~~~"[staticmethod]"}\\
+\mbox{~~~~~~~~return~x}\\
+\mbox{}\\
+\mbox{class~D(object):}\\
+\mbox{~~~~"Undecorated"~{\#}~no~magic~docstring~here}\\
+\mbox{~~~~def~name(cls):}\\
+\mbox{~~~~~~~~"[classmethod]"}\\
+\mbox{~~~~~~~~return~cls.{\_}{\_}name{\_}{\_}}\\
+\mbox{}\\
+\mbox{c=C();~d=D()}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/example3.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+\texttt{C} has a \texttt{[Decorated]} docstring, so its methods
+are automatically decorated:
+\begin{verbatim}>>> from example3 import *
+>>> assert c.do_nothing() is None
+>>> assert C.identity(1) == 1
+>>> assert c.identity(1) == 1 \end{verbatim}
+
+On the other hand, since \texttt{D} misses a magic docstring,
+its \texttt{name} method is not decorated:
+\begin{verbatim}>>> hasattr(D.__dict__['name'],'__func__') # not a decorator
+False\end{verbatim}
+
+Since \texttt{D.name} is a regular method and not a classmethod, \texttt{D.name()}
+gives an error:
+\begin{verbatim}>>> D.name()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method name() must be called with D instance
+as first argument (got nothing instead)\end{verbatim}
+
+Under the hood, the magic works by enhancing the \texttt{object} class
+of the module with a \texttt{decorators.ClassDecorator} metaclass:
+\begin{verbatim}>>> import example4
+>>> type(example4.object)
+<class 'decorators.ClassDecorator'>\end{verbatim}
+
+Notice that for safety reasons the enhancement is only on the module
+\texttt{object} class, not on the \texttt{{\_}{\_}builtin{\_}{\_}.object} class. The dangers of
+adding too much magic are discussed in the \href{#diving-into-magic}{Diving into magic} section.
+
+
+%___________________________________________________________________________
+
+\hypertarget{defining-method-decorators}{}
+\subsection*{Defining method decorators}
+\pdfbookmark[1]{Defining method decorators}{defining-method-decorators}
+
+The \texttt{decorators} module contains two predefinite method decorators,
+\texttt{staticmethod} and \texttt{classmethod}, which emulate the built-ins
+with the same names. However, it is possible to write your own
+custom decorators. The \texttt{decorators.MethodDecorator} class which is here
+exactly for that purpose.
+
+Custom decorators are expected to be implemented by subclassing
+\texttt{MethodDecorator} and by overriding its \texttt{get} method. The
+\texttt{get} method automagically induces a \texttt{{\_}{\_}get{\_}{\_}} method, turning the
+class in a descriptor. The machinery is needed since \texttt{{\_}{\_}get{\_}{\_}} cannot
+be made cooperative using the standard \texttt{super} mechanism because
+there would be a confusion between \texttt{super.{\_}{\_}get{\_}{\_}} and the decorator
+\texttt{{\_}{\_}get{\_}{\_}}. This is a bit tricky, but the causal programmer is not
+expected to write custom decorators, and actually I don't want to make
+the access to decorators \emph{too} easy, since they are potentially dangerous.
+
+In order to give a simple example, let me show the implementation
+of a \texttt{chattymethod} that prints a message when it is called:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}customdec.py{$>$}}\\
+\mbox{}\\
+\mbox{from~decorators~import~*~~}\\
+\mbox{}\\
+\mbox{class~chattymethod(MethodDecorator):}\\
+\mbox{~~~~logfile=sys.stdout~{\#}~default}\\
+\mbox{~~~~def~get(self,obj,cls=None):~{\#}~same~signature~as~{\_}{\_}get{\_}{\_}}\\
+\mbox{~~~~~~~~self.logfile.write('calling~{\%}s~from~{\%}s{\textbackslash}n'~{\%}~(self,obj~or~cls))}\\
+\mbox{~~~~~~~~return~super(chattymethod,self).get(obj,cls)}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/customdec.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Notice the usage of the \texttt{super().get} trick. This guarantees that
+\texttt{chattymethod} will play well with other decorators (i.e. it
+can be nicely composed via multiple inheritance). The point will
+be fully discussed in the section on composing decorators.
+
+Here is an example of usage:
+\begin{verbatim}>>> import customdec # adds chattymethod to the list of known decorators
+>>> customdec.enhance_classes() # automagically enhances classes
+>>> class C:
+... " [Decorated] "
+... def f(self):
+... """
+... [ chattymethod ]
+... """
+>>> c=C()
+>>> c.f()
+calling <chattymethod:f> from <C instance>\end{verbatim}
+
+By the way, this shows that one can safely add whitespaces (including
+newlines) to the magic docstring: they are simply ignored.
+
+One can check that the syntax \texttt{C.f(c)} works too:
+\begin{verbatim}>>> C.f(c)
+calling <chattymethod:f> from <class C[Decorated]>\end{verbatim}
+
+A tricky point of the decorators mechanism is the issue of parameter passing.
+In comp.lang.python there was the proposal of allowing explicit parameter
+passing to decorators, with a syntax of kind
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{def~f(self)[chattymethod(logfile=file('file1.log','w'))]}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+In my view, there are too many parenthesis in this syntax, and it
+becomes rapidly unreadable. Moreover, it complicates the implementation
+without any real benefit, so the \texttt{decorators} module does not allow
+this kind of parameter passings. There are however viable
+workarounds, so you should not miss the syntax.
+
+A simple minded solution is to change the defaults by hand:
+\begin{verbatim}>>> from customdec import chattymethod,decorated
+>>> chattymethod.logfile=file('file.log','w')
+>>> def g(self):
+... "[chattymethod]"
+>>> C.g=decorated(g)
+>>> c.g() # will print a message on file.log\end{verbatim}
+
+This approach has the drawback that chattymethods created before changing
+the logfile will also print to the new logfile, if invoked after the
+change. Therefore
+\begin{verbatim}>>> c.f()\end{verbatim}
+
+will print a message to \texttt{file.log} too, and not to standard output.
+Here is the confirmation:
+\begin{verbatim}>>> chattymethod.logfile.close()
+>>> print file('file.log').read().rstrip()
+calling <chattymethod:g> from <C instance>
+calling <chattymethod:f> from <C instance>\end{verbatim}
+
+A better solution is to pass
+parameters to method decorators as function attributes: then the function
+attributes can be converted to attributes of the decorator
+in the \texttt{{\_}{\_}init{\_}{\_}} method. Here is an example:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}customdec.py{$>$}}\\
+\mbox{}\\
+\mbox{class~chattymethod2(chattymethod):~}\\
+\mbox{~~~~logfile=sys.stdout~{\#}~default}\\
+\mbox{~~~~def~{\_}{\_}init{\_}{\_}(self,objfunc):}\\
+\mbox{~~~~~~~~super(chattymethod2,self).{\_}{\_}init{\_}{\_}(objfunc)}\\
+\mbox{~~~~~~~~logfile=getattr(self.{\_}{\_}func{\_}{\_},'logfile',None)}\\
+\mbox{~~~~~~~~if~logfile:~self.logfile=logfile~}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/customdec.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Notice that the \texttt{{\_}{\_}init{\_}{\_}} method has the signature
+\texttt{{\_}{\_}init{\_}{\_}(self,objfunc)}, where the \texttt{objfunc} object is a
+decorator object or the function to be converted in the decorator
+object, and that it is cooperative.
+This is the suggested way of overriding \texttt{{\_}{\_}init{\_}{\_}}.
+
+Here is the testing:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}chatty2.py{$>$}}\\
+\mbox{}\\
+\mbox{import~customdec;~customdec.enhance{\_}classes()}\\
+\mbox{}\\
+\mbox{{\#}~sets~the~log~files}\\
+\mbox{log1=file('file1.log','w')}\\
+\mbox{log2=file('file2.log','w')}\\
+\mbox{}\\
+\mbox{class~C:}\\
+\mbox{~~~~"[Decorated]"}\\
+\mbox{~~~~def~f(self):~}\\
+\mbox{~~~~~~~~"[chattymethod2]"}\\
+\mbox{~~~~f.logfile=log1~{\#}~function~attribute}\\
+\mbox{~~~~def~g(self):~}\\
+\mbox{~~~~~~~~"[chattymethod2]"}\\
+\mbox{~~~~g.logfile=log2~{\#}~function~attribute}\\
+\mbox{}\\
+\mbox{assert~C.{\_}{\_}dict{\_}{\_}['f'].logfile~is~log1~{\#}~check~the~conversion~}\\
+\mbox{assert~C.{\_}{\_}dict{\_}{\_}['g'].logfile~is~log2~{\#}~function~attr.~-{$>$}~decorator~attr.}\\
+\mbox{}\\
+\mbox{c=C()~{\#}~C~instantiation}\\
+\mbox{}\\
+\mbox{c.f()~{\#}~print~a~message~in~file1.log}\\
+\mbox{c.g()~{\#}~print~a~message~in~file2.log}\\
+\mbox{}\\
+\mbox{log1.close();~log2.close()~{\#}~finally}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/chatty2.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Let me check the contents of the log files:
+\begin{verbatim}>>> import chatty2
+>>> print file('file1.log').read().rstrip()
+calling <chattymethod2:f> from <C instance>
+>>> print file('file2.log').read().rstrip()
+calling <chattymethod2:g> from <C instance>\end{verbatim}
+
+\texttt{chattymethod} is the poor man version of \texttt{tracedmethod}, a
+sophisticated decorator for tracing methods.
+Here is the code, given for pedagogical purposes; the lazy reader can
+skip it and go directly to the usage section.
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}customdec.py{$>$}}\\
+\mbox{}\\
+\mbox{class~tracedmethod(MethodDecorator):}\\
+\mbox{~~~~"Descriptor~class,~converts~a~method~in~a~traced~method"}\\
+\mbox{~~~~indent=0;~output=sys.stdout~{\#}~defaults}\\
+\mbox{}\\
+\mbox{~~~~def~{\_}{\_}init{\_}{\_}(self,objfunc):}\\
+\mbox{~~~~~~~~super(tracedmethod,self).{\_}{\_}init{\_}{\_}(objfunc)}\\
+\mbox{~~~~~~~~self.funcname=self.{\_}{\_}func{\_}{\_}.{\_}{\_}name{\_}{\_}}\\
+\mbox{~~~~~~~~output=getattr(self.{\_}{\_}func{\_}{\_},'output',None)~}\\
+\mbox{~~~~~~~~if~output:~self.output=output~{\#}~func.attr.~-{$>$}~dec.attr.}\\
+\mbox{}\\
+\mbox{~~~~def~get(self,obj,cls):}\\
+\mbox{~~~~~~~~clsname=self.{\_}{\_}klass{\_}{\_}.{\_}{\_}name{\_}{\_}~{\#}~definition~clas}\\
+\mbox{~~~~~~~~def~tracedmeth(obj,*args,**kw):}\\
+\mbox{~~~~~~~~~~~~i='~'*self.indent~{\#}~default~indentation}\\
+\mbox{~~~~~~~~~~~~self.{\_}{\_}class{\_}{\_}.indent+=4~{\#}~increases~indentation}\\
+\mbox{~~~~~~~~~~~~self.output.write("{\%}sCalling~'{\%}s.{\%}s'~with~arguments~"~{\%}~}\\
+\mbox{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~(i,clsname,self.funcname))}\\
+\mbox{~~~~~~~~~~~~self.output.write("{\%}s{\%}s~...{\textbackslash}n"~{\%}~(obj~or~'',str(args)+str(kw)))}\\
+\mbox{~~~~~~~~~~~~res=super(tracedmethod,self).get(obj,cls)(*args,**kw)}\\
+\mbox{~~~~~~~~~~~~self.output.write("{\%}s'{\%}s.{\%}s'~called~with~result:~{\%}s{\textbackslash}n"}\\
+\mbox{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{\%}~(i,clsname,self.funcname,res))}\\
+\mbox{~~~~~~~~~~~~self.{\_}{\_}class{\_}{\_}.indent-=4~{\#}~restores~default~indentation}\\
+\mbox{~~~~~~~~~~~~return~res}\\
+\mbox{~~~~~~~~return~tracedmeth.{\_}{\_}get{\_}{\_}(obj,cls)~{\#}~method~wrapper}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/customdec.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+\texttt{tracedmethod.get} returns a method wrapper object, so it is
+possible to use \texttt{im{\_}func} to retrieve the internal function
+\texttt{tracedmeth}:
+\begin{verbatim}>>> class C:
+... "[Decorated]"
+... def f(self):
+... "[tracedmethod]"
+>>> c=C(); c.f()
+Calling 'C.f' with arguments <C instance>(){} ...
+'C.f' called with result: None
+>>> c.f.im_func.__name__
+'tracedmeth'\end{verbatim}
+
+As soon as the \texttt{tracedmethod} module is loaded, the \texttt{tracedmethod} class
+is added to the list of know decorators, so one should use the
+``[tracedmethod]'' docstring and not something like
+``[customdec.tracedmethod]''.
+
+Here is a less trivial example of usage, writing in a log file the
+internal working of a recursive function:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}example9.py{$>$}}\\
+\mbox{}\\
+\mbox{import~customdec;~customdec.enhance{\_}classes()}\\
+\mbox{}\\
+\mbox{logfile=file('file3.log','w')}\\
+\mbox{}\\
+\mbox{class~C(object):}\\
+\mbox{~~~~"[Decorated]"}\\
+\mbox{~~~~def~fact(self,n):}\\
+\mbox{~~~~~~~~"[tracedmethod]~The~good~old~factorial."}\\
+\mbox{~~~~~~~~if~n==0:~return~1}\\
+\mbox{~~~~~~~~else:~return~n*self.fact(n-1)}\\
+\mbox{~~~~fact.output=logfile}\\
+\mbox{}\\
+\mbox{C().fact(2)~{\#}~write~a~message~to~logfile}\\
+\mbox{}\\
+\mbox{logfile.close()}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/example9.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Here is the content of \texttt{file3.log}:
+\begin{verbatim}>>> import example9 # creates file3.log
+>>> print file('file3.log').read().rstrip()
+Calling 'C.fact' with arguments <C instance>(2,){} ...
+ Calling 'C.fact' with arguments <C instance>(1,){} ...
+ Calling 'C.fact' with arguments <C instance>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2\end{verbatim}
+
+
+%___________________________________________________________________________
+
+\hypertarget{defining-class-decorators}{}
+\subsection*{Defining class decorators}
+\pdfbookmark[1]{Defining class decorators}{defining-class-decorators}
+
+PEP 318 proposes to decorate methods by using descriptors; it is
+quite natural to extend this idea and to decorate classes by using
+class decorators implemented as metaclasses. We already saw a couple of
+class decorator at work, the metaclass \texttt{ClassDecorator}, which gives
+to its instances the ability to interpret class level magic docstrings, and
+its subclass \texttt{Decorated}, which converts functions in method decorators
+if suitable docstrings are found.
+
+To define a custom class decorator is easy: one defines a custom metaclass
+as usual, with the only difference of deriving from \texttt{ClassDecorator} instead
+of deriving from \texttt{type}.
+
+To understand how this works in practice, let me
+show how to add logging capabilities to a given class. The first
+step is to define a suitable class decorator, such as the following:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}customdec.py{$>$}}\\
+\mbox{}\\
+\mbox{class~Logged(ClassDecorator):}\\
+\mbox{~~~~output=sys.stdout}\\
+\mbox{~~~~def~{\_}{\_}init{\_}{\_}(cls,name,bases,dic):}\\
+\mbox{~~~~~~~~super(Logged,cls).{\_}{\_}init{\_}{\_}(name,bases,dic)}\\
+\mbox{~~~~~~~~print~{$>$}{$>$}~cls.output,"{\%}s~created"~{\%}~cls}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/customdec.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+\texttt{Logged} is derived by the metaclass \texttt{ClassDecorator},
+which provides a certain amount of magic under the hood (in particular
+its printing representation and its calling syntax are redefined by its
+(meta-)metaclass \texttt{MetaDecorator}).
+Logging capabilities can be added to a class
+by simply using the magic docstring syntax:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}logged.py{$>$}}\\
+\mbox{}\\
+\mbox{import~customdec;~customdec.enhance{\_}classes()}\\
+\mbox{}\\
+\mbox{class~D(object):~{\#}~will~print~a~message~at~D~creation}\\
+\mbox{~~~~"[Logged]"}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/logged.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+\begin{verbatim}>>> import logged
+<class 'logged.D'> created\end{verbatim}
+
+Notice that the printing representation of \texttt{D} involves the name
+of \texttt{D} preceded by the name of its metaclass, which in this case
+is \texttt{Logged}
+
+Each time an instance of \texttt{Logged} is created, a similar message is printed:
+\begin{verbatim}>>> class E(logged.D):
+... pass
+<class 'E'> created\end{verbatim}
+
+Notice that \texttt{E} does not have any magic docstring
+\begin{verbatim}>>> E.__doc__ # no docstring\end{verbatim}
+
+but still it inherits its magic from \texttt{D}.
+
+Another simple example of class decorator is the following metaclass
+which modifies the docstrings of the methods of its instances,
+by magically inducing tracing capabilities on them:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}customdec.py{$>$}}\\
+\mbox{}\\
+\mbox{from~types~import~FunctionType~~}\\
+\mbox{}\\
+\mbox{class~Traced(Decorated):}\\
+\mbox{~~~~def~{\_}{\_}init{\_}{\_}(cls,n,b,d):}\\
+\mbox{~~~~~~~~for~name,func~in~d.iteritems():}\\
+\mbox{~~~~~~~~~~~~if~isinstance(func,FunctionType)~and~name!='{\_}{\_}str{\_}{\_}':~}\\
+\mbox{~~~~~~~~~~~~~~~~{\#}~cannot~trace~{\_}{\_}str{\_}{\_},~since~it~is~invoked~by}\\
+\mbox{~~~~~~~~~~~~~~~~{\#}~tracedmethod~and~would~generate~infinite~recursion}\\
+\mbox{~~~~~~~~~~~~~~~~func.{\_}{\_}doc{\_}{\_}="[tracedmethod]~"~+~(func.{\_}{\_}doc{\_}{\_}~or~'')}\\
+\mbox{~~~~~~~~super(Traced,cls).{\_}{\_}init{\_}{\_}(n,b,d)~{\#}~decorates~the~methods}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/customdec.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Here is an example of usage:
+\begin{verbatim}>>> class C(object):
+... """[Traced] The class decorator adds the magic docstring
+... '[tracedmethod]' to f1 and f2, which are then converted
+... in method decorator objects."""
+... def f1(self): pass
+... def f2(self): pass
+...
+>>> type(C)
+<class 'customdec.Traced'>
+>>> c=C()
+>>> c.f1()
+Calling 'C.f1' with arguments <C instance>(){} ...
+'C.f1' called with result: None
+>>> c.f2()
+Calling 'C.f2' with arguments <C instance>(){} ...
+'C.f2' called with result: None\end{verbatim}
+
+By default, the decorators module only decorates classes with a magic
+docstring (and they subclasses, even without magic docstrings).
+If all the classes of your module have the same magic docstring,
+it makes sense to decorate them all
+with a single command. It is enough to use \texttt{decorators.enhance{\_}classes()}
+with a magic docstring corresponding to a class decorator as argument,
+as in this example:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}example7.py{$>$}}\\
+\mbox{}\\
+\mbox{from~example2~import~identity,name}\\
+\mbox{import~inspect,~decorators;~decorators.enhance{\_}classes("[Decorated]")}\\
+\mbox{}\\
+\mbox{class~C1(object):~{\#}~automagically~converted~to~a~decorated~class}\\
+\mbox{~~~~identity=identity~}\\
+\mbox{}\\
+\mbox{class~C2:~{\#}~automagically~converted~to~a~decorated~class}\\
+\mbox{~~~~name=name}\\
+\mbox{}\\
+\mbox{c1=C1()~{\#}~C1~instance}\\
+\mbox{c2=C2()~{\#}~C2~instance}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/example7.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+The magic works both for new style classes such as \texttt{C1}
+\begin{verbatim}>>> from example7 import C1,c1
+>>> assert C1.identity(1) == 1
+>>> assert c1.identity(1) == 1 \end{verbatim}
+
+and old style classes such as \texttt{C2} by implicitly converting them
+to new style classes:
+\begin{verbatim}>>> from example7 import C2,c2
+>>> assert C2.name() == 'C2'
+>>> assert c2.name() == 'C2' \end{verbatim}
+
+
+%___________________________________________________________________________
+
+\hypertarget{composing-decorators}{}
+\subsection*{Composing decorators}
+\pdfbookmark[1]{Composing decorators}{composing-decorators}
+
+Decorators can be composed by using magic docstrings with comma-separated
+decorator names. For instance, you can trace a classmethod:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}example6.py{$>$}}\\
+\mbox{}\\
+\mbox{"How~to~trace~a~class~method"}\\
+\mbox{}\\
+\mbox{import~customdec;~customdec.enhance{\_}classes()}\\
+\mbox{}\\
+\mbox{class~C(object):}\\
+\mbox{~~~~"[Decorated]"}\\
+\mbox{~~~~def~fact(cls,n):~{\#}~a~traced~classmethod}\\
+\mbox{~~~~~~~~"[classmethod,tracedmethod]"}\\
+\mbox{~~~~~~~~if~n==0:~return~1}\\
+\mbox{~~~~~~~~else:~return~n*cls.fact(n-1)}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/example6.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Here is the testing:
+\begin{verbatim}>>> from example6 import C
+>>> C.fact(2)
+Calling 'C.fact' with arguments <class C[Decorated]>(2,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(1,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2\end{verbatim}
+
+You may easily check that calling \texttt{C().fact} will work too.
+
+Under the hood the syntax
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{[classmethod,tracedmethod]}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+generates a \texttt{classmethodtracedmethod} class obtained via
+multiple inheritance:
+\begin{verbatim}>>> type(C.__dict__['fact'])
+<class 'safetype.classmethodtracedmethod'>\end{verbatim}
+
+Notice that the order \emph{does} matter and using the docstring
+``[tracedmethod,classmethod]'' will not work:
+\begin{verbatim}>>> class D:
+... "[Decorated]"
+... def f(cls):
+... "[tracedmethod,classmethod]"
+>>> D.f()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with D instance
+as first argument (got nothing instead)\end{verbatim}
+
+The problem here is that \texttt{tracedmethod.get} returns a method-wrapper object
+which expects a D instance
+as first argument whereas it gets \texttt{None} since
+it is called from the class. On the other hand,
+\begin{verbatim}>>> D().f()
+Calling 'D.f' with arguments <D instance>(){} ...
+'D.f' called with result: None\end{verbatim}
+
+will work. When \texttt{classmethod} precedes \texttt{tracedmethod}, then
+\texttt{classmethod} passes to \texttt{tracedmeth} a non-empty first argument,
+i.e. the calling class, even when called from the instance:
+\begin{verbatim}>>> C().fact(2)
+Calling 'C.fact' with arguments <class C[Decorated]>(2,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(1,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2\end{verbatim}
+
+If we try to trace a staticmethod, we will get a different error with
+the order ``tracedmethod, staticmethod'':
+\begin{verbatim}>>> class F(object):
+... "[Decorated]"
+... def fact(n):
+... "[tracedmethod,staticmethod]"
+... if n==0: return 1
+... else: return n*F.fact(n-1)
+>>> F.fact(2)
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with F instance
+as first argument (got int instance instead)\end{verbatim}
+
+The message is self-explanatory.
+
+On the other hand, composing the decorators in the order
+``[tracedmethod,staticmethod]'' will work just fine.
+
+It is possible to compose class decorators just as method decorators,
+by using the docstring syntax: for instance we may create a class
+which is both \texttt{Decorated} and \texttt{Logged} and by trivially writing
+\begin{verbatim}>>> class C:
+... "[Decorated,Logged]"
+... def f():
+... "[staticmethod]"
+... return 'it works!'
+<class C[DecoratedLogged]> created
+>>> C().f()
+'it works!'\end{verbatim}
+
+
+%___________________________________________________________________________
+
+\hypertarget{diving-into-magic}{}
+\subsection*{Diving into magic}
+\pdfbookmark[1]{Diving into magic}{diving-into-magic}
+
+If you never use metaclasses, this part can be safely skipped. On the
+other hand, if you are a metaclass user, you \emph{must} read this section
+in order to keep your code working.
+
+The \texttt{decorators} module provide a \texttt{ClassDecorator} metaclass which
+converts a regular (both old style or new style) class in a class with
+the ability to recognize magic docstrings. Under the hood, the
+\texttt{decorators.enhance{\_}classes()} trick works by decorating the
+\texttt{object} class with \texttt{decorators.ClassDecorator} and by setting
+the custom metaclass to \texttt{decorators.ClassDecorator} and it is
+equivalent to
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{import~decorators}\\
+\mbox{object=decorators.ClassDecorator(object)~{\#}~decorates~new~style~classes}\\
+\mbox{{\_}{\_}metaclass{\_}{\_}=~decorators.ClassDecorator~{\#}~decorates~old~style~classes}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+If you want the magic to work only for new style classes only, you may
+forget the second line; if you want the magic to work for old style
+classes only, you may forget the first line.
+
+The \texttt{decorators.enhance{\_}classes("[SomeClassDec]")} syntax looks at the
+magic docstring and executes something like
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{import~decorators}\\
+\mbox{object=decorators.SomeClassDec(object)~{\#}~decorates~all~new~style~classes}\\
+\mbox{{\_}{\_}metaclass{\_}{\_}=~decorators.SomeClassDec~{\#}~decorates~all~old~style~classes}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+The problem with the \texttt{enhance{\_}classes()} syntaxes is that it is
+not 100{\%} safe under metaclass conflicts. In order to explain the issue,
+let me give an example.
+
+Suppose we enhance the \texttt{object} class in the interpreter namespace:
+\begin{verbatim}>>> import decorators; decorators.enhance_classes()\end{verbatim}
+
+making it an instance of \texttt{ClassDecorator}:
+\begin{verbatim}>>> object.__class__
+<class 'decorators.ClassDecorator'>\end{verbatim}
+
+Now, if we naively create a custom metaclass \texttt{M}:
+\begin{verbatim}>>> class M(type):
+... "Some non-trivial code here..." \end{verbatim}
+
+and we try to use it to enhance a new style class \texttt{NwithM}, we will get a
+conflict:
+\begin{verbatim}>>> class NwithM(object): __metaclass__=M # does not work!
+...
+Traceback (most recent call last):
+ ...
+TypeError: metaclass conflict: the metaclass of a derived class must be a
+(non-strict) subclass of the metaclasses of all its bases\end{verbatim}
+
+The problem is that the previous line tries to create a class \texttt{NwithM}
+which should have both metaclasses \texttt{ClassDecorator} and \texttt{M}:
+a conflict follows.
+
+Fortunately, the decorators module imports the \texttt{type} metaclass from
+my \texttt{safetype} module just to avoid this kind of problems. If we
+derive \texttt{M} from \texttt{decorators.type} (which is really \texttt{safetype.type})
+the conflict is automagically avoided:
+\begin{verbatim}>>> class M(decorators.type):
+... "This metaclass is conflict-proof"
+>>> class NwithM(object): # it works!
+... __metaclass__=M\end{verbatim}
+
+The reason why the conflict is avoided is that the \texttt{safetype} module
+(which makes use of really \emph{deep} metaclass magic) automatically
+creates the composed class \texttt{MClassDecorator} by multiply inheriting
+from \texttt{M} and from \texttt{ClassDecorator}. Then, \texttt{NwithM} can be safely
+created as an instance of \texttt{safetype.MClassDecorator}:
+\begin{verbatim}>>> type(NwithM)
+<class 'safetype.MClassDecorator'>\end{verbatim}
+
+The situation with old style classes is worse since
+apparently
+\begin{verbatim}>>> class OwithM: # old style class with metaclass M
+... __metaclass__=M
+... def sm():
+... "[staticmethod]"\end{verbatim}
+
+gives no error, but actually \texttt{M} overrides
+\texttt{ClassDecorator}, so \texttt{OwithM} will not recognize magic docstrings:
+\begin{verbatim}>>> type(OwithM)
+<class 'M'>
+>>> OwithM.sm()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with OwithM instance
+as first argument (got nothing instead)\end{verbatim}
+
+The simpler solution is to convert \texttt{OwithM} in a new style class:
+\begin{verbatim}>>> class NwithM(OwithM,object):
+... __metaclass__=M
+... def sm():
+... "[staticmethod]"
+>>> type(NwithM)
+<class 'safetype.MClassDecorator'>\end{verbatim}
+
+Now \texttt{NwithM} is not decorated since it does miss a magic docstring, but
+it provides the ability to recognizing magic docstrings, so \texttt{NwithM}
+subclasses with a ``[Decorated]'' docstring will be decorated:
+\begin{verbatim}>>> class E(NwithM):
+... "[Decorated]"
+... def cm(cls):
+... "[classmethod]"
+... print '.cm() called from',cls\end{verbatim}
+\begin{verbatim}>>> E.cm() # it works
+.cm() called from <class E[MClassDecoratorDecorated]>\end{verbatim}
+
+Notice that \texttt{sm} was defined in \texttt{NwithM}, the undecorated class: therefore
+it is not decorated:
+\begin{verbatim}>>> E.sm() # correctly, does not work
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with E instance
+as first argument (got nothing instead)\end{verbatim}
+
+The error message says that \texttt{sm} is an unbound method and not a
+static method.
+
+It is possible to go even deeper in \textbf{black} magic, and to decorate all
+the new style classes in \emph{all} modules, by decorating the
+\texttt{{\_}{\_}builtin{\_}{\_}.object}. Still, naively redefining the \texttt{{\_}{\_}builtin{\_}{\_}object}
+class is risky, since it will induce metaclass conflicts in other modules
+using metaclasses. In other words, it will work only if you import modules
+not using metaclasses, or modules using metaclasses safely, i.e. modules
+taking care of possible conflicts by using \texttt{safetype.type} as base metaclass.
+If you really enjoy black magic, you may solve the problem by
+redefining the \texttt{{\_}{\_}builtin{\_}{\_}.type} as \texttt{safetype.type}.
+The \texttt{decorators} module does not go so deep in dark magic, but still
+there are cases where you may want to do it. In these cases you must be
+explicit and redefine the builtins by hand, without help from the
+module. For instance, one of my original motivation for the usage
+of metaclasses/class decorators was to use them for debugging purposes.
+For instance, I wanted to trace the execution of methods in
+complicate inheritance hierarchies, \emph{without changing the source code}.
+For simple situations, i.e. in absence of inheritance and of pre-existing
+metaclasses, the function \texttt{import{\_}with{\_}metaclass} discussed in the
+\href{http://www-106.ibm.com/developerworks/library/l-pymeta.html}{first paper on metaclasses} written in collaboration with David Mertz, works
+fine but in general the implementation of a working \texttt{import{\_}with{\_}metaclass}
+is cumbersome. For debugging purposes, the quick and dirty way can be a
+good enough way, so let me show how we can redefine the builtins \texttt{object} and
+\texttt{type} \emph{before} importing the module, in such a way to enhance \emph{all}
+its classes with tracing capabilities.
+
+Let me start from a module using an unsafe metaclass \texttt{M}, such that it
+cannot be traced trivially by decorating its classes \emph{after} the import;
+moreover there is an inheritance hierarchy, such that it cannot be
+traced correctly by naively decorating all the classes one after the
+other (unless one modifies the original source code, but this forbidden
+by the rules of the game ;)
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}tracing.py{$>$}}\\
+\mbox{}\\
+\mbox{"""}\\
+\mbox{This~is~a~pre-existing~module~not~using~decorators~but~using~multiple}\\
+\mbox{inheritance~and~unsafe~metaclasses.~We~want~to~trace~it~for~debugging~}\\
+\mbox{purposes.}\\
+\mbox{"""}\\
+\mbox{~}\\
+\mbox{class~M(type):~}\\
+\mbox{~~~~"There~should~be~some~non-trivial~code~here"}\\
+\mbox{}\\
+\mbox{class~B(object):~}\\
+\mbox{~~~~def~{\_}{\_}init{\_}{\_}(self):}\\
+\mbox{~~~~~~~~super(B,self).{\_}{\_}init{\_}{\_}()}\\
+\mbox{}\\
+\mbox{class~D(object):~}\\
+\mbox{~~~~{\_}{\_}metaclass{\_}{\_}=M}\\
+\mbox{~~~~def~{\_}{\_}init{\_}{\_}(self):}\\
+\mbox{~~~~~~~~super(D,self).{\_}{\_}init{\_}{\_}()}\\
+\mbox{}\\
+\mbox{class~E(B,D):}\\
+\mbox{~~~~def~{\_}{\_}init{\_}{\_}(self):}\\
+\mbox{~~~~~~~~super(E,self).{\_}{\_}init{\_}{\_}()}\\
+\mbox{}\\
+\mbox{~{\#}{$<$}/tracing.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+Everything works is we modify the builtins before importing the module:
+\begin{verbatim}>>> import __builtin__
+>>> __object__=__builtin__.object # the original 'object' class
+>>> __builtin__.object=customdec.Traced('tracedobject',(),{})
+>>> __builtin__.type=customdec.type # a safe 'type' class\end{verbatim}
+
+Now, when we import the module, all the classes \texttt{M}, \texttt{B}, \texttt{D} and \texttt{E}
+will be created starting for the tricked builtins, so they will be traced
+and safe under conflicts. For instance, let me show that \texttt{E} is created
+with a conflict safe \texttt{MTraced} metaclass:
+\begin{verbatim}>>> from tracing import E
+>>> print E
+<class E[MTraced]>\end{verbatim}
+
+This shows that the \texttt{{\_}{\_}init{\_}{\_}} methods are traced indeed and shows the
+Method Resolution Order:
+\begin{verbatim}>>> e=E()
+Calling 'E.__init__' with arguments <E instance>(){} ...
+ Calling 'B.__init__' with arguments <E instance>(){} ...
+ Calling 'D.__init__' with arguments <E instance>(){} ...
+ 'D.__init__' called with result: None
+ 'B.__init__' called with result: None
+'E.__init__' called with result: None\end{verbatim}
+
+This works, indeed. At the end, one should not forget to restore
+the standard builtins, otherwise it will trace \emph{all} the classes
+created thereafter.
+\begin{verbatim}>>> __builtin__.object=__object__ # restore the __builtin__
+>>> __builtin__.type=decorators.__type__ # restore the __builtin__\end{verbatim}
+
+At the end, I will notice that it is possible to solve the problem more
+nicely, without redefining the builtins, but I will discuss the solution
+elsewhere ;)
+
+
+%___________________________________________________________________________
+
+\hypertarget{advanced-usage}{}
+\subsection*{Advanced usage}
+\pdfbookmark[1]{Advanced usage}{advanced-usage}
+
+Whereas the average programmer is expected to use the \texttt{decorated()}
+and \texttt{enhance{\_}classes()} functions only, the \texttt{decorators} module provides
+facilities which may be useful to the advanced programmer.
+
+The simplest is an utility function which retrieves the list of
+recognized decorators, \texttt{decorators.getdec()}. The precise syntax is
+\texttt{decorators.getdec(docstring)}, where \texttt{docstring}
+is a magic docstring, i.e. a bracketed comma-separated list
+of decorator names. For instance \texttt{decorators.getdec('[MethodDecorator]')}
+gives the list of all subclasses of \texttt{MethodDecorator}, i.e. all method
+decorators, whereas \texttt{decorators.getdec('[ClassDecorator]')}
+gives the list of the known class decorators. The utility of the function
+is that it also returns decorators that have been automagically created:
+\begin{verbatim}>>> decorators.getdec("[classmethodtracedmethod]")
+[<class 'safetype.classmethodtracedmethod'>]\end{verbatim}
+
+It is even possible to use the comma notation:
+\begin{verbatim}>>> decorators.getdec("[classmethod,tracedmethod]")
+[<class 'safetype.classmethodtracedmethod'>]\end{verbatim}
+
+If you mispell a decorator name you get an helpful error message:
+\begin{verbatim}>>> class E:
+... "[Decorated]"
+... def f():
+... "[staticmeth]"
+Traceback (most recent call last):
+ .. a cryptic traceback here ..
+UnknownDecoratorError: staticmeth\end{verbatim}
+
+By design, the \texttt{decorated} function is quite limited, and does not
+decorate functions without magic docstrings. This is safe and also convenient
+for internal usage of the \texttt{decorated} function in the \texttt{Decorated}
+metaclass. Nevertheless, advanced users may want to have the ability
+of decorating functions by hand, without invoking decorators.decorated()`
+and magic docstrings. This is possible, by calling the decorator directly.
+For instance, here is how to convert a lambda function in a staticmethod:
+\begin{verbatim}>>> do_nothing=decorators.staticmethod(lambda:None)
+>>> print do_nothing # ``do_nothing`` is a static method
+<staticmethod:<lambda>>\end{verbatim}
+
+The most convenient usage of this feature is in the composition of decorators.
+For instance, we may compose the just defined \texttt{staticmethod} with a
+\texttt{chattymethod2}:
+\begin{verbatim}>>> chattystatic=customdec.chattymethod2(do_nothing)
+>>> print chattystatic
+<chattymethod2staticmethod:<lambda>>\end{verbatim}
+
+The syntax
+\begin{quote}
+
+\texttt{decorator1(decorator2(obj))}
+\end{quote}
+
+automagically creates a composed class \texttt{decorator1decorator2} in the
+\texttt{safetype} module (or recycle it, if \texttt{decorator1decorator2} has
+been already created) and it is equivalent to
+\begin{quote}
+
+\texttt{decorator1decorator2(obj)}
+\end{quote}
+
+Here is the check that everything works:
+\begin{verbatim}>>> class B:
+... chattystatic=chattystatic
+>>> B.chattystatic()
+calling <chattymethod2staticmethod:<lambda>> from <class 'B'>\end{verbatim}
+
+Notice that \texttt{chattystatic} does not know the class where it
+is defined:
+\begin{verbatim}>>> chattystatic.__klass__
+<class 'safetype.?'>\end{verbatim}
+
+unless the \texttt{{\_}{\_}klass{\_}{\_}} attribute is explicitly set.
+
+This is the hierarchy:
+\begin{verbatim}>>> for C in type(chattystatic).mro(): print C
+...
+<class 'safetype.chattymethod2staticmethod'>
+<class 'customdec.chattymethod2'>
+<class 'customdec.chattymethod'>
+<class 'decorators.staticmethod'>
+<class 'decorators.MethodDecorator'>
+<class 'decorators.Decorator'>
+<type 'object'>\end{verbatim}
+
+One can also compose classes by hand, by using class decorators:
+\begin{verbatim}>>> class C:
+... "[Logged]"
+... def f(): "[staticmethod]"
+...
+<class 'C'> created
+>>> C=customdec.Traced(C)
+<class C[TracedLogged]> created\end{verbatim}
+
+The \texttt{decorators.enhance{\_}classes({$<$}classdecorator{$>$})} syntax performs
+the composition automagically:
+\begin{quote}
+\begin{ttfamily}\begin{flushleft}
+\mbox{{\#}{$<$}example8.py{$>$}}\\
+\mbox{}\\
+\mbox{from~example2~import~identity,name}\\
+\mbox{import~inspect,~decorators;~decorators.enhance{\_}classes("[Decorated]")}\\
+\mbox{}\\
+\mbox{class~C1:~{\#}~automagically~converted~to~a~Decorated~class}\\
+\mbox{~~~~identity=identity~}\\
+\mbox{}\\
+\mbox{class~C2:~{\#}~automagically~converted~to~a~DecoratedLogged~class}\\
+\mbox{~~~~"[Logged]"}\\
+\mbox{~~~~name=name}\\
+\mbox{}\\
+\mbox{c1=C1()~{\#}~C1~instance}\\
+\mbox{c2=C2()~{\#}~C2~instance}\\
+\mbox{}\\
+\mbox{{\#}{$<$}/example8.py{$>$}}
+\end{flushleft}\end{ttfamily}
+\end{quote}
+
+In this example the class \texttt{C2} has already a magic docstring. This means that
+\texttt{C2} has to be enhanced both from \texttt{Logged} and from \texttt{Decorated}.
+This is done by automagically creating a \texttt{DecoratedLogged} class
+decorator:
+\begin{verbatim}>>> from example8 import C1,C2,c1,c2
+<class C2[DecoratedLogged]> created\end{verbatim}
+
+The second line is printed because of the logging capabilities of \texttt{C2}.
+Moreover, since \texttt{C2} is decorated too, the following will work:
+\begin{verbatim}>>> assert C2.name() == 'C2'
+>>> assert c2.name() == 'C2' \end{verbatim}
+
+Idem for \texttt{C1}:
+\begin{verbatim}>>> assert C1.identity(1) == 1
+>>> assert c1.identity(1) == 1 \end{verbatim}
+
+
+%___________________________________________________________________________
+
+\hypertarget{the-implementation}{}
+\section*{The implementation}
+\pdfbookmark[0]{The implementation}{the-implementation}
+
+This part can be safely skipped, unless you are a \emph{really} curious and
+you want to know how the implementation works.
+
+The module is rather short (less than 150 lines if you skip comments and
+docstrings) but far from being trivial, since it is based on extensive
+usage of metaclass wizardry. Moreover,
+it invokes the \texttt{safetype} module to solve metaclass conflicts, and
+\texttt{safetype} contains 50 lines of \emph{really} deep metaclass wizardry.
+\begin{quote}
+\begin{figure}
+
+\includegraphics{decorators.ps}
+\end{figure}
+\end{quote}
+
+The main class-metaclass hierarchy is represented in the figure, where
+boxes denote classes and ovals denote metaclasses; instantiation is
+denoted by dashed green lines whereas inheritance is denoted by continuous
+blue lines.
+
+For instance, this is the Method Resolution Order for the \texttt{Decorated}
+metaclass:
+\begin{verbatim}>>> for i,c in enumerate(decorators.Decorated.__mro__):
+... print i,c,"[%s]" % type(c).__name__
+0 <class 'decorators.Decorated'> [MetaDecorator]
+1 <class 'decorators.ClassDecorator'> [MetaDecorator]
+2 <class 'safetype.safetype'> [type]
+3 <type 'type'> [type]
+4 <class 'decorators.Decorator'> [MetaDecorator]
+5 <type 'object'> [type]\end{verbatim}
+
+\texttt{Decorator} is the mother of all decorators. Its main purpose it to
+provide the \texttt{MetaDecorator}
+metaclass to all decorators.
+
+The \texttt{safetype} metaclass, imported from the \texttt{safetype} module,
+ensures that class decorators can generate classes without incurring
+in conflicts.
+
+Since class decorators are metaclasses,
+\texttt{MetaDecorator} is actually a meta-metaclass with respect to
+instances of decorated classes. For this reason if
+\begin{verbatim}>>> C=decorators.ClassDecorator('C',(),{})\end{verbatim}
+
+then
+\begin{verbatim}>>> C.__class__
+<class 'decorators.ClassDecorator'>\end{verbatim}
+
+but
+\begin{verbatim}>>> C.__metaclass__
+<class 'decorators.MetaDecorator'>\end{verbatim}
+
+since the \texttt{C.{\_}{\_}metaclass{\_}{\_}} attribute is inherited from \texttt{Decorator}.
+
+On the other hand, \texttt{MetaDecorator} is a simple metaclass with
+respect to instances of decorated methods.
+
+The implementation is relatively smart. Consider for instance the case of
+the \texttt{logged} example. In that example class \texttt{D} was a subclass
+of a tricked \texttt{object} class, enhanced by \texttt{ClassDecorator}. Moreover \texttt{D}
+had a \texttt{Logged} docstring. Therefore it should have been an instance of a
+\texttt{ClassDecoratorLogged} metaclass. But logged was
+a subclass of \texttt{ClassDecorator}, therefore it already had all the features
+of \texttt{ClassDecorator} and it would have been redundant to create
+\texttt{ClassDecoratorLogged}, when``Logged`` would have been enough.
+So \texttt{Logged} was used and \texttt{ClassDecoratorLogged} was never created.
+All this magic is in the \texttt{safetype.remove{\_}redundant(*classes)} function.
+
+The current implementation does not make any attempt of optimization and
+there may be alternative implementations faster or more memory efficient.
+At this experimental level I didn't care to explore about performances
+issues. Probably, they do not matter unless one has to decorate
+thousands or millions of functions and classes.
+
+Finally, a word about bugs. The \texttt{decorators} module is fairly sophisticated,
+therefore whereas I can guarantee that it passes my test suite (which involves
+{\~{ }}200 tests, most of them extracted from the documentation you are reading),
+I cannot guarantee that it is correct. If somebody finds a bug or an
+unexpected behavior, please let me know and I will fix it or document it.
+% References:
+
+
+%___________________________________________________________________________
+
+\hypertarget{module-decorators}{}
+\subsection*{Module \texttt{decorators}}
+\pdfbookmark[1]{Module decorators}{module-decorators}
+
+A module to implement pep318 (decorator syntax) via magic doctrings.
+For the full documentation see
+\href{http://www.phyast.pitt.edu/~micheles/python/decorators.html}{http://www.phyast.pitt.edu/{\~{ }}micheles/python/decorators.html} .
+
+
+%___________________________________________________________________________
+
+\hypertarget{id3}{}
+\subsubsection*{Metaclasses}
+\pdfbookmark[2]{Metaclasses}{id3}
+
+\texttt{metaclass ClassDecorator(type,Decorator):}
+\begin{quote}
+
+Metaclass callable with one or three arguments, having its calling
+syntax redefined by \texttt{MetaDecorator}.
+\end{quote}
+
+\texttt{metaclass Decorated(ClassDecorator):}
+\begin{quote}
+
+Metaclass which decorates the methods of its instances according
+to the docstrings. It redefines \texttt{{\_}{\_}str{\_}{\_}} on
+its instances and the default \texttt{{\_}{\_}str{\_}{\_}} on the instances of its
+instances.
+
+\texttt{{\_}{\_}str{\_}{\_}(cls):}
+\begin{quote}
+
+Redefine the printing representation of classes
+\end{quote}
+\end{quote}
+
+\texttt{metaclass safetype(type):}
+\begin{quote}
+
+Overrides the \texttt{{\_}{\_}new{\_}{\_}} method of the \texttt{type} metaclass, making the
+generation of classes conflict-proof.
+\end{quote}
+
+\texttt{metaclass MetaDecorator(type):}
+\begin{quote}
+
+Metaclass inducing a certain amount of magic on decorators:
+\newcounter{listcnt1}
+\begin{list}{\arabic{listcnt1}.}
+{
+\usecounter{listcnt1}
+\setlength{\rightmargin}{\leftmargin}
+}
+\item
+Each time a decorator is defined in any module, it is stored in
+MetaDecorator.dic and MetaDecorator.ls.
+
+\item
+If the (method) decorator has a 'get' method, a '{\_}{\_}get{\_}{\_}' method
+is automagically created as an alias to 'get'.
+
+\item
+Decorators calls are dispatched to the decorator {\_}call{\_}
+classmethod.
+
+\end{list}
+
+\texttt{{\_}{\_}call{\_}{\_}(dec,*args):}
+\begin{quote}
+
+This is the heart of the module. Infers the correct decorator class
+from \texttt{dec} and the docstring and creates the correct decorator object.
+Returns the original object if \texttt{dec} is the trivial \texttt{Decorator}
+class and no docstring is found.
+\end{quote}
+
+\texttt{{\_}{\_}init{\_}{\_}(dec,*args):}
+\begin{quote}
+
+Update the metaclass attributes \texttt{dic} and \texttt{ls};
+alias \texttt{get} to \texttt{{\_}{\_}get{\_}{\_}}.
+\end{quote}
+\end{quote}
+
+
+%___________________________________________________________________________
+
+\hypertarget{classes}{}
+\subsubsection*{Classes}
+\pdfbookmark[2]{Classes}{classes}
+
+\texttt{class UnknownDecoratorError(Exception):}
+\begin{quote}
+
+The name says it all.
+\end{quote}
+
+\texttt{class Decorator(object):}
+\begin{quote}
+
+Instance of MetaDecorator and mothers of all decorators. When called
+in the form \texttt{Decorator(obj)} with obj having a magic docstring, it returns
+a decorated object; otherwise it returns the original object.
+\end{quote}
+
+\texttt{class staticmethod(MethodDecorator):}
+\begin{quote}
+
+Decorator, converts a function in a staticmethod
+\end{quote}
+
+\texttt{class MethodDecorator(Decorator):}
+\begin{quote}
+
+Descriptor class callable with a function or a descriptor object
+as argument. It defines a default printing representation on method
+decorators objects and a default \texttt{get} method. All the rest is
+provided by the metaclass \texttt{MetaDecorator}.
+
+\texttt{get(self,obj,cls=None):}
+\begin{quote}
+
+aliased to {\_}{\_}get{\_}{\_} by the metaclass, to be overridden
+\end{quote}
+
+\texttt{{\_}{\_}str{\_}{\_}(self):}
+\begin{quote}
+
+Printing representation of kind {$<$}decoratorclass:functionname{$>$}
+\end{quote}
+
+\texttt{{\_}{\_}init{\_}{\_}(self,objfunc):}
+\begin{quote}
+
+objfunc is a decorator object or a function
+\end{quote}
+\end{quote}
+
+\texttt{class classmethod(MethodDecorator):}
+\begin{quote}
+
+Decorator, converts a function in a classmethod
+\end{quote}
+
+
+%___________________________________________________________________________
+
+\hypertarget{functions}{}
+\subsubsection*{Functions}
+\pdfbookmark[2]{Functions}{functions}
+
+\texttt{enhance{\_}classes(magicstring='[ClassDecorator]'):}
+\begin{quote}
+
+Enhances all the classes in the caller module with a metaclass
+built from the given magicstring.
+\end{quote}
+
+\texttt{remove{\_}redundant(bases):}
+\begin{quote}
+
+Returns a tuple of non-redundant base classes.
+Given a sequence of base classes, a class is redundant if it is duplicated
+or if it is implied by the others, i.e. it is an ancestor of at least one
+of the other classes. For instance, if \texttt{C} is derived from \texttt{B}, in the
+sequence \texttt{C,B} the class \texttt{B} is redundant, since all its features are
+already provided by \texttt{C}. Therefore \texttt{B}
+is removed and \texttt{remove{\_}redundant} returns the tuple \texttt{(C,)}:
+\begin{verbatim}>>> class B(object): pass
+...
+>>> class C(B): pass
+...
+>>> import safetype; safetype.remove_redundant([C,B])
+(<class 'C'>,)\end{verbatim}
+\end{quote}
+
+\texttt{compose(dclasses,*defaultclasses):}
+\begin{quote}
+
+Retrieves or creates a decorator for a tuple of decorators. If
+defaults decorators are given, they get the precedence. It removes
+redundant classes.
+\end{quote}
+
+\texttt{instance{\_}str(self):}
+\begin{quote}
+
+Redefines the printing representation of simple objects
+\end{quote}
+
+\texttt{getdec(magicstring="[Decorator]"):}
+\begin{quote}
+
+Given a magicstring describing a valid decorator name, returns the list
+of its subclasses. By default returns the full list of decorators.
+\end{quote}
+
+\texttt{decorate(objdict):}
+\begin{quote}
+
+Takes an object with a dictionary and decorates all its functions
+and classes according to their docstrings.
+\end{quote}
+
+\texttt{decorators{\_}in(docstring):}
+\begin{quote}
+
+Takes a docstring and returns a (possibly empty) tuple of decorator
+classes.
+\end{quote}
+
+\end{document}
+
diff --git a/pypers/pep318/decorators.txt b/pypers/pep318/decorators.txt
new file mode 100755
index 0000000..fb7f321
--- /dev/null
+++ b/pypers/pep318/decorators.txt
@@ -0,0 +1,1413 @@
+Implementing PEP 318 (decorators)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+:Module: decorators
+:Version: 0.5
+:Author: Michele Simionato
+:e-mail: MicheleSimionato@libero.it
+:Licence: Python-like
+:Date: September 2003
+:Disclaimer: This is experimental code. Use it at your own risk!
+
+.. contents::
+
+Using decorators
+=========================================================================
+
+Having plenty of free time in these days, I have finished an old
+project of mine, the implementation of `PEP 318`_ in pure Python
+(2.3).
+
+Here is the rationale:
+
+* some kind of decorator syntax is scheduled to go in Python 2.4,
+ therefore it is interesting to play with the concept;
+
+* it is nice to play with decorators now, without having to
+ wait for one year or so;
+
+* it is much easier to experiment with a pure Python implementation
+ than with a C implementation;
+
+* the implementation can be seen as an exercise on modern Python
+ programming and may be valuable to people wanting to study the most
+ advanced new constructs in Python (descriptors_, metaclasses_,
+ `cooperative methods`_, etc.)
+
+Basics
+--------------------------------------------------------------------
+
+PEP 318 has the goal of providing a nice syntactic sugar for expressions like
+
+ ::
+
+ def identity(x):
+ return x
+ identity=staticmethod(identity)
+
+or
+
+ ::
+
+ def name(cls):
+ return cls.__name__
+ name=classmethod(name)
+
+which are pretty verbose. It is clear that having new syntax (as
+for instance the proposed square bracket notation)
+
+ ::
+
+ def identity(x)[staticmethod]:
+ return x
+
+ def name(cls)[classmethod]:
+ return cls.__name__
+
+involves changing the grammar and modifying the interpreter at the
+C level. This means a lot of work. Fortunately, it is possible to
+have the same effect without changing the Python grammar.
+The idea is to use magic docstrings like this:
+
+ ::
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+The implementation is able to recognize such magic docstrings
+and automatically converts methods with magic docstrings in
+method decorators.
+
+Decorators are nothing else than a sophisticated kind of wrappers.
+The ``decorators`` module provides support both for method decorators
+and class decorators:
+
++ *Method decorators* are classes taking a single function as input and
+ producing a descriptor object as output. ``staticmethod`` and
+ ``classmethod`` are two examples of already existing
+ method decorators (actually my implementation rewrites them).
+ A knowledge of descriptors [1]_ is not needed in order to use the ``decorator``
+ module; however it is welcomed for advanced users wanting to implement
+ custom method decorators.
+
++ *Class decorators* are metaclasses taking a class as imput and returning
+ a decorated class as output. A good understanding of metaclasses is needed
+ in order to be able to write custom class decorators, but no knowledge
+ at all is required in order to use the pre-defined class decorators
+ provided by the module.
+
+Notice that properties are not decorators according to my definitions,
+since they take four functions as input, ``get, set, del_`` and ``doc``.
+Whereas the decorators concept could be generalized to the case of
+multiple inputs, I don't see the need for such complication, so
+properties are not implemented as method decorators. Moreover, I
+think it is much better to use them trough a class decorator.
+
+Finally, the module is meant to be extensible; so one could
+define new kind of decorators. For instance, the original version of
+the module also had the concept of module decorators; however I have cut
+down that part in order to keep the documentation short.
+
+Admittedly, the implementation
+is not for the faint of heart, nevertheless I have tried to make the
+basic usage easy and simple to understand.
+
+.. [1] Descriptors are objects with a ``__get__`` method; they are quite
+ sophisticated, but fortunately they have been wonderfully explained by
+ Raymond Hettinger already, so I am allowed to skip on this point ;).
+
+Decorating methods
+------------------------------------------------------------------------
+
+Before talking about the implementation details, I will show
+how the ``decorators`` module works in practice. The simplest and safest
+usage is by means of the ``decorators.decorator()`` function, which
+takes an object (a function or a class) and checks its docstring: if
+a magic docstring is found, it returns a decorated version of the object,
+otherwise it returns the original object. Using ``decorators.decorator()``
+is simple but verbose, so magic shortcuts will be discussed in the next
+sections.
+
+Here, let me give an example, showing that method decorators work both for
+`new style classes and old style classes`_:
+
+ ::
+
+ #<example1.py>
+
+ import decorators
+
+ def do_nothing(self):
+ "No magic docstring here"
+ dec_do_nothing=decorators.decorator(do_nothing)
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+ dec_identity=decorators.decorator(identity)
+
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+ dec_name=decorators.decorator(name)
+
+ class OldStyle:
+ do_nothing=dec_do_nothing
+ identity=dec_identity
+
+ class NewStyle(object):
+ name=dec_name
+
+ o=OldStyle() # creates an old style instance
+ n=NewStyle() # creates a new style instance
+
+ #</example1.py>
+
+>>> from example1 import * # for testing purposes
+
+In this example, both ``dec_identity`` and ``dec_name`` are decorator objects,
+i.e. descriptors modifiying the attribute access. It is easy to recognize
+decorators objects in the interpreter, since they have a re-defined
+printing representation:
+
+>>> print dec_identity
+<staticmethod:identity>
+>>> print dec_name
+<classmethod:name>
+
+On the other hand, ``do_nothing`` does not have a magic
+docstring, therefore it is *not* converted to a decorator object:
+actually, in this case ``decorator`` returns ``None``:
+
+
+>>> print dec_do_nothing
+None
+
+This is useful since one can tests if an object is a decorator
+object with idioms like
+
+ ``if decorator(obj): do_something()``
+
+and one can convert generic objects with the idiom
+
+ ``dec_obj=decorator(obj) or object``
+
+which returns the original object if no magic docstring is found.
+
+
+Let me check that ``dec_ identity`` works correctly as a staticmethod,
+
+>>> OldStyle.identity(1) # called from the class
+1
+>>> o.identity(1) # called from the instance
+1
+
+whereas ``dec_name`` works as a classmethod:
+
+>>> NewStyle.name() # called from the class
+'NewStyle'
+>>> n.name() # called from the instance
+'NewStyle'
+
+Notice that, I have re-implemented the built-in
+``staticmethod`` and ``classmethod``, so
+
+>>> isinstance(dec_identity,staticmethod)
+False
+
+and
+
+>>> isinstance(dec_name,classmethod)
+False
+
+It is possible to recognize method decorators since they provides
+a couple of special attributes:
+
+- ``__func__``: returning the function from which they originated:
+
+ >>> assert dec_identity.__func__ is identity
+ >>> assert dec_name.__func__ is name
+
+- ``__klass__``: returning the class where they where defined:
+
+ >>> dec_identity.__klass__
+ <class 'safetype.?'>
+
+The question mark here means that the definition class is unknown.
+The ``__klass__`` attribute can be set by hand or automatically
+with the trick explained in the next section.
+
+Decorating classes
+----------------------------------------------------------------------
+
+The problem with the approach just described
+is that it does not present any significant advantage over
+the already existing mechanism. A real step forward would be to
+have classes with the ability of automatically decorating their
+methods according to the docstrings.
+This sounds a bit of magic, but actually can be done very simply
+by adding to the class a docstring starting with "[Decorated]"
+and by decorating the class.
+Here is an example:
+
+ ::
+
+ #<example2.py>
+
+ from decorators import decorator
+ from example1 import do_nothing,identity,name
+
+ class B(object):
+ "This is a regular class"
+
+ B=decorator(B) or B # return the original B
+
+ class C(B):
+ "[Decorated]"
+ do_nothing=do_nothing
+ identity=identity
+ class Inner: # old style class
+ "[Decorated]" # required docstring
+ name=name
+
+ C=decorator(C) # regenerate the class converting methods in decorators
+ c=C()
+
+ #</example2.py>
+
+Under the hood ``decorators.decorator()`` recognizes the class level
+magic docstring "[Decorated]" and creates an instance of the
+``decorators.Decorated`` metaclass.
+Internally the metaclass invokes ``decorators.decorator()``
+on the methods of its instances: this is why they becomes decorated
+if a suitable docstring is found. Moreover, it decorates inner classes,
+if a suitable docstring is found, and it works recursively.
+
+Here is the testing:
+
+>>> from example2 import *
+>>> assert C.identity(1) == 1
+>>> assert C.Inner.name() == 'Inner'
+>>> assert c.identity(1) == 1
+>>> assert c.Inner.name() == 'Inner'
+
+Notice that adding ``identity`` after the class creation with the syntax
+``C.identity=identity`` would not work;
+``C.identity=decorators.decorator(identity)`` is required:
+
+>>> C.identity=decorators.decorator(identity)
+>>> C.identity(1) # it works
+1
+
+If a class misses the magic docstring, nothing happens:
+
+>>> B # returns the original B
+<class 'example2.B'>
+
+The mechanism works for old style classes too,
+since the metaclass automagically converts the old style classes in a
+new style one:
+
+>>> type(C.Inner) # C.Inner is an instance of decorator.Decorated
+<class 'decorators.Decorated'>
+
+The enhancement provided by the metaclass includes a new default
+printing representation for both the class
+
+>>> print C # returns the name of D and of its metaclass
+<class C[Decorated]>
+
+and its instances:
+
+>>> print c
+<C instance>
+
+On the other hand, if a custom printing representation is already
+defined, the metaclass takes it without any change.
+
+One can even forget the docstring in subclasses of decorated
+classes, since metaclasses are inherited:
+
+>>> class D(C):
+... def name(cls):
+... "[classmethod]"
+... return cls.__name__
+>>> print D.name()
+D
+
+Decorating whole classes presents another advantage: the decorated methods know
+the class where they were defined via the special attribute ``__klass__``:
+
+>>> D.__dict__['name'].__klass__ # the class where 'name' is defined
+<class 'D'>
+
+This is useful for introspection and debugging purposes.
+
+Adding magic
+----------------------------------------------------------------------------
+
+The problem of the previous approach is that one must explicitely
+decorate the classes by hand, by invoking ``decorators.decorator()``
+each time. However, it is possible to add more magic
+and to decorate all the classes automatically.
+It is as easy as writing ``decorators.enhance_classes()``
+on top of you module. Then all methods in all classes with a magic docstring
+will be checked for magic docstrings and automagically decorated if needed.
+For instance, the previous example would be written
+
+ ::
+
+ #<example3.py>
+
+ import decorators; decorators.enhance_classes()
+
+ class C:
+ "[Decorated]" # magic docstring here
+ def do_nothing(self):
+ "No magic docstring here"
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ class D(object):
+ "Undecorated" # no magic docstring here
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+ c=C(); d=D()
+
+ #</example3.py>
+
+``C`` has a ``[Decorated]`` docstring, so its methods
+are automatically decorated:
+
+>>> from example3 import *
+>>> assert c.do_nothing() is None
+>>> assert C.identity(1) == 1
+>>> assert c.identity(1) == 1
+
+On the other hand, since ``D`` misses a magic docstring,
+its ``name`` method is not decorated:
+
+>>> hasattr(D.__dict__['name'],'__func__') # not a decorator
+False
+
+Since ``D.name`` is a regular method and not a classmethod, ``D.name()``
+gives an error:
+
+>>> D.name()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method name() must be called with D instance as first argument (got nothing instead)
+
+Under the hood, the magic works by enhancing the ``object`` class
+of the module with a ``decorators.ClassDecorator`` metaclass:
+
+>>> import example4
+>>> type(example4.object)
+<class 'decorators.ClassDecorator'>
+
+Notice that for safety reasons the enhancement is only on the module
+``object`` class, not on the ``__builtin__.object`` class. The dangers of
+adding too much magic are discussed in the `Diving into magic`_ section.
+
+Defining method decorators
+-----------------------------------------------------------------------
+
+The ``decorators`` module contains two predefinite method decorators,
+``staticmethod`` and ``classmethod``, which emulate the built-ins
+with the same names. However, it is possible to write your own
+custom decorators. The ``decorators.MethodDecorator`` class which is here
+exactly for that purpose.
+
+Custom decorators are expected to be implemented by subclassing
+``MethodDecorator`` and by overriding its ``get`` method. The
+``get`` method automagically induces a ``__get__`` method, turning the
+class in a descriptor. The machinery is needed since ``__get__`` cannot
+be made cooperative using the standard ``super`` mechanism because
+there would be a confusion between ``super.__get__`` and the decorator
+``__get__``. This is a bit tricky, but the causal programmer is not
+expected to write custom decorators, and actually I don't want to make
+the access to decorators *too* easy, since they are potentially dangerous.
+
+In order to give a simple example, let me show the implementation
+of a ``chattymethod`` that prints a message when it is called:
+
+ ::
+
+ #<customdec.py>
+
+ from decorators import *
+
+ class chattymethod(MethodDecorator):
+ logfile=sys.stdout # default
+ def get(self,obj,cls=None): # same signature as __get__
+ self.logfile.write('calling %s from %s\n' % (self,obj or cls))
+ return super(chattymethod,self).get(obj,cls)
+
+ #</customdec.py>
+
+Notice the usage of the ``super().get`` trick. This guarantees that
+``chattymethod`` will play well with other decorators (i.e. it
+can be nicely composed via multiple inheritance). The point will
+be fully discussed in the section on composing decorators.
+
+Here is an example of usage:
+
+>>> import customdec # adds chattymethod to the list of known decorators
+>>> customdec.enhance_classes() # automagically enhances classes
+>>> class C:
+... " [Decorated] "
+... def f(self):
+... """
+... [ chattymethod ]
+... """
+>>> c=C()
+>>> c.f()
+calling <chattymethod:f> from <C instance>
+
+By the way, this shows that one can safely add whitespaces (including
+newlines) to the magic docstring: they are simply ignored.
+
+One can check that the syntax ``C.f(c)`` works too:
+
+>>> C.f(c)
+calling <chattymethod:f> from <class C[Decorated]>
+
+A tricky point of the decorators mechanism is the issue of parameter passing.
+In comp.lang.python there was the proposal of allowing explicit parameter
+passing to decorators, with a syntax of kind
+
+ ::
+
+ def f(self)[chattymethod(logfile=file('file1.log','w'))]
+
+In my view, there are too many parenthesis in this syntax, and it
+becomes rapidly unreadable. Moreover, it complicates the implementation
+without any real benefit, so the ``decorators`` module does not allow
+this kind of parameter passings. There are however viable
+workarounds, so you should not miss the syntax.
+
+A simple minded solution is to change the defaults by hand:
+
+>>> from customdec import chattymethod,decorator
+>>> chattymethod.logfile=file('file.log','w')
+>>> def g(self):
+... "[chattymethod]"
+>>> C.g=decorator(g)
+>>> c.g() # will print a message on file.log
+
+This approach has the drawback that chattymethods created before changing
+the logfile will also print to the new logfile, if invoked after the
+change. Therefore
+
+>>> c.f()
+
+will print a message to ``file.log`` too, and not to standard output.
+Here is the confirmation:
+
+>>> chattymethod.logfile.close()
+>>> print file('file.log').read().rstrip()
+calling <chattymethod:g> from <C instance>
+calling <chattymethod:f> from <C instance>
+
+A better solution is to pass
+parameters to method decorators as function attributes: then the function
+attributes can be converted to attributes of the decorator
+in the ``__init__`` method. Here is an example:
+
+ ::
+
+ #<customdec.py>
+
+ class chattymethod2(chattymethod):
+ logfile=sys.stdout # default
+ def __init__(self,objfunc):
+ super(chattymethod2,self).__init__(objfunc)
+ logfile=getattr(self.__func__,'logfile',None)
+ if logfile: self.logfile=logfile
+
+ #</customdec.py>
+
+Notice that the ``__init__`` method has the signature
+``__init__(self,objfunc)``, where the ``objfunc`` object is a
+decorator object or the function to be converted in the decorator
+object, and that it is cooperative.
+This is the suggested way of overriding ``__init__``.
+
+Here is the testing:
+
+ ::
+
+ #<chatty2.py>
+
+ import customdec; customdec.enhance_classes()
+
+ # sets the log files
+ log1=file('file1.log','w')
+ log2=file('file2.log','w')
+
+ class C:
+ "[Decorated]"
+ def f(self):
+ "[chattymethod2]"
+ f.logfile=log1 # function attribute
+ def g(self):
+ "[chattymethod2]"
+ g.logfile=log2 # function attribute
+
+ assert C.__dict__['f'].logfile is log1 # check the conversion
+ assert C.__dict__['g'].logfile is log2 # function attr. -> decorator attr.
+
+ c=C() # C instantiation
+
+ c.f() # print a message in file1.log
+ c.g() # print a message in file2.log
+
+ log1.close(); log2.close() # finally
+
+ #</chatty2.py>
+
+Let me check the contents of the log files:
+
+>>> import chatty2
+>>> print file('file1.log').read().rstrip()
+calling <chattymethod2:f> from <C instance>
+>>> print file('file2.log').read().rstrip()
+calling <chattymethod2:g> from <C instance>
+
+``chattymethod`` is the poor man version of ``tracedmethod``, a
+sophisticated decorator for tracing methods.
+Here is the code, given for pedagogical purposes; the lazy reader can
+skip it and go directly to the usage section.
+
+ ::
+
+ #<customdec.py>
+
+ class tracedmethod(MethodDecorator):
+ "Descriptor class, converts a method in a traced method"
+ indent=0; output=sys.stdout # defaults
+
+ def __init__(self,objfunc):
+ super(tracedmethod,self).__init__(objfunc)
+ self.funcname=self.__func__.__name__
+ output=getattr(self.__func__,'output',None)
+ if output: self.output=output # func.attr. -> dec.attr.
+
+ def get(self,obj,cls):
+ clsname=self.__klass__.__name__ # definition clas
+ def tracedmeth(obj,*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write("%sCalling '%s.%s' with arguments " %
+ (i,clsname,self.funcname))
+ self.output.write("%s%s ...\n" % (obj or '',str(args)+str(kw)))
+ res=super(tracedmethod,self).get(obj,cls)(*args,**kw)
+ self.output.write("%s'%s.%s' called with result: %s\n"
+ % (i,clsname,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return tracedmeth.__get__(obj,cls) # method wrapper
+
+ #</customdec.py>
+
+``tracedmethod.get`` returns a method wrapper object, so it is
+possible to use ``im_func`` to retrieve the internal function
+``tracedmeth``:
+
+>>> class C:
+... "[Decorated]"
+... def f(self):
+... "[tracedmethod]"
+>>> c=C(); c.f()
+Calling 'C.f' with arguments <C instance>(){} ...
+'C.f' called with result: None
+>>> c.f.im_func.__name__
+'tracedmeth'
+
+As soon as the ``tracedmethod`` module is loaded, the ``tracedmethod`` class
+is added to the list of know decorators, so one should use the
+"[tracedmethod]" docstring and not something like
+"[customdec.tracedmethod]".
+
+Here is a less trivial example of usage, writing in a log file the
+internal working of a recursive function:
+
+ ::
+
+ #<example9.py>
+
+ import customdec; customdec.enhance_classes()
+
+ logfile=file('file3.log','w')
+
+ class C(object):
+ "[Decorated]"
+ def fact(self,n):
+ "[tracedmethod] The good old factorial."
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact.output=logfile
+
+ C().fact(2) # write a message to logfile
+
+ logfile.close()
+
+ #</example9.py>
+
+Here is the content of ``file3.log``:
+
+>>> import example9 # creates file3.log
+>>> print file('file3.log').read().rstrip()
+Calling 'C.fact' with arguments <C instance>(2,){} ...
+ Calling 'C.fact' with arguments <C instance>(1,){} ...
+ Calling 'C.fact' with arguments <C instance>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+
+Defining class decorators
+-----------------------------------------------------------------------
+
+PEP 318 proposes to decorate methods by using descriptors; it is
+quite natural to extend this idea and to decorate classes by using
+class decorators implemented as metaclasses. We already saw a couple of
+class decorator at work, the metaclass ``ClassDecorator``, which gives
+to its instances the ability to interpret class level magic docstrings, and
+its subclass ``Decorated``, which converts functions in method decorators
+if suitable docstrings are found.
+
+To define a custom class decorator is easy: one defines a custom metaclass
+as usual, with the only difference of deriving from ``ClassDecorator`` instead
+of deriving from ``type``.
+
+To understand how this works in practice, let me
+show how to add logging capabilities to a given class. The first
+step is to define a suitable class decorator, such as the following:
+
+ ::
+
+ #<customdec.py>
+
+ class Logged(ClassDecorator):
+ output=sys.stdout
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print >> cls.output,"%s created" % cls
+
+ #</customdec.py>
+
+``Logged`` is derived by the metaclass ``ClassDecorator``,
+which provides a certain amount of magic under the hood (in particular
+its printing representation and its calling syntax are redefined by its
+(meta-)metaclass ``MetaDecorator``).
+Logging capabilities can be added to a class
+by simply using the magic docstring syntax:
+
+ ::
+
+ #<logged.py>
+
+ import customdec; customdec.enhance_classes()
+
+ class D(object): # will print a message at D creation
+ "[Logged]"
+
+ #</logged.py>
+
+>>> import logged
+<class 'logged.D'> created
+
+Notice that the printing representation of ``D`` involves the name
+of ``D`` preceded by the name of its metaclass, which in this case
+is ``Logged``
+
+Each time an instance of ``Logged`` is created, a similar message is printed:
+
+>>> class E(logged.D):
+... pass
+<class 'E'> created
+
+Notice that ``E`` does not have any magic docstring
+
+>>> E.__doc__ # no docstring
+
+but still it inherits its magic from ``D``.
+
+Another simple example of class decorator is the following metaclass
+which modifies the docstrings of the methods of its instances,
+by magically inducing tracing capabilities on them:
+
+ ::
+
+ #<customdec.py>
+
+ from types import FunctionType
+
+ class Traced(Decorated):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType) and name!='__str__':
+ # cannot trace __str__, since it is invoked by
+ # tracedmethod and would generate infinite recursion
+ func.__doc__="[tracedmethod] " + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d) # decorates the methods
+
+ #</customdec.py>
+
+Here is an example of usage:
+
+>>> class C(object):
+... """[Traced] The class decorator adds the magic docstring
+... '[tracedmethod]' to f1 and f2, which are then converted
+... in method decorator objects."""
+... def f1(self): pass
+... def f2(self): pass
+...
+>>> type(C)
+<class 'customdec.Traced'>
+>>> c=C()
+>>> c.f1()
+Calling 'C.f1' with arguments <C instance>(){} ...
+'C.f1' called with result: None
+>>> c.f2()
+Calling 'C.f2' with arguments <C instance>(){} ...
+'C.f2' called with result: None
+
+By default, the decorators module only decorates classes with a magic
+docstring (and they subclasses, even without magic docstrings).
+If all the classes of your module have the same magic docstring,
+it makes sense to decorate them all
+with a single command. It is enough to use ``decorators.enhance_classes()``
+with a magic docstring corresponding to a class decorator as argument,
+as in this example:
+
+ ::
+
+ #<example7.py>
+
+ from example2 import identity,name
+ import inspect, decorators; decorators.enhance_classes("[Decorated]")
+
+ class C1(object): # automagically converted to a decorated class
+ identity=identity
+
+ class C2: # automagically converted to a decorated class
+ name=name
+
+ c1=C1() # C1 instance
+ c2=C2() # C2 instance
+
+ #</example7.py>
+
+The magic works both for new style classes such as ``C1``
+
+>>> from example7 import C1,c1
+>>> assert C1.identity(1) == 1
+>>> assert c1.identity(1) == 1
+
+and old style classes such as ``C2`` by implicitly converting them
+to new style classes:
+
+>>> from example7 import C2,c2
+>>> assert C2.name() == 'C2'
+>>> assert c2.name() == 'C2'
+
+Composing decorators
+---------------------------------------------------------------------
+
+Decorators can be composed by using magic docstrings with comma-separated
+decorator names. For instance, you can trace a classmethod:
+
+ ::
+
+ #<example6.py>
+
+ "How to trace a class method"
+
+ import customdec; customdec.enhance_classes()
+
+ class C(object):
+ "[Decorated]"
+ def fact(cls,n): # a traced classmethod
+ "[classmethod,tracedmethod]"
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+ #</example6.py>
+
+Here is the testing:
+
+>>> from example6 import C
+>>> C.fact(2)
+Calling 'C.fact' with arguments <class C[Decorated]>(2,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(1,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+
+You may easily check that calling ``C().fact`` will work too.
+
+Under the hood the syntax
+
+ ::
+
+ [classmethod,tracedmethod]
+
+generates a ``classmethodtracedmethod`` class obtained via
+multiple inheritance:
+
+>>> type(C.__dict__['fact'])
+<class 'safetype.classmethodtracedmethod'>
+
+Notice that the order *does* matter and using the docstring
+"[tracedmethod,classmethod]" will not work:
+
+>>> class D:
+... "[Decorated]"
+... def f(cls):
+... "[tracedmethod,classmethod]"
+>>> D.f()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with D instance as first argument (got nothing instead)
+
+The problem here is that ``tracedmethod.get`` returns a method-wrapper object
+which expects a D instance as first argument whereas it gets ``None`` since
+it is called from the class. On the other hand,
+
+>>> D().f()
+Calling 'D.f' with arguments <D instance>(){} ...
+'D.f' called with result: None
+
+will work. When ``classmethod`` precedes ``tracedmethod``, then
+``classmethod`` passes to ``tracedmeth`` a non-empty first argument,
+i.e. the calling class, even when called from the instance:
+
+>>> C().fact(2)
+Calling 'C.fact' with arguments <class C[Decorated]>(2,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(1,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+
+If we try to trace a staticmethod, we will get a different error with
+the order "tracedmethod, staticmethod":
+
+>>> class F(object):
+... "[Decorated]"
+... def fact(n):
+... "[tracedmethod,staticmethod]"
+... if n==0: return 1
+... else: return n*F.fact(n-1)
+>>> F.fact(2)
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with F instance as first argument (got int instance instead)
+
+The message is self-explanatory.
+
+On the other hand, composing the decorators in the order
+"[tracedmethod,staticmethod]" will work just fine.
+
+It is possible to compose class decorators just as method decorators,
+by using the docstring syntax: for instance we may create a class
+which is both ``Decorated`` and ``Logged`` and by trivially writing
+
+>>> class C:
+... "[Decorated,Logged]"
+... def f():
+... "[staticmethod]"
+... return 'it works!'
+<class C[DecoratedLogged]> created
+>>> C().f()
+'it works!'
+
+Diving into magic
+-----------------------------------------------------------------------
+
+If you never use metaclasses, this part can be safely skipped. On the
+other hand, if you are a metaclass user, you *must* read this section
+in order to keep your code working.
+
+The ``decorators`` module provide a ``ClassDecorator`` metaclass which
+converts a regular (both old style or new style) class in a class with
+the ability to recognize magic docstrings. Under the hood, the
+``decorators.enhance_classes()`` trick works by decorating the
+``object`` class with ``decorators.ClassDecorator`` and by setting
+the custom metaclass to ``decorators.ClassDecorator`` and it is
+equivalent to
+
+ ::
+
+ import decorators
+ object=decorators.ClassDecorator(object) # decorates new style classes
+ __metaclass__= decorators.ClassDecorator # decorates old style classes
+
+If you want the magic to work only for new style classes only, you may
+forget the second line; if you want the magic to work for old style
+classes only, you may forget the first line.
+
+The ``decorators.enhance_classes("[SomeClassDec]")`` syntax looks at the
+magic docstring and executes something like
+
+ ::
+
+ import decorators
+ object=decorators.SomeClassDec(object) # decorates all new style classes
+ __metaclass__= decorators.SomeClassDec # decorates all old style classes
+
+The problem with the ``enhance_classes()`` syntaxes is that it is
+not 100% safe under metaclass conflicts. In order to explain the issue,
+let me give an example.
+
+Suppose we enhance the ``object`` class in the interpreter namespace:
+
+>>> import decorators; decorators.enhance_classes()
+
+making it an instance of ``ClassDecorator``:
+
+>>> object.__class__
+<class 'decorators.ClassDecorator'>
+
+Now, if we naively create a custom metaclass ``M``:
+
+>>> class M(type):
+... "Some non-trivial code here..."
+
+and we try to use it to enhance a new style class ``NwithM``, we will get a
+conflict:
+
+>>> class NwithM(object): __metaclass__=M # does not work!
+...
+Traceback (most recent call last):
+ ...
+TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+
+The problem is that the previous line tries to create a class ``NwithM``
+which should have both metaclasses ``ClassDecorator`` and ``M``:
+a conflict follows.
+
+Fortunately, the decorators module imports the ``type`` metaclass from
+my ``safetype`` module just to avoid this kind of problems. If we
+derive ``M`` from ``decorators.type`` (which is really ``safetype.type``)
+the conflict is automagically avoided:
+
+>>> class M(decorators.type):
+... "This metaclass is conflict-proof"
+>>> class NwithM(object): # it works!
+... __metaclass__=M
+
+The reason why the conflict is avoided is that the ``safetype`` module
+(which makes use of really *deep* metaclass magic) automatically
+creates the composed class ``MClassDecorator`` by multiply inheriting
+from ``M`` and from ``ClassDecorator``. Then, ``NwithM`` can be safely
+created as an instance of ``safetype.MClassDecorator``:
+
+>>> type(NwithM)
+<class 'safetype.MClassDecorator'>
+
+The situation with old style classes is worse since
+apparently
+
+>>> class OwithM: # old style class with metaclass M
+... __metaclass__=M
+... def sm():
+... "[staticmethod]"
+
+gives no error, but actually ``M`` overrides
+``ClassDecorator``, so ``OwithM`` will not recognize magic docstrings:
+
+>>> type(OwithM)
+<class 'M'>
+>>> OwithM.sm()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with OwithM instance as first argument (got nothing instead)
+
+The simpler solution is to convert ``OwithM`` in a new style class:
+
+>>> class NwithM(OwithM,object):
+... __metaclass__=M
+... def sm():
+... "[staticmethod]"
+>>> type(NwithM)
+<class 'safetype.MClassDecorator'>
+
+Now ``NwithM`` is not decorated since it does miss a magic docstring, but
+it provides the ability to recognizing magic docstrings, so ``NwithM``
+subclasses with a "[Decorated]" docstring will be decorated:
+
+>>> class E(NwithM):
+... "[Decorated]"
+... def cm(cls):
+... "[classmethod]"
+... print '.cm() called from',cls
+
+>>> E.cm() # it works
+.cm() called from <class E[MClassDecoratorDecorated]>
+
+Notice that ``sm`` was defined in ``NwithM``, the undecorated class: therefore
+it is not decorated:
+
+>>> E.sm() # correctly, does not work
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with E instance as first argument (got nothing instead)
+
+The error message says that ``sm`` is an unbound method and not a
+static method.
+
+It is possible to go even deeper in **black** magic, and to decorate all
+the new style classes in *all* modules, by decorating the
+``__builtin__.object``. Still, naively redefining the ``__builtin__object``
+class is risky, since it will induce metaclass conflicts in other modules
+using metaclasses. In other words, it will work only if you import modules
+not using metaclasses, or modules using metaclasses safely, i.e. modules
+taking care of possible conflicts by using ``safetype.type`` as base metaclass.
+If you really enjoy black magic, you may solve the problem by
+redefining the ``__builtin__.type`` as ``safetype.type``.
+The ``decorators`` module does not go so deep in dark magic, but still
+there are cases where you may want to do it. In these cases you must be
+explicit and redefine the builtins by hand, without help from the
+module. For instance, one of my original motivation for the usage
+of metaclasses/class decorators was to use them for debugging purposes.
+For instance, I wanted to trace the execution of methods in
+complicate inheritance hierarchies, *without changing the source code*.
+For simple situations, i.e. in absence of inheritance and of pre-existing
+metaclasses, the function ``import_with_metaclass`` discussed in the
+`first paper on metaclasses`_ written in collaboration with David Mertz, works
+fine but in general the implementation of a working ``import_with_metaclass``
+is cumbersome. For debugging purposes, the quick and dirty way can be a
+good enough way, so let me show how we can redefine the builtins ``object`` and
+``type`` *before* importing the module, in such a way to enhance *all*
+its classes with tracing capabilities.
+
+Let me start from a module using an unsafe metaclass ``M``, such that it
+cannot be traced trivially by decorating its classes *after* the import;
+moreover there is an inheritance hierarchy, such that it cannot be
+traced correctly by naively decorating all the classes one after the
+other (unless one modifies the original source code, but this forbidden
+by the rules of the game ;)
+
+ ::
+
+ #<tracing.py>
+
+ """
+ This is a pre-existing module not using decorators but using multiple
+ inheritance and unsafe metaclasses. We want to trace it for debugging
+ purposes.
+ """
+
+ class M(type):
+ "There should be some non-trivial code here"
+
+ class B(object):
+ def __init__(self):
+ super(B,self).__init__()
+
+ class D(object):
+ __metaclass__=M
+ def __init__(self):
+ super(D,self).__init__()
+
+ class E(B,D):
+ def __init__(self):
+ super(E,self).__init__()
+
+ #</tracing.py>
+
+Everything works is we modify the builtins before importing the module:
+
+>>> import __builtin__
+>>> __object__=__builtin__.object # the original 'object' class
+>>> __builtin__.object=customdec.Traced('tracedobject',(),{})
+>>> __builtin__.type=customdec.type # a safe 'type' class
+
+Now, when we import the module, all the classes ``M``, ``B``, ``D`` and ``E``
+will be created starting for the tricked builtins, so they will be traced
+and safe under conflicts. For instance, let me show that ``E`` is created
+with a conflict safe ``MTraced`` metaclass:
+
+>>> from tracing import E
+>>> print E
+<class E[MTraced]>
+
+This shows that the ``__init__`` methods are traced indeed and shows the
+Method Resolution Order:
+
+>>> e=E()
+Calling 'E.__init__' with arguments <E instance>(){} ...
+ Calling 'B.__init__' with arguments <E instance>(){} ...
+ Calling 'D.__init__' with arguments <E instance>(){} ...
+ 'D.__init__' called with result: None
+ 'B.__init__' called with result: None
+'E.__init__' called with result: None
+
+This works, indeed. At the end, one should not forget to restore
+the standard builtins, otherwise it will trace *all* the classes
+created thereafter.
+
+>>> __builtin__.object=__object__ # restore the __builtin__
+>>> __builtin__.type=decorators.__type__ # restore the __builtin__
+
+At the end, I will notice that it is possible to solve the problem more
+nicely, without redefining the builtins, but I will discuss the solution
+elsewhere ;)
+
+Advanced usage
+---------------------------------------------------------------------------
+
+Whereas the average programmer is expected to use the ``decorator()``
+and ``enhance_classes()`` functions only, the ``decorators`` module provides
+facilities which may be useful to the advanced programmer.
+
+The simplest is an utility function which retrieves the list of
+recognized decorators, ``decorators.getdec()``. The precise syntax is
+``decorators.getdec(docstring)``, where ``docstring``
+is a magic docstring, i.e. a bracketed comma-separated list
+of decorator names. For instance ``decorators.getdec('[MethodDecorator]')``
+gives the list of all subclasses of ``MethodDecorator``, i.e. all method
+decorators, whereas ``decorators.getdec('[ClassDecorator]')``
+gives the list of the known class decorators. The utility of the function
+is that it also returns decorators that have been automagically created:
+
+>>> decorators.getdec("[classmethodtracedmethod]")
+[<class 'safetype.classmethodtracedmethod'>]
+
+It is even possible to use the comma notation:
+
+>>> decorators.getdec("[classmethod,tracedmethod]")
+[<class 'safetype.classmethodtracedmethod'>]
+
+If you mispell a decorator name you get an helpful error message:
+
+>>> class E:
+... "[Decorated]"
+... def f():
+... "[staticmeth]"
+Traceback (most recent call last):
+ .. a cryptic traceback here ..
+UnknownDecoratorError: staticmeth
+
+
+By design, the ``decorated`` function is quite limited, and does not
+decorate functions without magic docstrings. This is safe and also convenient
+for internal usage of the ``decorated`` function in the ``Decorated``
+metaclass. Nevertheless, advanced users may want to have the ability
+of decorating functions by hand, without invoking `decorators.decorator()``
+and magic docstrings. This is possible, by calling the decorator directly.
+For instance, here is how to convert a lambda function in a staticmethod:
+
+>>> do_nothing=decorators.staticmethod(lambda:None)
+>>> print do_nothing # ``do_nothing`` is a static method
+<staticmethod:<lambda>>
+
+The most convenient usage of this feature is in the composition of decorators.
+For instance, we may compose the just defined ``staticmethod`` with a
+``chattymethod2``:
+
+>>> chattystatic=customdec.chattymethod2(do_nothing)
+>>> print chattystatic
+<chattymethod2staticmethod:<lambda>>
+
+The syntax
+
+ ``decorator1(decorator2(obj))``
+
+automagically creates a composed class ``decorator1decorator2`` in the
+``safetype`` module (or recycle it, if ``decorator1decorator2`` has
+been already created) and it is equivalent to
+
+ ``decorator1decorator2(obj)``
+
+Here is the check that everything works:
+
+>>> class B:
+... chattystatic=chattystatic
+>>> B.chattystatic()
+calling <chattymethod2staticmethod:<lambda>> from <class 'B'>
+
+Notice that ``chattystatic`` does not know the class where it
+is defined:
+
+>>> chattystatic.__klass__
+<class 'safetype.?'>
+
+unless the ``__klass__`` attribute is explicitly set.
+
+This is the hierarchy:
+
+>>> for C in type(chattystatic).mro(): print C
+...
+<class 'safetype.chattymethod2staticmethod'>
+<class 'customdec.chattymethod2'>
+<class 'customdec.chattymethod'>
+<class 'decorators.staticmethod'>
+<class 'decorators.MethodDecorator'>
+<class 'decorators.decorator'>
+<type 'object'>
+
+One can also compose classes by hand, by using class decorators:
+
+>>> class C:
+... "[Logged]"
+... def f(): "[staticmethod]"
+...
+<class 'C'> created
+>>> C=customdec.Traced(C)
+<class C[TracedLogged]> created
+
+
+The ``decorators.enhance_classes(<classdecorator>)`` syntax performs
+the composition automagically:
+
+ ::
+
+ #<example8.py>
+
+ from example2 import identity,name
+ import inspect, decorators; decorators.enhance_classes("[Decorated]")
+
+ class C1: # automagically converted to a Decorated class
+ identity=identity
+
+ class C2: # automagically converted to a DecoratedLogged class
+ "[Logged]"
+ name=name
+
+ c1=C1() # C1 instance
+ c2=C2() # C2 instance
+
+ #</example8.py>
+
+In this example the class ``C2`` has already a magic docstring. This means that
+``C2`` has to be enhanced both from ``Logged`` and from ``Decorated``.
+This is done by automagically creating a ``DecoratedLogged`` class
+decorator:
+
+>>> from example8 import C1,C2,c1,c2
+<class C2[DecoratedLogged]> created
+
+The second line is printed because of the logging capabilities of ``C2``.
+Moreover, since ``C2`` is decorated too, the following will work:
+
+>>> assert C2.name() == 'C2'
+>>> assert c2.name() == 'C2'
+
+Idem for ``C1``:
+
+>>> assert C1.identity(1) == 1
+>>> assert c1.identity(1) == 1
+
+The implementation
+============================================================================
+
+This part can be safely skipped, unless you are a *really* curious and
+you want to know how the implementation works.
+
+The module is rather short (less than 150 lines if you skip comments and
+docstrings) but quite non-trivial, since it is based on extensive
+usage of metaclass wizardry. Moreover,
+it invokes the ``safetype`` module to solve metaclass conflicts, and
+``safetype`` contains 50 lines of *really* deep metaclass magic.
+
+ .. figure:: decorators.png
+
+The main class-metaclass hierarchy is represented in figure, where
+boxes denote classes and ovals denote metaclasses; instantiation is
+denoted by dashed green lines whereas inheritance is denoted by continuous
+blue lines.
+
+For instance, this is the Method Resolution Order for the ``Decorated``
+metaclass:
+
+>>> for i,c in enumerate(decorators.Decorated.__mro__):
+... print i,c,"[%s]" % type(c).__name__
+0 <class 'decorators.Decorated'> [MetaDecorator]
+1 <class 'decorators.ClassDecorator'> [MetaDecorator]
+2 <class 'safetype.safetype'> [type]
+3 <type 'type'> [type]
+4 <class 'decorators.decorator'> [MetaDecorator]
+5 <type 'object'> [type]
+
+``Decorator`` is the mother of all decorators. Its main purpose it to
+provide the ``MetaDecorator``
+metaclass to all decorators.
+
+The ``safetype`` metaclass, imported from the ``safetype`` module,
+ensures that class decorators can generate classes without incurring
+in conflicts.
+
+Since class decorators are metaclasses,
+``MetaDecorator`` is actually a meta-metaclass with respect to
+instances of decorated classes. For this reason if
+
+>>> C=decorators.ClassDecorator('C',(),{})
+
+then
+
+>>> C.__class__
+<class 'decorators.ClassDecorator'>
+
+but
+
+>>> C.__metaclass__
+<class 'decorators.MetaDecorator'>
+
+since the ``C.__metaclass__`` attribute is inherited from ``Decorator``.
+
+On the other hand, ``MetaDecorator`` is a simple metaclass with
+respect to instances of decorated methods.
+
+The implementation is relatively smart. Consider for instance the case of
+the ``logged`` example. In that example class ``D`` was a subclass
+of a tricked ``object`` class, enhanced by ``ClassDecorator``. Moreover ``D``
+had a ``Logged`` docstring. Therefore it should have been an instance of a
+``ClassDecoratorLogged`` metaclass. But logged was
+a subclass of ``ClassDecorator``, therefore it already had all the features
+of ``ClassDecorator`` and it would have been redundant to create
+``ClassDecoratorLogged``, when``Logged`` would have been enough.
+So ``Logged`` was used and ``ClassDecoratorLogged`` was never created.
+All this magic is in the ``safetype.remove_redundant(*classes)`` function.
+
+The current implementation does not make any attempt of optimization and
+there may be alternative implementations faster or more memory efficient.
+At this experimental level I didn't care to explore about performances
+issues. Probably, they do not matter unless one has to decorate
+thousands or millions of functions and classes.
+
+Finally, a word about bugs. The ``decorators`` module is fairly sophisticated,
+therefore whereas I can guarantee that it passes my test suite (which involves
+~200 tests, most of them extracted from the documentation you are reading),
+I cannot guarantee that it is correct. If somebody finds a bug or an
+unexpected behavior, please let me know and I will fix it or document it.
+
+.. References:
+
+.. _PEP 318:
+ http://www.python.org/pep
+.. _cooperative methods:
+ http://www.python.org/2.3/descrintro.html
+.. _new style classes and old style classes:
+ http://www.python.org/2.3/descrintro.html
+.. _descriptors: http://users.rcn.com/python/download/Descriptor.htm
+.. _cookbook: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197
+.. _first paper on metaclasses:
+ http://www-106.ibm.com/developerworks/library/l-pymeta.html
+.. _metaclasses: http://www-106.ibm.com/developerworks/library/l-pymeta2.html
+
+.. include:: decorators.rst
diff --git a/pypers/pep318/example.py b/pypers/pep318/example.py
new file mode 100755
index 0000000..aedb6f3
--- /dev/null
+++ b/pypers/pep318/example.py
@@ -0,0 +1,16 @@
+# example.py
+
+from example2 import identity,name
+import inspect, decorators; decorators.enhance_classes("[Decorated]")
+
+class C1: # automagically converted to a decorated class
+ identity=identity
+
+class C2: # automagically converted to a DecoratedLogged class
+ "[Logged]"
+ name=name
+
+c1=C1() # C1 instance
+c2=C2() # C2 instance
+
+
diff --git a/pypers/pep318/example1.py b/pypers/pep318/example1.py
new file mode 100755
index 0000000..5e8f7c8
--- /dev/null
+++ b/pypers/pep318/example1.py
@@ -0,0 +1,29 @@
+# example1.py
+
+import decorators
+
+def do_nothing(self):
+ "No magic docstring here"
+dec_do_nothing=decorators.decorator(do_nothing)
+
+def identity(x):
+ "[staticmethod]"
+ return x
+dec_identity=decorators.decorator(identity)
+
+def name(cls):
+ "[classmethod]"
+ return cls.__name__
+dec_name=decorators.decorator(name)
+
+class OldStyle:
+ do_nothing=dec_do_nothing
+ identity=dec_identity
+
+class NewStyle(object):
+ name=dec_name
+
+o=OldStyle() # creates an old style instance
+n=NewStyle() # creates a new style instance
+
+
diff --git a/pypers/pep318/example2.py b/pypers/pep318/example2.py
new file mode 100755
index 0000000..0377c0c
--- /dev/null
+++ b/pypers/pep318/example2.py
@@ -0,0 +1,22 @@
+# example2.py
+
+from decorators import decorator
+from example1 import do_nothing,identity,name
+
+class B(object):
+ "This is a regular class"
+
+B=decorator(B) or B # return the original B
+
+class C(B):
+ "[Decorated]"
+ do_nothing=do_nothing
+ identity=identity
+ class Inner: # old style class
+ "[Decorated]" # required docstring
+ name=name
+
+C=decorator(C) # regenerate the class converting methods in decorators
+c=C()
+
+
diff --git a/pypers/pep318/example3.py b/pypers/pep318/example3.py
new file mode 100755
index 0000000..5f3ddac
--- /dev/null
+++ b/pypers/pep318/example3.py
@@ -0,0 +1,22 @@
+# example3.py
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ "[Decorated]" # magic docstring here
+ def do_nothing(self):
+ "No magic docstring here"
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+class D(object):
+ "Undecorated" # no magic docstring here
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+c=C(); d=D()
+
+
diff --git a/pypers/pep318/example4.py b/pypers/pep318/example4.py
new file mode 100755
index 0000000..723c7c5
--- /dev/null
+++ b/pypers/pep318/example4.py
@@ -0,0 +1,20 @@
+# example4.py
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ "[Decorated]" # required docstring
+ def identity(x):
+ "[staticmethod]"
+ return x
+ class Inner:
+ "[Decorated]" # required docstring
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+
+assert C.identity(1) == 1
+assert C.Inner.name() == 'Inner'
+
+
diff --git a/pypers/pep318/example5.py b/pypers/pep318/example5.py
new file mode 100755
index 0000000..81ebce9
--- /dev/null
+++ b/pypers/pep318/example5.py
@@ -0,0 +1,20 @@
+# example5.py
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ "[Decorated]" # required docstring
+ def identity(x):
+ "[staticmethod]"
+ return x
+ class Inner:
+ "[Decorated]" # required docstring
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+
+assert C.identity(1) == 1
+assert C.Inner.name() == 'Inner'
+
+
diff --git a/pypers/pep318/example6.py b/pypers/pep318/example6.py
new file mode 100755
index 0000000..145c06a
--- /dev/null
+++ b/pypers/pep318/example6.py
@@ -0,0 +1,14 @@
+# example6.py
+
+"How to trace a class method"
+
+import customdec; customdec.enhance_classes()
+
+class C(object):
+ "[Decorated]"
+ def fact(cls,n): # a traced classmethod
+ "[classmethod,tracedmethod]"
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+
diff --git a/pypers/pep318/example7.py b/pypers/pep318/example7.py
new file mode 100755
index 0000000..ce12589
--- /dev/null
+++ b/pypers/pep318/example7.py
@@ -0,0 +1,15 @@
+# example7.py
+
+from example2 import identity,name
+import inspect, decorators; decorators.enhance_classes("[Decorated]")
+
+class C1(object): # automagically converted to a decorated class
+ identity=identity
+
+class C2: # automagically converted to a decorated class
+ name=name
+
+c1=C1() # C1 instance
+c2=C2() # C2 instance
+
+
diff --git a/pypers/pep318/example8.py b/pypers/pep318/example8.py
new file mode 100755
index 0000000..5b4f9df
--- /dev/null
+++ b/pypers/pep318/example8.py
@@ -0,0 +1,16 @@
+# example8.py
+
+from example2 import identity,name
+import inspect, decorators; decorators.enhance_classes("[Decorated]")
+
+class C1: # automagically converted to a Decorated class
+ identity=identity
+
+class C2: # automagically converted to a DecoratedLogged class
+ "[Logged]"
+ name=name
+
+c1=C1() # C1 instance
+c2=C2() # C2 instance
+
+
diff --git a/pypers/pep318/example9.py b/pypers/pep318/example9.py
new file mode 100755
index 0000000..8a6fd33
--- /dev/null
+++ b/pypers/pep318/example9.py
@@ -0,0 +1,19 @@
+# example9.py
+
+import customdec; customdec.enhance_classes()
+
+logfile=file('file3.log','w')
+
+class C(object):
+ "[Decorated]"
+ def fact(self,n):
+ "[tracedmethod] The good old factorial."
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact.output=logfile
+
+C().fact(2) # write a message to logfile
+
+logfile.close()
+
+
diff --git a/pypers/pep318/lessmeta/decorators.py b/pypers/pep318/lessmeta/decorators.py
new file mode 100755
index 0000000..b452c24
--- /dev/null
+++ b/pypers/pep318/lessmeta/decorators.py
@@ -0,0 +1,210 @@
+# Simpler implementation with smaller usage of metaclasses
+
+"""
+A module to implement pep318 (decorator syntax) via magic doctrings.
+It defines two new classes, MethodDecorator and ClassDecorator,
+which are meant to be subclassed.
+
+def f(x):
+ "[chattymethod]"
+
+as a shortcut for
+
+def f(x):
+ pass
+f=chattymethod(f)
+
+Decorators can be composed and for instance
+
+def f(x):
+ "[chattymethod,classmethod]"
+
+is a shortcut for
+
+def f(x):
+ pass
+f=chattymethodclassmethod(f)
+
+where 'chattymethodclassmethod' is a decorator class obtained by
+multiple inheriting from chattymethod and classmethod.
+Notice that the built-in classmethod descriptor (idem for
+staticmethod) is non=cooperatice, whereas the custom
+descriptor chattymethod is cooperative: this means that
+the custom descriptor has to be put *first* in the list.
+
+The implementation stores the generated descriptors in a
+dictionary, and avoids creating unneeded subclasses.
+
+The names in the module are quite specific, since I am trying to avoid
+troubles to people using the form "from decorator import *".
+"""
+
+import sys,re,inspect,__builtin__,time,noconflict
+anyTrue=sum
+
+############################ UTILITIES ##############################
+
+class UnknownDecoratorError(Exception):
+ "In case of mistakes"
+
+class StoredDecorators(type):
+ "Metaclass storing its instances in the dictionary dic"
+ dic={}
+
+ def __init__(cls,*args):
+ super(StoredDecorators,cls).__init__(*args)
+ StoredDecorators.dic[cls.__name__]=cls
+ get=cls.__dict__.get('get') # if get
+ if get: cls.__get__=get # set __get__
+
+ def methodlike(mcl):
+ "List of recognized MethodDecorators"
+ return [name for name in mcl.dic
+ if issubclass(mcl.dic[name],MethodDecorator)]
+ methodlike=classmethod(methodlike)
+
+ def classlike(mcl):
+ "List of recognized ClassDecorators"
+ return [name for name in mcl.dic
+ if issubclass(mcl.dic[name],ClassDecorator)]
+ classlike=classmethod(classlike)
+
+def decorate(obj='THISMODULE'):
+ """
+ obj can be:
+ - the string 'THISMODULE'
+ in this case magic docstrings are interpreted in the new
+ style classes of the calling module;
+ - the string 'ALLMODULES'
+ in this case magic docstrings are interpreted in the new
+ style classes of ALL modules;
+ - a dictionary or an object with a dictionary
+ in this case magic docstrings are interpreted in all the
+ functions and classes in the dictionary
+ """
+ dic={}
+ if obj=='THISMODULE':
+ callerglobals=sys._getframe(1).f_globals
+ callerglobals['object']=_EnableMagicDocstrings
+ elif obj=='ALLMODULES':
+ __builtin__.object=_EnableMagicDocstrings
+ elif isinstance(obj,dict):
+ dic=obj
+ elif hasattr(obj,'__dict__'):
+ dic=obj.__dict__
+ else:
+ raise TypeError("Dictionary or object with a __dict__ required")
+ for name,value in dic.items():
+ _set(obj,name,value)
+
+def _decorate(obj):
+ """Given an object with a magic docstrings, returns its decorated
+ version; otherwise, returns None"""
+ docstring=inspect.getdoc(obj) or ''
+ MO=re.match(r'\[([\w_ ,]*)\]',docstring)
+ # for instance [name_1, name_2, name_3] is matched
+ if MO:
+ decorators=MO.group(1).split(',')
+ try: dclasses=[StoredDecorators.dic[n] for n in decorators]
+ except KeyError: raise UnknownDecoratorError(n)
+ dclasses=noconflict.remove_redundant(dclasses)
+ decname=''.join([d.__name__ for d in dclasses])
+ decorator=StoredDecorators.dic.get(decname)
+ if not decorator: decorator=makecls()(decname,dclasses,{})
+ if issubclass(decorator,ClassDecorator): return decorator(obj)()
+ return decorator(obj)
+
+def _set(objdict,name,obj):
+ dec=_decorate(obj)
+ if dec:
+ dec.inside=objdict
+ if isinstance(objdict,dict):
+ objdict[name]=dec
+ else:
+ setattr(objdict,name,dec)
+
+class _MagicDocstrings:
+ def __init__(cls,name,bases,dic):
+ decorate(cls) # both cls and its dictionary
+
+class _EnableMagicDocstrings:
+ __metaclass__=_MagicDocstrings
+
+class Decorator(object):
+ """Instance of StoredDecorators, i.e. each time Decorator is
+ subclassed, StoredDecorators.dic is updated. Provides a setattributes
+ method to recognize magic attributes with ``set_`` prefix.
+ Provides an 'inside' attribute (default='?')"""
+ __metaclass__=StoredDecorators
+ inside=type('?',(),{}) # default placeholder class (to be
+ # replaced by the class that contains the decorated method)
+ def setattributes(self):
+ for a in dir(self):
+ if a.startswith('set_'):
+ setattr(self,a[4:],getattr(self,a))
+
+class MethodDecorator(Decorator):
+ """MethodDecorator objects provide a 'get' method and a 'str' method"""
+ def __init__(self,func):
+ super(MethodDecorator,self).__init__(func)
+ self.func=func; self.setattributes()
+ def get(self,obj,cls=None): # default, to be overridden
+ return self.func.__get__(obj,cls)
+ def __str__(self):
+ return '<%s:%s>' % (self.__class__.__name__,self.func.__name__)
+
+class ClassDecorator(Decorator):
+ """ClassDecorator takes a class as argument and returns a callable
+ object acting as a factory of decorated objects"""
+ def __init__(self,klass):
+ super(ClassDecorator,self).__init__(klass)
+ self.klass=klass; self.setattributes()
+ def __call__(self): # to be cooperatively overridden
+ return self.klass
+ def __str__(self):
+ return '<%s:%s>' % (self.__class__.__name__,self.klass.__name__)
+
+#################### Useful Method Decorators ######################
+
+class staticmethod(MethodDecorator):
+ "Decorator, converts a function in a staticmethod"
+ def get(self,obj,cls=None):
+ super(staticmethod,self).get(obj,cls)
+ return self.func
+
+class classmethod(MethodDecorator):
+ "Decorator, converts a function in a classmethod"
+ def get(self,obj,cls=None):
+ if cls is None: cls=type(obj)
+ return super(classmethod,self).get(cls,cls)
+
+class tracedmethod(MethodDecorator):
+ "Descriptor class, converts a function in a traced method"
+ indent=0; output=sys.stdout # defaults
+ def __init__(self,func):
+ super(tracedmethod,self).__init__(func)
+ self.funcname=self.func.__name__
+ def get(self,obj,cls):
+ clsname=self.inside.__name__
+ boundmethod=super(tracedmethod,self).get(obj,cls)
+ def _(*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write("%sCalling '%s.%s' with arguments " %
+ (i,clsname,self.funcname))
+ self.output.write("%s ...\n" % (str(args)+str(kw)))
+ res=boundmethod(*args,**kw)
+ self.output.write("%s'%s.%s' called with result: %s\n"
+ % (i,clsname,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return _
+
+####################### Class Decorators ###############################
+
+class Register(ClassDecorator):
+ output=sys.stdout
+ def __call__(self):
+ cls=super(Register,self).__call__()
+ print >> self.output, "%s: %s created" % (time.asctime(),cls)
+ return cls
diff --git a/pypers/pep318/logged.py b/pypers/pep318/logged.py
new file mode 100755
index 0000000..04be3fd
--- /dev/null
+++ b/pypers/pep318/logged.py
@@ -0,0 +1,8 @@
+# logged.py
+
+import customdec; customdec.enhance_classes()
+
+class D(object): # will print a message at D creation
+ "[Logged]"
+
+
diff --git a/pypers/pep318/mod.py b/pypers/pep318/mod.py
new file mode 100755
index 0000000..4e7073d
--- /dev/null
+++ b/pypers/pep318/mod.py
@@ -0,0 +1,11 @@
+# mod.py
+
+#"[TraceFunctions]"
+
+def f1(): pass
+
+def f2(): pass
+
+def f3(): "-untraced-"
+
+
diff --git a/pypers/pep318/module.py b/pypers/pep318/module.py
new file mode 100755
index 0000000..d22c798
--- /dev/null
+++ b/pypers/pep318/module.py
@@ -0,0 +1,13 @@
+# module.py
+
+"Magically decorated module"
+
+import decorators,sys
+
+thismodule=sys.modules[__name__]
+
+class MyClass: "[Decorated]"
+
+newmod=decorators.decorated(thismodule)
+
+
diff --git a/pypers/pep318/moduledec.py b/pypers/pep318/moduledec.py
new file mode 100755
index 0000000..ccaa73c
--- /dev/null
+++ b/pypers/pep318/moduledec.py
@@ -0,0 +1,51 @@
+
+
+err=file('err','w')
+
+def printerr(*args):
+ "For debugging purposes"
+ for a in args: print >> err, a,
+ print >> err
+
+def importmodule(name,dic):
+ """Given a module name and a dictionary, executes the module in a copy
+ of the dictionary and returns a new module."""
+ already_imported=sys.modules.get(name)
+ if already_imported: return already_imported # do nothing
+ fname=name+'.py'
+ dic=dic.copy()
+ execfile(fname,dic)
+ mod=types.ModuleType(name)
+ for k,v in dic.iteritems():
+ setattr(mod,k,v)
+ sys.modules[name]=mod
+ mod.__name__=name
+
+ mod.__file__=fname
+ return mod
+
+class ModuleDecorator(Decorator,types.ModuleType):
+ def __init__(self,mod): # non-cooperative
+ self.undecorated=mod
+ for k,v in mod.__dict__.iteritems():
+ setattr(self,k,v)
+ decorate(self)
+ def __str__(self):
+ return '<module %s[%s]>' % (self.mod.__name__,self.__class__.__name__)
+
+class DecoratedModule(ModuleDecorator): # defined for readability
+ pass
+
+def callModuleDecorator(dec,*args):
+ if issubclass(dec,ModuleDecorator):
+ nargs=len(args)
+ if nargs==1:
+ mod=args[0]
+ elif nargs==2:
+ name,glob=args # a different object for each module
+ glob['object']=ClassDecorator(object)
+ mod=importmodule(name,glob)
+ else:
+ raise TypeError('%s() takes 1 or 2 arguments' % dec.__name__)
+ return type.__call__(dec,mod)
+
diff --git a/pypers/pep318/moduledec.txt b/pypers/pep318/moduledec.txt
new file mode 100755
index 0000000..602aec4
--- /dev/null
+++ b/pypers/pep318/moduledec.txt
@@ -0,0 +1,97 @@
+
+
+
+Module decorators
+-----------------------------------------------------------------------
+
+Finally, one can decorate entire modules through the concept of
+*module decorators*. Module decorators have the ability of decorating
+modules by changing their dictionary. Custom module decorators
+should be derived from the class ``decorators.ModuleDecorator``, by
+cooperatively overriding its ``__init__(self,mod)`` method. Writing
+a module decorator is a bit tricky, but I do expect only
+expert programmers to play this kind of game.
+For instance, suppose one wants to trace all the functions in a module,
+unless they have the docstring "-untraced-" . This can be done with a
+suitable module decorator which modifies the module dictionary.
+Here is an example
+
+ ::
+
+ #<customdec.py>
+
+ class TraceFunctions(ModuleDecorator):
+ def __init__(self,mod):
+ super(TraceFunctions,self).__init__(mod)
+ for name,func in self.__dict__.items():
+ if inspect.isfunction(func):
+ doc=func.__doc__ or ''
+ if doc.startswith('-untraced-'):
+ pass # do nothing
+ else:
+ def traced(func):
+ def tracedfunc(*args,**kw):
+ print 'called',func.__name__
+ return func(*args,**kw)
+ return tracedfunc
+ setattr(self,name,traced(func))
+
+ #</customdec.py>
+
+There is no way of tinkering with the attribute access in modules (as
+opposed to attribute access in classes) so we cannot used descriptors
+here and we are forced to use closures.
+
+Let me test that the module decorator does its job. Consider the module
+
+ ::
+
+ #<mod.py>
+
+ #"[TraceFunctions]"
+
+ def f1(): pass
+
+ def f2(): pass
+
+ def f3(): "-untraced-"
+
+ #</mod.py>
+
+By importing this module, only the functions ``f1`` and ``f2`` should
+be traced. This is indeed the case:
+
+>>> from customdec import TraceFunctions
+>>> mod=TraceFunctions('mod',{})
+>>> mod.f1()
+called f1
+>>> mod.f2()
+called f2
+>>> mod.f3() # does nothing, correct
+
+One has always access to the original, undecorated module, via the
+``undecorated`` attribute:
+
+>>> orig=mod.undecorated
+>>> orig.f1() # does nothing, correct
+
+ ::
+
+ #<module.py>
+
+ "Magically decorated module"
+
+ import decorators,sys
+
+ thismodule=sys.modules[__name__]
+
+ class MyClass: "[Decorated]"
+
+ newmod=decorators.decorated(thismodule)
+
+ #</module.py>
+
+>>> from module import *
+>>> assert isinstance(newmod.MyClass, decorators.Decorated)
+>>> assert isinstance(newmod,decorators.DecoratedModule)
+
diff --git a/pypers/pep318/mydoc.html b/pypers/pep318/mydoc.html
new file mode 100755
index 0000000..fb70714
--- /dev/null
+++ b/pypers/pep318/mydoc.html
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.2.9: http://docutils.sourceforge.net/" />
+<title>Documentation of the mydoc module</title>
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="documentation-of-the-mydoc-module">
+<h1 class="title">Documentation of the mydoc module</h1>
+<p>Short utility to extract documentation from a module</p>
+<div class="section" id="documented-functions">
+<h1><a name="documented-functions">Documented functions</a></h1>
+<p><tt class="literal"><span class="pre">publish_cmdline(reader=None,</span> <span class="pre">reader_name='standalone'</span></tt></p>
+<blockquote>
+<p>Set up &amp; run a <cite>Publisher</cite>. For command-line front ends.</p>
+<p>Parameters:</p>
+<ul class="simple">
+<li><cite>reader</cite>: A <cite>docutils.readers.Reader</cite> object.</li>
+<li><cite>reader_name</cite>: Name or alias of the Reader class to be instantiated if
+no <cite>reader</cite> supplied.</li>
+<li><cite>parser</cite>: A <cite>docutils.parsers.Parser</cite> object.</li>
+<li><cite>parser_name</cite>: Name or alias of the Parser class to be instantiated if
+no <cite>parser</cite> supplied.</li>
+<li><cite>writer</cite>: A <cite>docutils.writers.Writer</cite> object.</li>
+<li><cite>writer_name</cite>: Name or alias of the Writer class to be instantiated if
+no <cite>writer</cite> supplied.</li>
+<li><cite>settings</cite>: Runtime settings object.</li>
+<li><cite>settings_spec</cite>: Extra settings specification; a <cite>docutils.SettingsSpec</cite>
+subclass. Used only if no <cite>settings</cite> specified.</li>
+<li><cite>settings_overrides</cite>: A dictionary containing program-specific overrides
+of component settings.</li>
+<li><cite>argv</cite>: Command-line argument list to use instead of <tt class="literal"><span class="pre">sys.argv[1:]</span></tt>.</li>
+<li><cite>usage</cite>: Usage string, output if there's a problem parsing the command
+line.</li>
+<li><cite>description</cite>: Program description, output for the &quot;--help&quot; option
+(along with command-line option descriptions).</li>
+</ul>
+</blockquote>
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="mydoc.rst">View document source</a>.
+Generated on: 2003-09-20 11:43 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/pypers/pep318/nonrecognized.py b/pypers/pep318/nonrecognized.py
new file mode 100755
index 0000000..d8e3be5
--- /dev/null
+++ b/pypers/pep318/nonrecognized.py
@@ -0,0 +1,23 @@
+# nonrecognized.py
+
+"Classes and functions inside a function are not decorated"
+
+import decorators; decorators.enable()
+
+def outer():
+
+ class C(object):
+ def f():
+ "[staticmethod]"
+
+ def g():
+ "[staticmethod]"
+
+ # testing
+
+ assert isinstance(C.__dict__['f'],decorators.staticmethod)
+ assert not isinstance(g,decorators.staticmethod)
+
+outer()
+
+
diff --git a/pypers/pep318/oopp.html b/pypers/pep318/oopp.html
new file mode 100755
index 0000000..948dad1
--- /dev/null
+++ b/pypers/pep318/oopp.html
@@ -0,0 +1,324 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.2.9: http://docutils.sourceforge.net/" />
+<title>Documentation of the oopp module</title>
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="documentation-of-the-oopp-module">
+<h1 class="title">Documentation of the oopp module</h1>
+<div class="section" id="documented-metaclasses">
+<h1><a name="documented-metaclasses">Documented metaclasses</a></h1>
+<p><tt class="literal"><span class="pre">Final(type):</span> <span class="pre">#</span> <span class="pre">better</span> <span class="pre">derived</span> <span class="pre">from</span> <span class="pre">WithCounter,typ</span></tt></p>
+<blockquote>
+Instances of Final cannot be derived</blockquote>
+<p><tt class="literal"><span class="pre">AutoWrapped(type)</span></tt></p>
+<blockquote>
+Metaclass that looks at the methods declared in the attributes
+builtinlist and wraplist of its instances and wraps them with
+autowrappedmethod.</blockquote>
+<p><tt class="literal"><span class="pre">Wrapped(Customizable,type)</span></tt></p>
+<blockquote>
+<p>A customizable metaclass to wrap methods with a given wrapper and
+a given condition</p>
+<p><tt class="literal"><span class="pre">Reflective(type)</span></tt></p>
+<blockquote>
+Cooperative metaclass that defines the private variable __this in
+its instances. __this contains a reference to the class, therefore
+it allows anonymous cooperative super calls in the class.</blockquote>
+<p><tt class="literal"><span class="pre">wrappedmethod(Customizable)</span></tt></p>
+<blockquote>
+Customizable method factory intended for derivation.
+The wrapper method is overridden in the children.</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">Cooperative(BracketCallable,type)</span></tt></p>
+<blockquote>
+<p>Bracket-callable metaclass implementing cooperative methods. Works
+well for plain methods returning None, such as __init__</p>
+<p><tt class="literal"><span class="pre">coop_method(cls,name,method):</span> <span class="pre">#</span> <span class="pre">method</span> <span class="pre">can</span> <span class="pre">be</span> <span class="pre">Non</span></tt></p>
+<blockquote>
+Calls both the superclass method and the class method (if the
+class has an explicit method). Implemented via a closure</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">Logged(WithLogger,Reflective)</span></tt></p>
+<blockquote>
+Metaclass that reuses the features provided by WithLogger.
+In particular the classes created by Logged are Reflective,
+PrettyPrinted and Customizable.</blockquote>
+<p><tt class="literal"><span class="pre">MagicallyTransformed(type)</span></tt></p>
+<blockquote>
+Metaclass changing the formatstring of its instances</blockquote>
+<p><tt class="literal"><span class="pre">Printable(PrettyPrinted,type)</span></tt></p>
+<blockquote>
+Apparently does nothing, but actually makes PrettyPrinted acting as
+a metaclass.</blockquote>
+</div>
+<div class="section" id="documented-classes">
+<h1><a name="documented-classes">Documented classes</a></h1>
+<p><tt class="literal"><span class="pre">convert2descriptor(object)</span></tt></p>
+<blockquote>
+<p>To all practical means, this class acts as a function that, given an
+object, adds to it a __get__ method if it is not already there. The
+added __get__ method is trivial and simply returns the original object,
+independently from obj and cls.</p>
+<p><tt class="literal"><span class="pre">__get__(self,obj,cls=None)</span></tt></p>
+<blockquote>
+Returns self.a independently from obj and cls</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">Object(object)</span></tt></p>
+<blockquote>
+A convenient Object class</blockquote>
+<p><tt class="literal"><span class="pre">GeometricFigure(object):</span> <span class="pre">#an</span> <span class="pre">example</span> <span class="pre">of</span> <span class="pre">object</span> <span class="pre">factor</span></tt></p>
+<blockquote>
+<p>This class allows to define geometric figures according to their
+equation in the cartesian plane. It will be extended later.</p>
+<p><tt class="literal"><span class="pre">__init__(self,equation,**parameters)</span></tt></p>
+<blockquote>
+Specify the cartesian equation of the object and its parameters</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">UglyDuckling(PrettyPrinted)</span></tt></p>
+<blockquote>
+A plain, regular class</blockquote>
+<p><tt class="literal"><span class="pre">autowrappedmethod(wrappedmethod)</span></tt></p>
+<blockquote>
+Makes the method returning cls instances, by wrapping its
+output with cls</blockquote>
+<p><tt class="literal"><span class="pre">Clock(object)</span></tt></p>
+<blockquote>
+Clock with a staticmethod</blockquote>
+<p><tt class="literal"><span class="pre">AccessError(object)</span></tt></p>
+<blockquote>
+Descriptor raising an AttributeError when the attribute is
+accessed</blockquote>
+<p><tt class="literal"><span class="pre">Frozen(object)</span></tt></p>
+<blockquote>
+Subclasses of Frozen are frozen, i.e. it is impossibile to add
+new attributes to them and their instances</blockquote>
+<p><tt class="literal"><span class="pre">Timer(Clock)</span></tt></p>
+<blockquote>
+Inherits the get_time staticmethod from Clock</blockquote>
+<p><tt class="literal"><span class="pre">Vector(list)</span></tt></p>
+<blockquote>
+Implements finite dimensional vectors as lists. Can be instantiated
+as Vector([a,b,c,..]) or as Vector(a,b,c ..)</blockquote>
+<p><tt class="literal"><span class="pre">Singleton(WithCounter)</span></tt></p>
+<blockquote>
+If you inherit from me, you can only have one instance</blockquote>
+<p><tt class="literal"><span class="pre">Homo(PrettyPrinted)</span></tt></p>
+<blockquote>
+Defines the method 'can', which is intended to be overriden
+in the children classes, and inherits '__str__' from PrettyPrinted,
+ensuring a nice printing representation for all children.</blockquote>
+<p><tt class="literal"><span class="pre">kwdict(dict)</span></tt></p>
+<blockquote>
+<p>Keyword dictionary base class</p>
+<p><tt class="literal"><span class="pre">pretty(dic)</span></tt></p>
+<blockquote>
+Returns a nice string representation for the dictionary</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">WithLogger(WithCounter,PrettyPrinted)</span></tt></p>
+<blockquote>
+WithLogger inherits from WithCounter the 'count' class attribute;
+moreover it inherits '__str__' from PrettyPrinted</blockquote>
+<p><tt class="literal"><span class="pre">Get(object)</span></tt></p>
+<blockquote>
+Invoked as Get(cls)(xxx) where xxx = staticmethod, classmethod,
+property, plainmethod, plaindata, returns the corresponding
+attributes as a keyword dictionary. It works by internally calling
+the routine inspect.classify_class_attrs. Notice that special data
+attributes are not retrieved (this is by design).</blockquote>
+<p><tt class="literal"><span class="pre">Makeobj(object)</span></tt></p>
+<blockquote>
+A factory of object factories. Makeobj(cls) returns instances
+of cls</blockquote>
+<p><tt class="literal"><span class="pre">ExampleBaseClass(PrettyPrinted)</span></tt></p>
+<blockquote>
+Contains a regular method 'm', a staticmethod 's', a classmethod
+'c', a property 'p' and a data attribute 'd'.</blockquote>
+<p><tt class="literal"><span class="pre">TransformedUglyDuckling(PrettyPrinted)</span></tt></p>
+<blockquote>
+A class metamagically modified</blockquote>
+<p><tt class="literal"><span class="pre">Customizable(object)</span></tt></p>
+<blockquote>
+Classes inhering from 'Customizable' have a 'with' method acting as
+an object modifier and 'With' classmethod acting as a class factory</blockquote>
+<p><tt class="literal"><span class="pre">WithMultiCounter(WithCounter)</span></tt></p>
+<blockquote>
+Each time a new subclass is derived, the counter is reset</blockquote>
+<p><tt class="literal"><span class="pre">BracketCallable(object)</span></tt></p>
+<blockquote>
+Any subclass C(BracketCallable) can be called with the syntax C[t],
+where t is a tuple of arguments stored in bracket_args; returns the
+class or an instance of it, depending on the flag 'returnclass'.</blockquote>
+<p><tt class="literal"><span class="pre">ClsFactory(BracketCallable)</span></tt></p>
+<blockquote>
+<dl>
+<dt>Bracket callable non-cooperative class acting as </dt>
+<dd>a factory of class factories.
+ClsFactory instances are class factories accepting 0,1,2 or 3 arguments.</dd>
+<dt>. They automatically converts functions to static methods </dt>
+<dd>if the input object is not a class. If an explicit name is not passed
+the name of the created class is obtained by adding an underscore to
+the name of the original object.</dd>
+</dl>
+<p><tt class="literal"><span class="pre">__call__(self,</span> <span class="pre">*args)</span></tt></p>
+<blockquote>
+Generates a new class using self.meta and avoiding conflicts.
+The first metaobject can be a dictionary, an object with a
+dictionary (except a class), or a simple name.</blockquote>
+</blockquote>
+<p><tt class="literal"><span class="pre">WithCounter(object)</span></tt></p>
+<blockquote>
+Mixin class counting the total number of its instances and storing
+it in the class attribute counter.</blockquote>
+</div>
+<div class="section" id="documented-functions">
+<h1><a name="documented-functions">Documented functions</a></h1>
+<p><tt class="literal"><span class="pre">mandelbrot(row,col)</span></tt></p>
+<blockquote>
+Computes the Mandelbrot set in one line</blockquote>
+<p><tt class="literal"><span class="pre">with_tracer(function,namespace='__main__',output=sys.stdout,</span> <span class="pre">indent=[0])</span></tt></p>
+<blockquote>
+Closure returning traced functions. It is typically invoked
+trough an auxiliary function fixing the parameters of with_tracer.</blockquote>
+<p><tt class="literal"><span class="pre">ancestor(C,S=None)</span></tt></p>
+<blockquote>
+Returns the ancestors of the first argument with respect to the
+MRO of the second argument. If the second argument is None, then
+returns the MRO of the first argument.</blockquote>
+<p><tt class="literal"><span class="pre">customize(obj,errfile=None,**kw)</span></tt></p>
+<blockquote>
+Adds attributes to an object, if possible. If not, writes an error
+message on 'errfile'. If errfile is None, skips the exception.</blockquote>
+<p><tt class="literal"><span class="pre">loop_overhead(N)</span></tt></p>
+<blockquote>
+Computes the time spent in empty loop of N iterations</blockquote>
+<p><tt class="literal"><span class="pre">indent(block,n)</span></tt></p>
+<blockquote>
+Indent a block of code by n spaces</blockquote>
+<p><tt class="literal"><span class="pre">totuple(arg)</span></tt></p>
+<blockquote>
+Converts the argument to a tuple, if need there is</blockquote>
+<p><tt class="literal"><span class="pre">attributes(obj,condition=lambda</span> <span class="pre">n,v:</span> <span class="pre">not</span> <span class="pre">special(n))</span></tt></p>
+<blockquote>
+Returns a dictionary containing the accessible attributes of
+an object. By default, returns the non-special attributes only.</blockquote>
+<p><tt class="literal"><span class="pre">generateblocks(regexp,text)</span></tt></p>
+<blockquote>
+Generator splitting text in blocks according to regexp</blockquote>
+<p><tt class="literal"><span class="pre">wrapfunctions(obj,wrapper,err=None,**options)</span></tt></p>
+<blockquote>
+Traces the callable objects in an object with a dictionary</blockquote>
+<p><tt class="literal"><span class="pre">wrap(obj,wrapped,condition=lambda</span> <span class="pre">k,v:</span> <span class="pre">True,</span> <span class="pre">err=None)</span></tt></p>
+<blockquote>
+Retrieves obj's dictionary and wraps it</blockquote>
+<p><tt class="literal"><span class="pre">reflective(*classes)</span></tt></p>
+<blockquote>
+Reflective classes know themselves, i.e. they own a private
+attribute __this containing a reference to themselves. If the class
+name starts with '_', the underscores are stripped. This is needed
+to make the mangling mechanism work.</blockquote>
+<p><tt class="literal"><span class="pre">withmemory(f)</span></tt></p>
+<blockquote>
+This closure invokes the callable object f only if need there is</blockquote>
+<p><tt class="literal"><span class="pre">get_time()</span></tt></p>
+<blockquote>
+Return the time of the system in the format HH:MM:SS</blockquote>
+<p><tt class="literal"><span class="pre">prn(s)</span></tt></p>
+<blockquote>
+Given an evaluable string, print its value and its object reference.
+Notice that the evaluation is done in the __main__ dictionary.</blockquote>
+<p><tt class="literal"><span class="pre">isplaindata(a)</span></tt></p>
+<blockquote>
+A data attribute has no __get__ or __set__ attributes, is not
+a built-in function, nor a built-in method.</blockquote>
+<p><tt class="literal"><span class="pre">Pizza(toppings,**dic)</span></tt></p>
+<blockquote>
+This function produces classes inheriting from GenericPizza and
+WithLogger, using a metaclass inferred from Logged</blockquote>
+<p><tt class="literal"><span class="pre">modulesub(s,r,module)</span></tt></p>
+<blockquote>
+Requires 2.3</blockquote>
+<p><tt class="literal"><span class="pre">memoize(f)</span></tt></p>
+<blockquote>
+This closure remembers all f invocations</blockquote>
+<p><tt class="literal"><span class="pre">with_timer(func,</span> <span class="pre">modulename='__main__',</span> <span class="pre">n=1,</span> <span class="pre">logfile=sys.stdout)</span></tt></p>
+<blockquote>
+Wraps the function func and executes it n times (default n=1).
+The average time spent in one iteration, express in milliseconds,
+is stored in the attributes func.time and func.CPUtime, and saved
+in a log file which defaults to the standard output.</blockquote>
+<p><tt class="literal"><span class="pre">dedent(text)</span></tt></p>
+<blockquote>
+<p>dedent(text : string) -&gt; string</p>
+<blockquote>
+<blockquote>
+<p>Remove any whitespace than can be uniformly removed from the left
+of every line in <cite>text</cite>.</p>
+<p>This can be used e.g. to make triple-quoted strings line up with
+the left edge of screen/whatever, while still presenting it in the
+source code in indented form.</p>
+<p>For example:</p>
+<blockquote>
+<blockquote>
+<dl>
+<dt>def test():</dt>
+<dd><p class="first"># end first line with to avoid the empty line!
+s = ''' hello</p>
+<div class="system-message">
+<p class="system-message-title">System Message: ERROR/3 (<tt>oopp.rst</tt>, line 337)</p>
+Unexpected indentation.</div>
+<blockquote>
+world</blockquote>
+<div class="system-message">
+<p class="system-message-title">System Message: WARNING/2 (<tt>oopp.rst</tt>, line 338)</p>
+Block quote ends without a blank line; unexpected unindent.</div>
+<p class="last">'''
+print repr(s) # prints ' hello</p>
+</dd>
+</dl>
+</blockquote>
+<div class="system-message">
+<p class="system-message-title">System Message: WARNING/2 (<tt>oopp.rst</tt>, line 340)</p>
+Block quote ends without a blank line; unexpected unindent.</div>
+<p>world</p>
+</blockquote>
+<div class="system-message">
+<p class="system-message-title">System Message: WARNING/2 (<tt>oopp.rst</tt>, line 341)</p>
+Block quote ends without a blank line; unexpected unindent.</div>
+<dl>
+<dt>'</dt>
+<dd>print repr(dedent(s)) # prints 'hello</dd>
+</dl>
+</blockquote>
+<div class="system-message">
+<p class="system-message-title">System Message: WARNING/2 (<tt>oopp.rst</tt>, line 343)</p>
+Block quote ends without a blank line; unexpected unindent.</div>
+<p>world</p>
+</blockquote>
+<div class="system-message">
+<p class="system-message-title">System Message: WARNING/2 (<tt>oopp.rst</tt>, line 344)</p>
+Block quote ends without a blank line; unexpected unindent.</div>
+<p>'</p>
+</blockquote>
+<p><tt class="literal"><span class="pre">makecls(*metas,**options)</span></tt></p>
+<blockquote>
+Class factory avoiding metatype conflicts. The invocation syntax is
+makecls(M1,M2,..,priority=1)(name,bases,dic). If the base classes have
+metaclasses conflicting within themselves or with the given metaclasses,
+it automatically generates a compatible metaclass and instantiate it.
+If priority is True, the given metaclasses have priority over the
+bases' metaclasses</blockquote>
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="oopp.rst">View document source</a>.
+Generated on: 2003-09-20 12:54 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/pypers/pep318/oopp.tex b/pypers/pep318/oopp.tex
new file mode 100755
index 0000000..e5ffd3c
--- /dev/null
+++ b/pypers/pep318/oopp.tex
@@ -0,0 +1,573 @@
+\documentclass[10pt,english]{article}
+\usepackage{babel}
+\usepackage{shortvrb}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\usepackage{longtable}
+\setlength{\extrarowheight}{2pt}
+\usepackage{amsmath}
+\usepackage{graphicx}
+\usepackage{color}
+\usepackage{multirow}
+\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+\usepackage[a4paper,margin=2cm,nohead]{geometry}
+%% generator Docutils: http://docutils.sourceforge.net/
+\newlength{\admonitionwidth}
+\setlength{\admonitionwidth}{0.9\textwidth}
+\newlength{\docinfowidth}
+\setlength{\docinfowidth}{0.9\textwidth}
+\newcommand{\optionlistlabel}[1]{\bf #1 \hfill}
+\newenvironment{optionlist}[1]
+{\begin{list}{}
+ {\setlength{\labelwidth}{#1}
+ \setlength{\rightmargin}{1cm}
+ \setlength{\leftmargin}{\rightmargin}
+ \addtolength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \renewcommand{\makelabel}{\optionlistlabel}}
+}{\end{list}}
+% begin: floats for footnotes tweaking.
+\setlength{\floatsep}{0.5em}
+\setlength{\textfloatsep}{\fill}
+\addtolength{\textfloatsep}{3em}
+\renewcommand{\textfraction}{0.5}
+\renewcommand{\topfraction}{0.5}
+\renewcommand{\bottomfraction}{0.5}
+\setcounter{totalnumber}{50}
+\setcounter{topnumber}{50}
+\setcounter{bottomnumber}{50}
+% end floats for footnotes
+% some commands, that could be overwritten in the style file.
+\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}}
+% end of "some commands"
+\input{/mnt/exp/MyDocs/pypers/style.tex}
+\title{Documentation of the oopp module}
+\author{}
+\date{}
+\hypersetup{
+pdftitle={Documentation of the oopp module}
+}
+\raggedbottom
+\begin{document}
+\maketitle
+
+
+
+%___________________________________________________________________________
+
+\hypertarget{documented-metaclasses}{}
+\section*{Documented metaclasses}
+\pdfbookmark[0]{Documented metaclasses}{documented-metaclasses}
+
+\texttt{Final(type): {\#} better derived from WithCounter,typ}
+\begin{quote}
+
+Instances of Final cannot be derived
+\end{quote}
+
+\texttt{AutoWrapped(type)}
+\begin{quote}
+
+Metaclass that looks at the methods declared in the attributes
+builtinlist and wraplist of its instances and wraps them with
+autowrappedmethod.
+\end{quote}
+
+\texttt{Wrapped(Customizable,type)}
+\begin{quote}
+
+A customizable metaclass to wrap methods with a given wrapper and
+a given condition
+\begin{quote}
+
+\texttt{Reflective(type)}
+\begin{quote}
+
+Cooperative metaclass that defines the private variable {\_}{\_}this in
+its instances. {\_}{\_}this contains a reference to the class, therefore
+it allows anonymous cooperative super calls in the class.
+\end{quote}
+
+\texttt{wrappedmethod(Customizable)}
+\begin{quote}
+
+Customizable method factory intended for derivation.
+The wrapper method is overridden in the children.
+\end{quote}
+\end{quote}
+\end{quote}
+
+\texttt{Cooperative(BracketCallable,type)}
+\begin{quote}
+
+Bracket-callable metaclass implementing cooperative methods. Works
+well for plain methods returning None, such as {\_}{\_}init{\_}{\_}
+
+\texttt{coop{\_}method(cls,name,method): {\#} method can be Non}
+\begin{quote}
+
+Calls both the superclass method and the class method (if the
+class has an explicit method). Implemented via a closure
+\end{quote}
+\end{quote}
+
+\texttt{Logged(WithLogger,Reflective)}
+\begin{quote}
+
+Metaclass that reuses the features provided by WithLogger.
+In particular the classes created by Logged are Reflective,
+PrettyPrinted and Customizable.
+\end{quote}
+
+\texttt{MagicallyTransformed(type)}
+\begin{quote}
+
+Metaclass changing the formatstring of its instances
+\end{quote}
+
+\texttt{Printable(PrettyPrinted,type)}
+\begin{quote}
+
+Apparently does nothing, but actually makes PrettyPrinted acting as
+a metaclass.
+\end{quote}
+
+
+%___________________________________________________________________________
+
+\hypertarget{documented-classes}{}
+\section*{Documented classes}
+\pdfbookmark[0]{Documented classes}{documented-classes}
+
+\texttt{convert2descriptor(object)}
+\begin{quote}
+
+To all practical means, this class acts as a function that, given an
+object, adds to it a {\_}{\_}get{\_}{\_} method if it is not already there. The
+added {\_}{\_}get{\_}{\_} method is trivial and simply returns the original object,
+independently from obj and cls.
+
+\texttt{{\_}{\_}get{\_}{\_}(self,obj,cls=None)}
+\begin{quote}
+
+Returns self.a independently from obj and cls
+\end{quote}
+\end{quote}
+
+\texttt{Object(object)}
+\begin{quote}
+
+A convenient Object class
+\end{quote}
+
+\texttt{GeometricFigure(object): {\#}an example of object factor}
+\begin{quote}
+
+This class allows to define geometric figures according to their
+equation in the cartesian plane. It will be extended later.
+
+\texttt{{\_}{\_}init{\_}{\_}(self,equation,**parameters)}
+\begin{quote}
+
+Specify the cartesian equation of the object and its parameters
+\end{quote}
+\end{quote}
+
+\texttt{UglyDuckling(PrettyPrinted)}
+\begin{quote}
+
+A plain, regular class
+\end{quote}
+
+\texttt{autowrappedmethod(wrappedmethod)}
+\begin{quote}
+
+Makes the method returning cls instances, by wrapping its
+output with cls
+\end{quote}
+
+\texttt{Clock(object)}
+\begin{quote}
+
+Clock with a staticmethod
+\end{quote}
+
+\texttt{AccessError(object)}
+\begin{quote}
+
+Descriptor raising an AttributeError when the attribute is
+accessed
+\end{quote}
+
+\texttt{Frozen(object)}
+\begin{quote}
+
+Subclasses of Frozen are frozen, i.e. it is impossibile to add
+new attributes to them and their instances
+\end{quote}
+
+\texttt{Timer(Clock)}
+\begin{quote}
+
+Inherits the get{\_}time staticmethod from Clock
+\end{quote}
+
+\texttt{Vector(list)}
+\begin{quote}
+
+Implements finite dimensional vectors as lists. Can be instantiated
+as Vector([a,b,c,..]) or as Vector(a,b,c ..)
+\end{quote}
+
+\texttt{Singleton(WithCounter)}
+\begin{quote}
+
+If you inherit from me, you can only have one instance
+\end{quote}
+
+\texttt{Homo(PrettyPrinted)}
+\begin{quote}
+
+Defines the method 'can', which is intended to be overriden
+in the children classes, and inherits '{\_}{\_}str{\_}{\_}' from PrettyPrinted,
+ensuring a nice printing representation for all children.
+\end{quote}
+
+\texttt{kwdict(dict)}
+\begin{quote}
+
+Keyword dictionary base class
+
+\texttt{pretty(dic)}
+\begin{quote}
+
+Returns a nice string representation for the dictionary
+\end{quote}
+\end{quote}
+
+\texttt{WithLogger(WithCounter,PrettyPrinted)}
+\begin{quote}
+
+WithLogger inherits from WithCounter the 'count' class attribute;
+moreover it inherits '{\_}{\_}str{\_}{\_}' from PrettyPrinted
+\end{quote}
+
+\texttt{Get(object)}
+\begin{quote}
+
+Invoked as Get(cls)(xxx) where xxx = staticmethod, classmethod,
+property, plainmethod, plaindata, returns the corresponding
+attributes as a keyword dictionary. It works by internally calling
+the routine inspect.classify{\_}class{\_}attrs. Notice that special data
+attributes are not retrieved (this is by design).
+\end{quote}
+
+\texttt{Makeobj(object)}
+\begin{quote}
+
+A factory of object factories. Makeobj(cls) returns instances
+of cls
+\end{quote}
+
+\texttt{ExampleBaseClass(PrettyPrinted)}
+\begin{quote}
+
+Contains a regular method 'm', a staticmethod 's', a classmethod
+'c', a property 'p' and a data attribute 'd'.
+\end{quote}
+
+\texttt{TransformedUglyDuckling(PrettyPrinted)}
+\begin{quote}
+
+A class metamagically modified
+\end{quote}
+
+\texttt{Customizable(object)}
+\begin{quote}
+
+Classes inhering from 'Customizable' have a 'with' method acting as
+an object modifier and 'With' classmethod acting as a class factory
+\end{quote}
+
+\texttt{WithMultiCounter(WithCounter)}
+\begin{quote}
+
+Each time a new subclass is derived, the counter is reset
+\end{quote}
+
+\texttt{BracketCallable(object)}
+\begin{quote}
+
+Any subclass C(BracketCallable) can be called with the syntax C[t],
+where t is a tuple of arguments stored in bracket{\_}args; returns the
+class or an instance of it, depending on the flag 'returnclass'.
+\end{quote}
+
+\texttt{ClsFactory(BracketCallable)}
+\begin{quote}
+\begin{description}
+%[visit_definition_list_item]
+\item[Bracket callable non-cooperative class acting as :]
+%[visit_definition]
+
+a factory of class factories.
+ClsFactory instances are class factories accepting 0,1,2 or 3 arguments.
+
+%[depart_definition]
+%[depart_definition_list_item]
+%[visit_definition_list_item]
+\item[. They automatically converts functions to static methods :]
+%[visit_definition]
+
+if the input object is not a class. If an explicit name is not passed
+the name of the created class is obtained by adding an underscore to
+the name of the original object.
+
+%[depart_definition]
+%[depart_definition_list_item]
+\end{description}
+
+\texttt{{\_}{\_}call{\_}{\_}(self, *args)}
+\begin{quote}
+
+Generates a new class using self.meta and avoiding conflicts.
+The first metaobject can be a dictionary, an object with a
+dictionary (except a class), or a simple name.
+\end{quote}
+\end{quote}
+
+\texttt{WithCounter(object)}
+\begin{quote}
+
+Mixin class counting the total number of its instances and storing
+it in the class attribute counter.
+\end{quote}
+
+
+%___________________________________________________________________________
+
+\hypertarget{documented-functions}{}
+\section*{Documented functions}
+\pdfbookmark[0]{Documented functions}{documented-functions}
+
+\texttt{mandelbrot(row,col)}
+\begin{quote}
+
+Computes the Mandelbrot set in one line
+\end{quote}
+
+\texttt{with{\_}tracer(function,namespace='{\_}{\_}main{\_}{\_}',output=sys.stdout, indent=[0])}
+\begin{quote}
+
+Closure returning traced functions. It is typically invoked
+trough an auxiliary function fixing the parameters of with{\_}tracer.
+\end{quote}
+
+\texttt{ancestor(C,S=None)}
+\begin{quote}
+
+Returns the ancestors of the first argument with respect to the
+MRO of the second argument. If the second argument is None, then
+returns the MRO of the first argument.
+\end{quote}
+
+\texttt{customize(obj,errfile=None,**kw)}
+\begin{quote}
+
+Adds attributes to an object, if possible. If not, writes an error
+message on 'errfile'. If errfile is None, skips the exception.
+\end{quote}
+
+\texttt{loop{\_}overhead(N)}
+\begin{quote}
+
+Computes the time spent in empty loop of N iterations
+\end{quote}
+
+\texttt{indent(block,n)}
+\begin{quote}
+
+Indent a block of code by n spaces
+\end{quote}
+
+\texttt{totuple(arg)}
+\begin{quote}
+
+Converts the argument to a tuple, if need there is
+\end{quote}
+
+\texttt{attributes(obj,condition=lambda n,v: not special(n))}
+\begin{quote}
+
+Returns a dictionary containing the accessible attributes of
+an object. By default, returns the non-special attributes only.
+\end{quote}
+
+\texttt{generateblocks(regexp,text)}
+\begin{quote}
+
+Generator splitting text in blocks according to regexp
+\end{quote}
+
+\texttt{wrapfunctions(obj,wrapper,err=None,**options)}
+\begin{quote}
+
+Traces the callable objects in an object with a dictionary
+\end{quote}
+
+\texttt{wrap(obj,wrapped,condition=lambda k,v: True, err=None)}
+\begin{quote}
+
+Retrieves obj's dictionary and wraps it
+\end{quote}
+
+\texttt{reflective(*classes)}
+\begin{quote}
+
+Reflective classes know themselves, i.e. they own a private
+attribute {\_}{\_}this containing a reference to themselves. If the class
+name starts with '{\_}', the underscores are stripped. This is needed
+to make the mangling mechanism work.
+\end{quote}
+
+\texttt{withmemory(f)}
+\begin{quote}
+
+This closure invokes the callable object f only if need there is
+\end{quote}
+
+\texttt{get{\_}time()}
+\begin{quote}
+
+Return the time of the system in the format HH:MM:SS
+\end{quote}
+
+\texttt{prn(s)}
+\begin{quote}
+
+Given an evaluable string, print its value and its object reference.
+Notice that the evaluation is done in the {\_}{\_}main{\_}{\_} dictionary.
+\end{quote}
+
+\texttt{isplaindata(a)}
+\begin{quote}
+
+A data attribute has no {\_}{\_}get{\_}{\_} or {\_}{\_}set{\_}{\_} attributes, is not
+a built-in function, nor a built-in method.
+\end{quote}
+
+\texttt{Pizza(toppings,**dic)}
+\begin{quote}
+
+This function produces classes inheriting from GenericPizza and
+WithLogger, using a metaclass inferred from Logged
+\end{quote}
+
+\texttt{modulesub(s,r,module)}
+\begin{quote}
+
+Requires 2.3
+\end{quote}
+
+\texttt{memoize(f)}
+\begin{quote}
+
+This closure remembers all f invocations
+\end{quote}
+
+\texttt{with{\_}timer(func, modulename='{\_}{\_}main{\_}{\_}', n=1, logfile=sys.stdout)}
+\begin{quote}
+
+Wraps the function func and executes it n times (default n=1).
+The average time spent in one iteration, express in milliseconds,
+is stored in the attributes func.time and func.CPUtime, and saved
+in a log file which defaults to the standard output.
+\end{quote}
+
+\texttt{dedent(text)}
+\begin{quote}
+
+dedent(text : string) -{$>$} string
+\begin{quote}
+\begin{quote}
+
+Remove any whitespace than can be uniformly removed from the left
+of every line in text.
+
+This can be used e.g. to make triple-quoted strings line up with
+the left edge of screen/whatever, while still presenting it in the
+source code in indented form.
+
+For example:
+\begin{quote}
+\begin{quote}
+\begin{description}
+%[visit_definition_list_item]
+\item[def test()::]
+%[visit_definition]
+
+{\#} end first line with to avoid the empty line!
+s = ''' hello
+
+Unexpected indentation.
+
+\begin{quote}
+
+world
+\end{quote}
+
+Block quote ends without a blank line; unexpected unindent.
+
+
+'''
+print repr(s) {\#} prints ' hello
+
+%[depart_definition]
+%[depart_definition_list_item]
+\end{description}
+\end{quote}
+
+Block quote ends without a blank line; unexpected unindent.
+
+
+world
+\end{quote}
+
+Block quote ends without a blank line; unexpected unindent.
+
+\begin{description}
+%[visit_definition_list_item]
+\item[':]
+%[visit_definition]
+
+print repr(dedent(s)) {\#} prints 'hello
+
+%[depart_definition]
+%[depart_definition_list_item]
+\end{description}
+\end{quote}
+
+Block quote ends without a blank line; unexpected unindent.
+
+
+world
+\end{quote}
+
+Block quote ends without a blank line; unexpected unindent.
+
+
+'
+\end{quote}
+
+\texttt{makecls(*metas,**options)}
+\begin{quote}
+
+Class factory avoiding metatype conflicts. The invocation syntax is
+makecls(M1,M2,..,priority=1)(name,bases,dic). If the base classes have
+metaclasses conflicting within themselves or with the given metaclasses,
+it automatically generates a compatible metaclass and instantiate it.
+If priority is True, the given metaclasses have priority over the
+bases' metaclasses
+\end{quote}
+
+\end{document}
diff --git a/pypers/pep318/post.txt b/pypers/pep318/post.txt
new file mode 100755
index 0000000..cfbb221
--- /dev/null
+++ b/pypers/pep318/post.txt
@@ -0,0 +1,21 @@
+Instructions:
+
+1. Download the file ``decorators.zip`` from my home-page:
+
+ http://www.phyast.pitt.edu/~micheles/python/decorators.zip
+
+2. Unzip it in a directory, for instance:
+
+ ``unzip decorators -d decorators``
+
+3. Test that everything works:
+
+ ``cd decorators; python doct.py decorators.txt``
+
+4. Add the decorators directory to your Python path or copy the files
+ decorators.py, noconflict.py, debugger.py into your Python distribution.
+
+5. It is always a good idea to give a look to the README.txt file.
+
+Notice: Python 2.3 is required. I have tested that it works (at least for
+me) both under Red Hat 7.3 and under Windows 98SE.
diff --git a/pypers/pep318/printerr.py b/pypers/pep318/printerr.py
new file mode 100755
index 0000000..7de2333
--- /dev/null
+++ b/pypers/pep318/printerr.py
@@ -0,0 +1,7 @@
+err=file('err','w')
+
+def printerr(*args):
+ "For debugging purposes"
+ for a in args: print >> err, a,
+ print >> err
+
diff --git a/pypers/pep318/prnt.py b/pypers/pep318/prnt.py
new file mode 100755
index 0000000..cb56674
--- /dev/null
+++ b/pypers/pep318/prnt.py
@@ -0,0 +1,7 @@
+# prnt.py
+
+import sys
+f=sys.stdout
+
+def hello():
+ print >> f,'hello'
diff --git a/pypers/pep318/pro.py b/pypers/pep318/pro.py
new file mode 100755
index 0000000..d875d55
--- /dev/null
+++ b/pypers/pep318/pro.py
@@ -0,0 +1,28 @@
+"""Funziona solo se e' composto una sola volta, senno' ricorsione
+infinita""" # ??
+
+import customdec,__builtin__
+__builtin__.type=customdec.type
+__builtin__.object=customdec.TraceFunctions(object)
+print __builtin__.object.__mro__
+
+__builtin__.object=customdec.Decorated(customdec.TraceFunctions(object))
+print __builtin__.object.__mro__
+
+#raise SystemExit
+
+#__builtin__.object=customdec.TraceFunctions(object)
+from tracing import E
+e=E()
+print E,type(type(E))
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pypers/pep318/pro1.py b/pypers/pep318/pro1.py
new file mode 100755
index 0000000..a9c2e0f
--- /dev/null
+++ b/pypers/pep318/pro1.py
@@ -0,0 +1,7 @@
+# pro1.py
+import sys
+f=sys.stdout
+a='ciao'
+def prn():
+ print >> f, a
+
diff --git a/pypers/pep318/pro1.txt b/pypers/pep318/pro1.txt
new file mode 100755
index 0000000..c75b12a
--- /dev/null
+++ b/pypers/pep318/pro1.txt
@@ -0,0 +1,10 @@
+#<pro1.py>
+import sys
+f=sys.stdout
+a='ciao'
+def prn():
+ print >> f, a
+#</pro1.py>
+>>> import pro1
+>>> pro1.prn()
+ciao
diff --git a/pypers/pep318/pro2.py b/pypers/pep318/pro2.py
new file mode 100755
index 0000000..58cffb4
--- /dev/null
+++ b/pypers/pep318/pro2.py
@@ -0,0 +1,24 @@
+from customdec import *
+
+def f(self): pass
+
+tracedf=tracedmethod(f)
+tracedtracedf=decorated(tracedmethod(f))
+
+class C: pass
+
+c=C()
+
+C.f=tracedtracedf
+
+c.f()
+
+class Chatty(ClassDecorator):
+ def __init__(cls,*args):
+ print 'Chatty.__init__'
+
+class C:pass
+
+
+
+C=Chatty(Chatty(C))
diff --git a/pypers/pep318/pro2.txt b/pypers/pep318/pro2.txt
new file mode 100755
index 0000000..70dbcd4
--- /dev/null
+++ b/pypers/pep318/pro2.txt
@@ -0,0 +1,3 @@
+>>> import pro1
+>>> pro1.prn()
+ciao
diff --git a/pypers/pep318/psyco.tex b/pypers/pep318/psyco.tex
new file mode 100755
index 0000000..93dcc9f
--- /dev/null
+++ b/pypers/pep318/psyco.tex
@@ -0,0 +1,201 @@
+\documentclass[10pt,english]{article}
+\usepackage{babel}
+\usepackage{shortvrb}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\usepackage{longtable}
+\setlength{\extrarowheight}{2pt}
+\usepackage{amsmath}
+\usepackage{graphicx}
+\usepackage{color}
+\usepackage{multirow}
+\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+\usepackage[a4paper,margin=2cm,nohead]{geometry}
+%% generator Docutils: http://docutils.sourceforge.net/
+\newlength{\admonitionwidth}
+\setlength{\admonitionwidth}{0.9\textwidth}
+\newlength{\docinfowidth}
+\setlength{\docinfowidth}{0.9\textwidth}
+\newcommand{\optionlistlabel}[1]{\bf #1 \hfill}
+\newenvironment{optionlist}[1]
+{\begin{list}{}
+ {\setlength{\labelwidth}{#1}
+ \setlength{\rightmargin}{1cm}
+ \setlength{\leftmargin}{\rightmargin}
+ \addtolength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \renewcommand{\makelabel}{\optionlistlabel}}
+}{\end{list}}
+% begin: floats for footnotes tweaking.
+\setlength{\floatsep}{0.5em}
+\setlength{\textfloatsep}{\fill}
+\addtolength{\textfloatsep}{3em}
+\renewcommand{\textfraction}{0.5}
+\renewcommand{\topfraction}{0.5}
+\renewcommand{\bottomfraction}{0.5}
+\setcounter{totalnumber}{50}
+\setcounter{topnumber}{50}
+\setcounter{bottomnumber}{50}
+% end floats for footnotes
+% some commands, that could be overwritten in the style file.
+\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}}
+% end of "some commands"
+\input{/mnt/exp/MyDocs/pypers/style.tex}
+\title{Module psyco}
+\author{}
+\date{}
+\hypersetup{
+pdftitle={Module psyco}
+}
+\raggedbottom
+\begin{document}
+\maketitle
+
+
+Psyco -- the Python Specializing Compiler.
+
+Typical usage: add the following lines to your application's main module:
+\begin{description}
+%[visit_definition_list_item]
+\item[try::]
+%[visit_definition]
+
+import psyco
+psyco.profile()
+
+%[depart_definition]
+%[depart_definition_list_item]
+%[visit_definition_list_item]
+\item[except::]
+%[visit_definition]
+
+print 'Psyco not found, ignoring it'
+
+%[depart_definition]
+%[depart_definition_list_item]
+\end{description}
+
+
+%___________________________________________________________________________
+
+\hypertarget{functions}{}
+\section*{Functions}
+\pdfbookmark[0]{Functions}{functions}
+
+\texttt{cannotcompile(x):}
+\begin{quote}
+
+Instruct Psyco never to compile the given function, method
+or code object.
+\end{quote}
+
+\texttt{log(logfile='', mode='w', top=10):}
+\begin{quote}
+
+Enable logging to the given file.
+
+If the file name is unspecified, a default name is built by appending
+a 'log-psyco' extension to the main script name.
+
+Mode is 'a' to append to a possibly existing file or 'w' to overwrite
+an existing file. Note that the log file may grow quickly in 'a' mode.
+\end{quote}
+
+\texttt{runonly(memory=None, time=None, memorymax=None, timemax=None):}
+\begin{quote}
+
+Nonprofiler.
+
+XXX check if this is useful and document.
+\end{quote}
+
+\texttt{profile(watermark = default{\_}watermark,}
+\begin{quote}
+
+Turn on profiling.
+
+The 'watermark' parameter controls how easily running functions will
+be compiled. The smaller the value, the more functions are compiled.
+\end{quote}
+
+\texttt{full(memory=None, time=None, memorymax=None, timemax=None):}
+\begin{quote}
+
+Compile as much as possible.
+
+Typical use is for small scripts performing intensive computations
+or string handling.
+\end{quote}
+
+\texttt{dumpcodebuf():}
+\begin{quote}
+
+Write in file psyco.dump a copy of the emitted machine code,
+provided Psyco was compiled with a non-zero CODE{\_}DUMP.
+See py-utils/httpxam.py to examine psyco.dump.
+\end{quote}
+
+\texttt{stop():}
+\begin{quote}
+
+Turn off all automatic compilation. bind() calls remain in effect.
+\end{quote}
+
+\texttt{proxy(x, rec=None):}
+\begin{quote}
+
+Return a Psyco-enabled copy of the function.
+
+The original function is still available for non-compiled calls.
+The optional second argument specifies the number of recursive
+compilation levels: all functions called by func are compiled
+up to the given depth of indirection.
+\end{quote}
+
+\texttt{background(watermark = default{\_}watermark,}
+\begin{quote}
+
+Turn on passive profiling.
+
+This is a very lightweight mode in which only intensively computing
+functions can be detected. The smaller the 'watermark', the more functions
+are compiled.
+\end{quote}
+
+\texttt{unbind(x):}
+\begin{quote}
+
+Reverse of bind().
+\end{quote}
+
+\texttt{bind(x, rec=None):}
+\begin{quote}
+
+Enable compilation of the given function, method, or class object.
+
+If C is a class (or anything with a '{\_}{\_}dict{\_}{\_}' attribute), bind(C) will
+rebind all functions and methods found in C.{\_}{\_}dict{\_}{\_} (which means, for
+classes, all methods defined in the class but not in its parents).
+
+The optional second argument specifies the number of recursive
+compilation levels: all functions called by func are compiled
+up to the given depth of indirection.
+\end{quote}
+
+\texttt{{\_}getemulframe(depth=0):}
+\begin{quote}
+
+As {\_}getframe(), but the returned objects are real Python frame objects
+emulating Psyco frames. Some of their attributes can be wrong or missing,
+however.
+\end{quote}
+
+\texttt{unproxy(proxy):}
+\begin{quote}
+
+Return a new copy of the original function of method behind a proxy.
+The result behaves like the original function in that calling it
+does not trigger compilation nor execution of any compiled code.
+\end{quote}
+
+\end{document}
diff --git a/pypers/pep318/pydoc.html b/pypers/pep318/pydoc.html
new file mode 100755
index 0000000..8de6660
--- /dev/null
+++ b/pypers/pep318/pydoc.html
@@ -0,0 +1,508 @@
+
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Python: module decorators</title>
+</head><body bgcolor="#f0f0f8">
+
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="#7799ee">
+<td valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>decorators</strong></big></big></font></td
+><td align=right valign=bottom
+><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/mnt/exp/MyDocs/pypers/pep318/decorators.py">/mnt/exp/MyDocs/pypers/pep318/decorators.py</a></font></td></tr></table>
+ <p><tt>A&nbsp;module&nbsp;to&nbsp;implement&nbsp;pep318&nbsp;(decorator&nbsp;syntax)&nbsp;via&nbsp;magic&nbsp;doctrings.<br>
+For&nbsp;the&nbsp;documentation&nbsp;see<br>
+&nbsp;<br>
+<a href="http://www.phyast.pitt.edu/~micheles/python/decorators,html">http://www.phyast.pitt.edu/~micheles/python/decorators,html</a><br>
+&nbsp;<br>
+and&nbsp;the&nbsp;on-line&nbsp;help.</tt></p>
+<p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#aa55cc">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#fffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
+
+<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="__builtin__.html">__builtin__</a><br>
+<a href="inspect.html">inspect</a><br>
+</td><td width="25%" valign=top><a href="noconflict.html">noconflict</a><br>
+<a href="re.html">re</a><br>
+</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
+</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ee77aa">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
+
+<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><dl>
+<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#UnknownDecoratorError">UnknownDecoratorError</a>
+</font></dt></dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#Decorator">Decorator</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#ClassDecorator">ClassDecorator</a>(<a href="__builtin__.html#type">__builtin__.type</a>, <a href="decorators.html#Decorator">Decorator</a>)
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#Decorated">Decorated</a>
+</font></dt></dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="decorators.html#MethodDecorator">MethodDecorator</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#classmethod">classmethod</a>
+</font></dt><dt><font face="helvetica, arial"><a href="decorators.html#staticmethod">staticmethod</a>
+</font></dt></dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="__builtin__.html#type">__builtin__.type</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#ClassDecorator">ClassDecorator</a>(<a href="__builtin__.html#type">__builtin__.type</a>, <a href="decorators.html#Decorator">Decorator</a>)
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#Decorated">Decorated</a>
+</font></dt></dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="decorators.html#MetaDecorator">MetaDecorator</a>
+</font></dt></dl>
+</dd>
+</dl>
+ <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="ClassDecorator">class <strong>ClassDecorator</strong></a>(<a href="__builtin__.html#type">__builtin__.type</a>, <a href="decorators.html#Decorator">Decorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Metaclass&nbsp;callable&nbsp;with&nbsp;one&nbsp;or&nbsp;three&nbsp;arguments,&nbsp;having&nbsp;its&nbsp;calling<br>
+syntax&nbsp;redefined&nbsp;by&nbsp;the&nbsp;meta-metaclass&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.&nbsp;It&nbsp;redefines<br>
+__str__&nbsp;both&nbsp;on&nbsp;classes&nbsp;and&nbsp;instances.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#ClassDecorator">ClassDecorator</a></dd>
+<dd><a href="__builtin__.html#type">__builtin__.type</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="ClassDecorator-__init__"><strong>__init__</strong></a>(cls, name, bases, dic)</dt></dl>
+
+<dl><dt><a name="ClassDecorator-__str__"><strong>__str__</strong></a>(cls)</dt></dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><a name="ClassDecorator-__call__"><strong>__call__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__call__">__call__</a>(...)&nbsp;&lt;==&gt;&nbsp;x(...)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__cmp__"><strong>__cmp__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__cmp__">__cmp__</a>(y)&nbsp;&lt;==&gt;&nbsp;cmp(x,y)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__subclasses__"><strong>__subclasses__</strong></a>(...)</dt><dd><tt><a href="#ClassDecorator-__subclasses__">__subclasses__</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;immediate&nbsp;subclasses</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-mro"><strong>mro</strong></a>(...)</dt><dd><tt><a href="#ClassDecorator-mro">mro</a>()&nbsp;-&gt;&nbsp;list<br>
+return&nbsp;a&nbsp;<a href="__builtin__.html#type">type</a>'s&nbsp;method&nbsp;resolution&nbsp;order</tt></dd></dl>
+
+<hr>
+Data and other attributes inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><strong>__base__</strong> = &lt;type 'type'&gt;</dl>
+
+<dl><dt><strong>__bases__</strong> = (&lt;type 'type'&gt;, &lt;class 'decorators.Decorator'&gt;)</dl>
+
+<dl><dt><strong>__basicsize__</strong> = 420</dl>
+
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;</dl>
+
+<dl><dt><strong>__dictoffset__</strong> = 132</dl>
+
+<dl><dt><strong>__flags__</strong> = 22523</dl>
+
+<dl><dt><strong>__itemsize__</strong> = 20</dl>
+
+<dl><dt><strong>__mro__</strong> = (&lt;class 'decorators.ClassDecorator'&gt;, &lt;type 'type'&gt;, &lt;class 'decorators.Decorator'&gt;, &lt;type 'object'&gt;)</dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ClassDecorator-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;<a href="__builtin__.html#type">type</a>&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>__weakrefoffset__</strong> = 184</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined&nbsp;in&nbsp;any&nbsp;module,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in<br>
+&nbsp;&nbsp;&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+2.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+&nbsp;&nbsp;&nbsp;is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>
+3.&nbsp;Decorators&nbsp;calls&nbsp;are&nbsp;dispatched&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_<br>
+&nbsp;&nbsp;&nbsp;<a href="#classmethod">classmethod</a>.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="Decorated">class <strong>Decorated</strong></a>(<a href="decorators.html#ClassDecorator">ClassDecorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Metaclass&nbsp;which&nbsp;decorates&nbsp;its&nbsp;instances<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#Decorated">Decorated</a></dd>
+<dd><a href="decorators.html#ClassDecorator">ClassDecorator</a></dd>
+<dd><a href="__builtin__.html#type">__builtin__.type</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="Decorated-__init__"><strong>__init__</strong></a>(cls, name, bases, dic)</dt></dl>
+
+<hr>
+Methods inherited from <a href="decorators.html#ClassDecorator">ClassDecorator</a>:<br>
+<dl><dt><a name="Decorated-__str__"><strong>__str__</strong></a>(cls)</dt></dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><a name="Decorated-__call__"><strong>__call__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__call__">__call__</a>(...)&nbsp;&lt;==&gt;&nbsp;x(...)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__cmp__"><strong>__cmp__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__cmp__">__cmp__</a>(y)&nbsp;&lt;==&gt;&nbsp;cmp(x,y)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__subclasses__"><strong>__subclasses__</strong></a>(...)</dt><dd><tt><a href="#Decorated-__subclasses__">__subclasses__</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;immediate&nbsp;subclasses</tt></dd></dl>
+
+<dl><dt><a name="Decorated-mro"><strong>mro</strong></a>(...)</dt><dd><tt><a href="#Decorated-mro">mro</a>()&nbsp;-&gt;&nbsp;list<br>
+return&nbsp;a&nbsp;<a href="__builtin__.html#type">type</a>'s&nbsp;method&nbsp;resolution&nbsp;order</tt></dd></dl>
+
+<hr>
+Data and other attributes inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><strong>__base__</strong> = &lt;class 'decorators.ClassDecorator'&gt;</dl>
+
+<dl><dt><strong>__bases__</strong> = (&lt;class 'decorators.ClassDecorator'&gt;,)</dl>
+
+<dl><dt><strong>__basicsize__</strong> = 420</dl>
+
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;</dl>
+
+<dl><dt><strong>__dictoffset__</strong> = 132</dl>
+
+<dl><dt><strong>__flags__</strong> = 22523</dl>
+
+<dl><dt><strong>__itemsize__</strong> = 20</dl>
+
+<dl><dt><strong>__mro__</strong> = (&lt;class 'decorators.Decorated'&gt;, &lt;class 'decorators.ClassDecorator'&gt;, &lt;type 'type'&gt;, &lt;class 'decorators.Decorator'&gt;, &lt;type 'object'&gt;)</dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#Decorated-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;<a href="__builtin__.html#type">type</a>&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>__weakrefoffset__</strong> = 184</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined&nbsp;in&nbsp;any&nbsp;module,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in<br>
+&nbsp;&nbsp;&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+2.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+&nbsp;&nbsp;&nbsp;is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>
+3.&nbsp;Decorators&nbsp;calls&nbsp;are&nbsp;dispatched&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_<br>
+&nbsp;&nbsp;&nbsp;<a href="#classmethod">classmethod</a>.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="Decorator">class <strong>Decorator</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Instance&nbsp;of&nbsp;<a href="#MetaDecorator">MetaDecorator</a>&nbsp;and&nbsp;mothers&nbsp;of&nbsp;all&nbsp;decorators.&nbsp;When&nbsp;called<br>
+in&nbsp;the&nbsp;form&nbsp;<a href="#Decorator">Decorator</a>(obj),&nbsp;with&nbsp;obj&nbsp;having&nbsp;a&nbsp;magic&nbsp;docstring,&nbsp;it&nbsp;returns<br>
+an&nbsp;instance&nbsp;of&nbsp;the&nbsp;correct&nbsp;decorator,&nbsp;otherwise&nbsp;it&nbsp;returns&nbsp;None.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%">Data and other attributes defined here:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined&nbsp;in&nbsp;any&nbsp;module,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in<br>
+&nbsp;&nbsp;&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+2.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+&nbsp;&nbsp;&nbsp;is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>
+3.&nbsp;Decorators&nbsp;calls&nbsp;are&nbsp;dispatched&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_<br>
+&nbsp;&nbsp;&nbsp;<a href="#classmethod">classmethod</a>.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="MetaDecorator">class <strong>MetaDecorator</strong></a>(<a href="__builtin__.html#type">__builtin__.type</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined&nbsp;in&nbsp;any&nbsp;module,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in<br>
+&nbsp;&nbsp;&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+2.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+&nbsp;&nbsp;&nbsp;is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>
+3.&nbsp;Decorators&nbsp;calls&nbsp;are&nbsp;dispatched&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_<br>
+&nbsp;&nbsp;&nbsp;<a href="#classmethod">classmethod</a>.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#MetaDecorator">MetaDecorator</a></dd>
+<dd><a href="__builtin__.html#type">__builtin__.type</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="MetaDecorator-__call__"><strong>__call__</strong></a>(dec, *args)</dt></dl>
+
+<dl><dt><a name="MetaDecorator-__init__"><strong>__init__</strong></a>(dec, *args)</dt></dl>
+
+<hr>
+Data and other attributes defined here:<br>
+<dl><dt><strong>dic</strong> = {'ClassDecorator': &lt;class 'decorators.ClassDecorator'&gt;, 'Decorated': &lt;class 'decorators.Decorated'&gt;, 'Decorator': &lt;class 'decorators.Decorator'&gt;, 'MethodDecorator': &lt;class 'decorators.MethodDecorator'&gt;, 'classmethod': &lt;class 'decorators.classmethod'&gt;, 'staticmethod': &lt;class 'decorators.staticmethod'&gt;}</dl>
+
+<dl><dt><strong>ls</strong> = [&lt;class 'decorators.Decorator'&gt;, &lt;class 'decorators.MethodDecorator'&gt;, &lt;class 'decorators.ClassDecorator'&gt;, &lt;class 'decorators.Decorated'&gt;, &lt;class 'decorators.staticmethod'&gt;, &lt;class 'decorators.classmethod'&gt;]</dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><a name="MetaDecorator-__cmp__"><strong>__cmp__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__cmp__">__cmp__</a>(y)&nbsp;&lt;==&gt;&nbsp;cmp(x,y)</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__subclasses__"><strong>__subclasses__</strong></a>(...)</dt><dd><tt><a href="#MetaDecorator-__subclasses__">__subclasses__</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;immediate&nbsp;subclasses</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-mro"><strong>mro</strong></a>(...)</dt><dd><tt><a href="#MetaDecorator-mro">mro</a>()&nbsp;-&gt;&nbsp;list<br>
+return&nbsp;a&nbsp;<a href="__builtin__.html#type">type</a>'s&nbsp;method&nbsp;resolution&nbsp;order</tt></dd></dl>
+
+<hr>
+Data and other attributes inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><strong>__base__</strong> = &lt;type 'type'&gt;</dl>
+
+<dl><dt><strong>__bases__</strong> = (&lt;type 'type'&gt;,)</dl>
+
+<dl><dt><strong>__basicsize__</strong> = 420</dl>
+
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;</dl>
+
+<dl><dt><strong>__dictoffset__</strong> = 132</dl>
+
+<dl><dt><strong>__flags__</strong> = 22523</dl>
+
+<dl><dt><strong>__itemsize__</strong> = 20</dl>
+
+<dl><dt><strong>__mro__</strong> = (&lt;class 'decorators.MetaDecorator'&gt;, &lt;type 'type'&gt;, &lt;type 'object'&gt;)</dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MetaDecorator-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;<a href="__builtin__.html#type">type</a>&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>__weakrefoffset__</strong> = 184</dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="MethodDecorator">class <strong>MethodDecorator</strong></a>(<a href="decorators.html#Decorator">Decorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Descriptor&nbsp;class&nbsp;callable&nbsp;with&nbsp;a&nbsp;function&nbsp;as&nbsp;argument.&nbsp;The&nbsp;calling<br>
+syntax&nbsp;is&nbsp;redefined&nbsp;by&nbsp;the&nbsp;meta-metaclass&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.&nbsp;It&nbsp;redefines<br>
+__str__&nbsp;and&nbsp;get&nbsp;(i.e.&nbsp;__get__)&nbsp;on&nbsp;its&nbsp;instances.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#MethodDecorator">MethodDecorator</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="MethodDecorator-__get__"><strong>__get__</strong></a> = <a href="#MethodDecorator-get">get</a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<dl><dt><a name="MethodDecorator-__init__"><strong>__init__</strong></a>(self, func)</dt></dl>
+
+<dl><dt><a name="MethodDecorator-__str__"><strong>__str__</strong></a>(self)</dt></dl>
+
+<dl><dt><a name="MethodDecorator-get"><strong>get</strong></a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<hr>
+Data and other attributes defined here:<br>
+<dl><dt><strong>__klass__</strong> = &lt;class 'decorators.?'&gt;</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined&nbsp;in&nbsp;any&nbsp;module,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in<br>
+&nbsp;&nbsp;&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+2.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+&nbsp;&nbsp;&nbsp;is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>
+3.&nbsp;Decorators&nbsp;calls&nbsp;are&nbsp;dispatched&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_<br>
+&nbsp;&nbsp;&nbsp;<a href="#classmethod">classmethod</a>.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="UnknownDecoratorError">class <strong>UnknownDecoratorError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>The&nbsp;name&nbsp;says&nbsp;it&nbsp;all<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%">Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
+<dl><dt><a name="UnknownDecoratorError-__getitem__"><strong>__getitem__</strong></a>(...)</dt></dl>
+
+<dl><dt><a name="UnknownDecoratorError-__init__"><strong>__init__</strong></a>(...)</dt></dl>
+
+<dl><dt><a name="UnknownDecoratorError-__str__"><strong>__str__</strong></a>(...)</dt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="classmethod">class <strong>classmethod</strong></a>(<a href="decorators.html#MethodDecorator">MethodDecorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt><a href="#Decorator">Decorator</a>,&nbsp;converts&nbsp;a&nbsp;function&nbsp;in&nbsp;a&nbsp;<a href="#classmethod">classmethod</a><br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#classmethod">classmethod</a></dd>
+<dd><a href="decorators.html#MethodDecorator">MethodDecorator</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="classmethod-__get__"><strong>__get__</strong></a> = <a href="#classmethod-get">get</a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<dl><dt><a name="classmethod-get"><strong>get</strong></a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<hr>
+Methods inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><a name="classmethod-__init__"><strong>__init__</strong></a>(self, func)</dt></dl>
+
+<dl><dt><a name="classmethod-__str__"><strong>__str__</strong></a>(self)</dt></dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><strong>__klass__</strong> = &lt;class 'decorators.?'&gt;</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined&nbsp;in&nbsp;any&nbsp;module,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in<br>
+&nbsp;&nbsp;&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+2.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+&nbsp;&nbsp;&nbsp;is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>
+3.&nbsp;Decorators&nbsp;calls&nbsp;are&nbsp;dispatched&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_<br>
+&nbsp;&nbsp;&nbsp;<a href="#classmethod">classmethod</a>.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="staticmethod">class <strong>staticmethod</strong></a>(<a href="decorators.html#MethodDecorator">MethodDecorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt><a href="#Decorator">Decorator</a>,&nbsp;converts&nbsp;a&nbsp;function&nbsp;in&nbsp;a&nbsp;<a href="#staticmethod">staticmethod</a><br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#staticmethod">staticmethod</a></dd>
+<dd><a href="decorators.html#MethodDecorator">MethodDecorator</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="staticmethod-__get__"><strong>__get__</strong></a> = <a href="#staticmethod-get">get</a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<dl><dt><a name="staticmethod-get"><strong>get</strong></a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<hr>
+Methods inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><a name="staticmethod-__init__"><strong>__init__</strong></a>(self, func)</dt></dl>
+
+<dl><dt><a name="staticmethod-__str__"><strong>__str__</strong></a>(self)</dt></dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><strong>__klass__</strong> = &lt;class 'decorators.?'&gt;</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined&nbsp;in&nbsp;any&nbsp;module,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in<br>
+&nbsp;&nbsp;&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+2.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+&nbsp;&nbsp;&nbsp;is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>
+3.&nbsp;Decorators&nbsp;calls&nbsp;are&nbsp;dispatched&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_<br>
+&nbsp;&nbsp;&nbsp;<a href="#classmethod">classmethod</a>.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#eeaa77">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
+
+<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><dl><dt><a name="-decorate"><strong>decorate</strong></a>(objdict)</dt><dd><tt>Takes&nbsp;an&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;a&nbsp;dictionary&nbsp;and&nbsp;decorates&nbsp;all&nbsp;its&nbsp;functions<br>
+and&nbsp;classes&nbsp;according&nbsp;to&nbsp;their&nbsp;docstrings.</tt></dd></dl>
+ <dl><dt><a name="-decorated"><strong>decorated</strong></a>(obj)</dt><dd><tt>Returns&nbsp;a&nbsp;new&nbsp;decorated&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;created&nbsp;from&nbsp;obj,&nbsp;if&nbsp;obj&nbsp;is&nbsp;a&nbsp;function<br>
+or&nbsp;a&nbsp;class;&nbsp;otherwise&nbsp;it&nbsp;returns&nbsp;None</tt></dd></dl>
+ <dl><dt><a name="-decorator_from"><strong>decorator_from</strong></a>(docstring, defaultdec<font color="#909090">=None</font>)</dt><dd><tt>Takes&nbsp;a&nbsp;magic&nbsp;docstring&nbsp;and&nbsp;a&nbsp;default&nbsp;decorator<br>
+and&nbsp;returns&nbsp;a&nbsp;decorator&nbsp;class&nbsp;or&nbsp;None.&nbsp;It&nbsp;tries&nbsp;to&nbsp;be&nbsp;smart.</tt></dd></dl>
+ <dl><dt><a name="-enhance_classes"><strong>enhance_classes</strong></a>(docstring<font color="#909090">=''</font>)</dt><dd><tt>Enhance&nbsp;all&nbsp;the&nbsp;classes&nbsp;in&nbsp;the&nbsp;caller&nbsp;module&nbsp;with&nbsp;a&nbsp;metaclass<br>
+built&nbsp;from&nbsp;the&nbsp;given&nbsp;docstring;&nbsp;the&nbsp;default&nbsp;is&nbsp;<a href="#ClassDecorator">ClassDecorator</a>.</tt></dd></dl>
+ <dl><dt><a name="-get"><strong>get</strong></a>(docstring<font color="#909090">=None</font>)</dt><dd><tt>List&nbsp;of&nbsp;recognized&nbsp;decorators</tt></dd></dl>
+</td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#55aa55">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
+
+<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><strong>MAGICDOC</strong> = &lt;_sre.SRE_Pattern object&gt;</td></tr></table>
+</body></html> \ No newline at end of file
diff --git a/pypers/pep318/safetype.html b/pypers/pep318/safetype.html
new file mode 100755
index 0000000..a3c3cd4
--- /dev/null
+++ b/pypers/pep318/safetype.html
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.2.9: http://docutils.sourceforge.net/" />
+<title>Module safetype</title>
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="module-safetype">
+<h1 class="title">Module safetype</h1>
+<p>Deep, DEEP magic to remove metaclass conflicts.
+Metaclasses derived from safetype.type by cooperatively overriding __new__
+are safe under conflicts.
+The suggested import syntax for usage in other modules is</p>
+<blockquote>
+from safetype import type</blockquote>
+<div class="section" id="documented-metaclasses">
+<h1><a name="documented-metaclasses">Documented metaclasses</a></h1>
+<p><tt class="literal"><span class="pre">safetype(type)</span></tt></p>
+<blockquote>
+Redefines the 'type' metaclass, making it safe under conflicts.</blockquote>
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="safetype.rst">View document source</a>.
+Generated on: 2003-09-20 16:41 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/pypers/pep318/safetype.tex b/pypers/pep318/safetype.tex
new file mode 100755
index 0000000..fc80a11
--- /dev/null
+++ b/pypers/pep318/safetype.tex
@@ -0,0 +1,61 @@
+\documentclass[10pt,english]{article}
+\usepackage{babel}
+\usepackage{shortvrb}
+\usepackage[latin1]{inputenc}
+\usepackage{tabularx}
+\usepackage{longtable}
+\setlength{\extrarowheight}{2pt}
+\usepackage{amsmath}
+\usepackage{graphicx}
+\usepackage{color}
+\usepackage{multirow}
+\usepackage[colorlinks=true,linkcolor=blue,urlcolor=blue]{hyperref}
+\usepackage[a4paper,margin=2cm,nohead]{geometry}
+%% generator Docutils: http://docutils.sourceforge.net/
+\newlength{\admonitionwidth}
+\setlength{\admonitionwidth}{0.9\textwidth}
+\newlength{\docinfowidth}
+\setlength{\docinfowidth}{0.9\textwidth}
+\newcommand{\optionlistlabel}[1]{\bf #1 \hfill}
+\newenvironment{optionlist}[1]
+{\begin{list}{}
+ {\setlength{\labelwidth}{#1}
+ \setlength{\rightmargin}{1cm}
+ \setlength{\leftmargin}{\rightmargin}
+ \addtolength{\leftmargin}{\labelwidth}
+ \addtolength{\leftmargin}{\labelsep}
+ \renewcommand{\makelabel}{\optionlistlabel}}
+}{\end{list}}
+% begin: floats for footnotes tweaking.
+\setlength{\floatsep}{0.5em}
+\setlength{\textfloatsep}{\fill}
+\addtolength{\textfloatsep}{3em}
+\renewcommand{\textfraction}{0.5}
+\renewcommand{\topfraction}{0.5}
+\renewcommand{\bottomfraction}{0.5}
+\setcounter{totalnumber}{50}
+\setcounter{topnumber}{50}
+\setcounter{bottomnumber}{50}
+% end floats for footnotes
+% some commands, that could be overwritten in the style file.
+\newcommand{\rubric}[1]{\subsection*{~\hfill {\it #1} \hfill ~}}
+% end of "some commands"
+\input{/mnt/exp/MyDocs/pypers/style.tex}
+\title{Documentation of the safetype module\\
+\large{Metaclasses}
+}
+\author{}
+\date{}
+\hypersetup{
+pdftitle={Documentation of the safetype module}
+}
+\raggedbottom
+\begin{document}
+\maketitle
+
+
+\texttt{safetype(type)}
+
+Redefines the 'type' metaclass, making it safe under conflicts.
+
+\end{document}
diff --git a/pypers/pep318/tracing.py b/pypers/pep318/tracing.py
new file mode 100755
index 0000000..5ea3552
--- /dev/null
+++ b/pypers/pep318/tracing.py
@@ -0,0 +1,25 @@
+# tracing.py
+
+"""
+This is a pre-existing module not using decorators but using multiple
+inheritance and unsafe metaclasses. We want to trace it for debugging
+purposes.
+"""
+
+class M(type):
+ "There should be some non-trivial code here"
+
+class B(object):
+ def __init__(self):
+ super(B,self).__init__()
+
+class D(object):
+ __metaclass__=M
+ def __init__(self):
+ super(D,self).__init__()
+
+class E(B,D):
+ def __init__(self):
+ super(E,self).__init__()
+
+
diff --git a/pypers/pep318/working/README.txt b/pypers/pep318/working/README.txt
new file mode 100755
index 0000000..31f878e
--- /dev/null
+++ b/pypers/pep318/working/README.txt
@@ -0,0 +1,45 @@
+DECORATORS README
+========================================================================
+
+The ``decorators`` distribution contains the following files:
+
+1. README.txt (your are reading it)
+
+2. decorators.txt (the documentation in ReStructuredText format)
+
+3. decorators.html (the documentation in HTML format)
+
+4. decorators.pdf (the documentation in pdf format)
+
+5. decorators.py (the heart of the distribution)
+
+6. noconflict.py (imported by decorators, resolves metaclass conflicts)
+
+7. doct.py (utility to extract tests from the documentation)
+
+8. decorators.ps (a figure included in decorators.pdf)
+
+9. decorators.png (a figure included in decorators.html)
+
+10. makegraph.dot (DOT script generating the figure)
+
+
+``noconflict`` and ``doct`` can be used as standalone
+modules too. They are documented in the on-line Python cookbook.
+
+After running ``python doct.py decorators.txt`` a number of files will be
+generated, including a module ``customdec.py`` containing the examples
+of custom decorators discussed in the documentation.
+
+If the tests fail, then there is something wrong with your Python
+installation, and I cannot help you since I don't have your machine
+at my disposal :-( It works for me both under Red Hat 7.3 and
+Windows 98SE. Notice that Python 2.3 is required.
+
+If you use the decorators module in your code (of course, you should
+not use it in production software!) and you find some bug of unexpected
+behaviour, please send a bug report to me:
+
+ MicheleSimionato@libero.it
+
+That's all, folks. Enjoy!
diff --git a/pypers/pep318/working/chatty2.py b/pypers/pep318/working/chatty2.py
new file mode 100755
index 0000000..8907abb
--- /dev/null
+++ b/pypers/pep318/working/chatty2.py
@@ -0,0 +1,27 @@
+# chatty2.py
+
+import customdec; customdec.enhance_classes("[Decorated]")
+
+# sets the log files
+log1=file('file1.log','w')
+log2=file('file2.log','w')
+
+class C:
+ def f(self):
+ "[chattymethod2]"
+ f.logfile=log1 # function attribute
+ def g(self):
+ "[chattymethod2]"
+ g.logfile=log2 # function attribute
+
+assert C.__dict__['f'].logfile is log1 # check the conversion
+assert C.__dict__['g'].logfile is log2 # function attr. -> decorator attr.
+
+c=C() # C instantiation
+
+c.f() # print a message in file1.log
+c.g() # print a message in file2.log
+
+log1.close(); log2.close() # finally
+
+
diff --git a/pypers/pep318/working/customdec.py b/pypers/pep318/working/customdec.py
new file mode 100755
index 0000000..bebec11
--- /dev/null
+++ b/pypers/pep318/working/customdec.py
@@ -0,0 +1,67 @@
+# customdec.py
+
+from decorators import *
+
+class chattymethod(MethodDecorator):
+ logfile=sys.stdout # default
+ def get(self,obj,cls=None): # same signature as __get__
+ self.logfile.write('calling %s from %s\n' % (self,obj or cls))
+ return super(chattymethod,self).get(obj,cls)
+
+
+
+class chattymethod2(chattymethod):
+ logfile=sys.stdout # default
+ def __init__(self,objfunc):
+ super(chattymethod2,self).__init__(objfunc)
+ logfile=getattr(self.__func__,'logfile',None)
+ if logfile: self.logfile=logfile
+
+
+
+class tracedmethod(MethodDecorator):
+ "Descriptor class, converts a method in a traced method"
+ indent=0; output=sys.stdout # defaults
+
+ def __init__(self,objfunc):
+ super(tracedmethod,self).__init__(objfunc)
+ self.funcname=self.__func__.__name__
+ output=getattr(self.__func__,'output',None)
+ if output: self.output=output # func.attr. -> dec.attr.
+
+ def get(self,obj,cls):
+ clsname=self.__klass__.__name__ # definition clas
+ def tracedmeth(obj,*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write("%sCalling '%s.%s' with arguments " %
+ (i,clsname,self.funcname))
+ self.output.write("%s%s ...\n" % (obj or '',str(args)+str(kw)))
+ res=super(tracedmethod,self).get(obj,cls)(*args,**kw)
+ self.output.write("%s'%s.%s' called with result: %s\n"
+ % (i,clsname,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return tracedmeth.__get__(obj,cls) # method wrapper
+
+
+
+class Logged(ClassDecorator):
+ output=sys.stdout
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print >> cls.output,"%s created" % cls
+
+
+
+from types import FunctionType
+
+class Traced(ClassDecorator):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType): # modifies the docstring
+ func.__doc__="[tracedmethod] " + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d)
+
+
+
diff --git a/pypers/pep318/working/debugger.py b/pypers/pep318/working/debugger.py
new file mode 100755
index 0000000..30510df
--- /dev/null
+++ b/pypers/pep318/working/debugger.py
@@ -0,0 +1,17 @@
+import sys
+
+def info(type, value, tb):
+ if hasattr(sys, 'ps1') or not sys.stderr.isatty() or \
+ type == SyntaxError:
+ # we are in interactive mode or we don't have a tty-like
+ # device, so we call the default hook
+ sys.__excepthook__(type, value, tb)
+ else:
+ import traceback, pdb
+ # we are NOT in interactive mode, print the exception...
+ traceback.print_exception(type, value, tb)
+ print
+ # ...then start the debugger in post-mortem mode.
+ pdb.pm()
+
+sys.excepthook = info
diff --git a/pypers/pep318/working/decorators.html b/pypers/pep318/working/decorators.html
new file mode 100755
index 0000000..ceac9b6
--- /dev/null
+++ b/pypers/pep318/working/decorators.html
@@ -0,0 +1,1337 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.2.9: http://docutils.sourceforge.net/" />
+<title>Implementing PEP 318 (decorators)</title>
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="implementing-pep-318-decorators">
+<h1 class="title">Implementing PEP 318 (decorators)</h1>
+<blockquote>
+<table class="field-list" frame="void" rules="none">
+<col class="field-name" />
+<col class="field-body" />
+<tbody valign="top">
+<tr class="field"><th class="field-name">Module:</th><td class="field-body">decorators</td>
+</tr>
+<tr class="field"><th class="field-name">Version:</th><td class="field-body">0.5</td>
+</tr>
+<tr class="field"><th class="field-name">Author:</th><td class="field-body">Michele Simionato</td>
+</tr>
+<tr class="field"><th class="field-name">e-mail:</th><td class="field-body"><a class="reference" href="mailto:MicheleSimionato&#64;libero.it">MicheleSimionato&#64;libero.it</a></td>
+</tr>
+<tr class="field"><th class="field-name">Licence:</th><td class="field-body">Python-like</td>
+</tr>
+<tr class="field"><th class="field-name">Disclaimer:</th><td class="field-body">This is experimental code. Use it at your own risk!</td>
+</tr>
+</tbody>
+</table>
+</blockquote>
+<div class="contents topic" id="contents">
+<p class="topic-title"><a name="contents">Contents</a></p>
+<ul class="simple">
+<li><a class="reference" href="#basics" id="id1" name="id1">Basics</a></li>
+<li><a class="reference" href="#simple-usage-of-decorators" id="id2" name="id2">Simple usage of decorators</a></li>
+<li><a class="reference" href="#decorating-classes" id="id3" name="id3">Decorating classes</a></li>
+<li><a class="reference" href="#adding-magic" id="id4" name="id4">Adding magic</a></li>
+<li><a class="reference" href="#the-dangers-of-magic" id="id5" name="id5">The dangers of magic</a></li>
+<li><a class="reference" href="#defining-method-decorators" id="id6" name="id6">Defining method decorators</a></li>
+<li><a class="reference" href="#composing-decorators" id="id7" name="id7">Composing decorators</a></li>
+<li><a class="reference" href="#defining-class-decorators" id="id8" name="id8">Defining class decorators</a></li>
+<li><a class="reference" href="#advanced-usage" id="id9" name="id9">Advanced usage</a></li>
+<li><a class="reference" href="#the-implementation" id="id10" name="id10">The implementation</a></li>
+</ul>
+</div>
+<p>Having plenty of free time in these days, I have finished an old
+project of mine, the implementation of PEP 318 in pure Python.</p>
+<p>Here is the rationale:</p>
+<ul class="simple">
+<li>some kind of decorator syntax is scheduled to go in Python 2.4,
+therefore it is interesting to play with the concept;</li>
+<li>it is nice to play with decorators now, without having to
+wait for one year or so;</li>
+<li>it is much easier levelto experiment with a pure Python implementation
+than with a C implementation;</li>
+<li>the implementation can be seen as an exercise on modern Python
+programming and may be valuable to people wanting to study the most
+advanced new constructs in Python 2.2 (<a class="reference" href="http://users.rcn.com/python/download/Descriptor.htm">descriptors</a>, <a class="reference" href="http://www-106.ibm.com/developerworks/library/l-pymeta2.html">metaclasses</a>,
+<a class="reference" href="http://www.python.org/2.3/descrintro.html">cooperative methods</a>, etc.)</li>
+</ul>
+<div class="section" id="basics">
+<h1><a class="toc-backref" href="#id1" name="basics">Basics</a></h1>
+<p>PEP 318 has the goal of providing a nice syntactic sugar for expressions like</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x):
+ return x
+identity=staticmethod(identity)
+</pre>
+</blockquote>
+<p>or</p>
+<blockquote>
+<pre class="literal-block">
+def name(cls):
+ return cls.__name__
+name=classmethod(name)
+</pre>
+</blockquote>
+<p>which are pretty verbose. It is clear that having new syntax (as
+for instance the proposed square bracket notation)</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x)[staticmethod]:
+ return x
+
+def name(cls)[classmethod]:
+ return cls.__name__
+</pre>
+</blockquote>
+<p>involves changing the grammar and modifying the interpreter at the
+C level. This means a lot of work. Fortunately, it is possible to
+have the same effect without changing the Python grammar.
+The idea is to use magic docstrings like this:</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+def name(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+</pre>
+</blockquote>
+<p>The implementation is able to recognize such docstrings
+and to automagically convert those methods in decorators.</p>
+<p>Decorators are nothing else than a sophisticated kind of wrappers.
+The <tt class="literal"><span class="pre">decorators</span></tt> module provides support both for method decorators,
+which wrap functions and class decorator, which wrap classes.
+<tt class="literal"><span class="pre">staticmethod</span></tt> and <tt class="literal"><span class="pre">classmethod</span></tt> are two examples of already existing
+method decorators (actually my implementation rewrites them, but let me
+pass on this detail). Technically speaking, method decorators are classes
+taking a single function as input and producing a descriptor object
+as output (properties are not decorators according to this definition,
+since they take four functions as input, <tt class="literal"><span class="pre">get,</span> <span class="pre">set,</span> <span class="pre">del_</span></tt> and <tt class="literal"><span class="pre">doc</span></tt>).
+Descriptors are objects with a <tt class="literal"><span class="pre">__get__</span></tt> method; they are quite
+sophisticated, but fortunately they have been wonderfully explained by
+Raymond Hettinger already, so I am allowed to skip on this point ;).
+A knowledge of descriptors is not needed in order to use the <tt class="literal"><span class="pre">decorator</span></tt>
+module; however it is welcomed for advanced users wanting to implement
+custom method decorators.
+Class decorators are metaclasses taking a class as imput and returning
+a decorated class as output. A good understanding of metaclasses is needed
+in order to be able to write custom class decorators, but no knowledge
+at all is required in order to use the pre-defined class decorators
+provided by the module.
+Finally, the module is meant to be extensible; so one could
+define new kind of decorators. For instance, the original version of
+the module also had the concept of module decorators; however I have cut
+down that part in order to keep the module short.</p>
+<p>Admittedly, the implementation
+is not for the faint of heart, nevertheless I have tried to make the
+basic usage easy and simple to understand.</p>
+</div>
+<div class="section" id="simple-usage-of-decorators">
+<h1><a class="toc-backref" href="#id2" name="simple-usage-of-decorators">Simple usage of decorators</a></h1>
+<p>Before talking about the implementation details, I will show
+how the <tt class="literal"><span class="pre">decorators</span></tt> module works in practice. The simplest and safest
+usage is by means of the <tt class="literal"><span class="pre">decorators.decorated()</span></tt> function, which
+takes an object (a function or a class) and checks its docstring: if
+a magic docstring is found, it returns a decorated version of the object,
+otherwise it returns the original object. Using <tt class="literal"><span class="pre">decorators.decorated()</span></tt>
+is simple but verbose, so magic shortcuts will be discussed in the next
+section.</p>
+<p>Here, let me give an example, showing that method decorators work both for
+<a class="reference" href="http://www.python.org/2.3/descrintro.html">new style classes and old style classes</a>:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example1.py&gt;
+
+import decorators
+
+def do_nothing(self):
+ &quot;No magic docstring here&quot;
+dec_do_nothing=decorators.decorated(do_nothing)
+
+def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+dec_identity=decorators.decorated(identity)
+
+def name(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+dec_name=decorators.decorated(name)
+
+class OldStyle:
+ do_nothing=dec_do_nothing
+ identity=dec_identity
+
+class NewStyle(object):
+ name=dec_name
+
+o=OldStyle() # creates an old style instance
+n=NewStyle() # creates a new style instance
+
+#&lt;/example1.py&gt;
+</pre>
+</blockquote>
+<p>In this example, both <tt class="literal"><span class="pre">dec_identity</span></tt> and <tt class="literal"><span class="pre">dec_name</span></tt> are decorator objects,
+i.e. descriptors modifiying the attribute access. It is easy to recognize
+decorators objects, since they have a re-defined printing representation:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example1 import *
+</pre>
+<pre class="doctest-block">
+&gt;&gt;&gt; print dec_identity
+&lt;staticmethod:identity&gt;
+</pre>
+<pre class="doctest-block">
+&gt;&gt;&gt; print dec_name
+&lt;classmethod:name&gt;
+</pre>
+<p>Now, let me check that <tt class="literal"><span class="pre">dec_</span> <span class="pre">identity</span></tt> works as a staticmethod,</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert OldStyle.identity(1) == 1 # called from the class
+&gt;&gt;&gt; assert o.identity(1) == 1 # called from the instance
+</pre>
+<p>whereas <tt class="literal"><span class="pre">dec_name</span></tt> works as a classmethod:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert NewStyle.name() == 'NewStyle' # called from the class
+&gt;&gt;&gt; assert n.name() == 'NewStyle' # called from the instance
+</pre>
+<p>On the other hand, <tt class="literal"><span class="pre">do_nothing</span></tt> does not have a magic
+docstring, therefore it is not converted to a decorator object;
+actually it is <em>exactly</em> the original function:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert dec_do_nothing is do_nothing # not converted
+</pre>
+<p>Therefore it works without surprises:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; o.do_nothing() # does nothing, correct
+</pre>
+<p>For sake of convenience, I have re-implemented the built-in
+<tt class="literal"><span class="pre">staticmethod</span></tt> and <tt class="literal"><span class="pre">classmethod</span></tt>, so</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; isinstance(dec_identity,staticmethod)
+False
+</pre>
+<p>and</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; isinstance(dec_name,classmethod)
+False
+</pre>
+<p>but</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; isinstance(dec_identity,decorators.staticmethod)
+True
+</pre>
+<p>and</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; isinstance(dec_name,decorators.classmethod)
+True
+</pre>
+<p>It is possible to recognize method decorators since they provides
+a couple of special attributes:</p>
+<p><tt class="literal"><span class="pre">__func__</span></tt>, returning the function from which they originated</p>
+<blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert dec_identity.__func__ is identity
+&gt;&gt;&gt; assert dec_name.__func__ is name
+</pre>
+</blockquote>
+<p>and <tt class="literal"><span class="pre">__klass__</span></tt>, returning the class where they where defined</p>
+<blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; dec_identity.__klass__
+&lt;class 'decorators.?'&gt;
+</pre>
+</blockquote>
+<p>The question mark here means that the definition class is unknown.</p>
+</div>
+<div class="section" id="decorating-classes">
+<h1><a class="toc-backref" href="#id3" name="decorating-classes">Decorating classes</a></h1>
+<p>The problem with the approach described in the previous section
+is that it does not present any significant advantage over
+the already existing mechanism. A real step forward would be to
+have classes with the ability of automatically converting their
+methods to method decorators according to the docstrings.
+This sounds a bit of magic, but actually can be done very simply
+by adding to the class a docstring starting with &quot;[Decorated]&quot;
+and decorating the class.
+Here is an example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example2.py&gt;
+
+from decorators import decorated
+from example1 import do_nothing,identity,name
+
+class B(object):
+ &quot;This is a regular class&quot;
+
+B=decorated(B) # does nothing
+
+class C(B):
+ &quot;[Decorated]&quot;
+ do_nothing=do_nothing
+ identity=identity
+ name=name
+
+C=decorated(C) # regenerates the class converting methods in decorators
+c=C()
+
+#&lt;/example2.py&gt;
+</pre>
+</blockquote>
+<p>Here is the testing:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example2 import *
+&gt;&gt;&gt; assert C.identity(1) == 1
+&gt;&gt;&gt; assert C.name() == 'C'
+&gt;&gt;&gt; assert c.identity(1) == 1
+&gt;&gt;&gt; assert c.name() == 'C'
+</pre>
+<p>Notice that adding <tt class="literal"><span class="pre">identity</span></tt> after the class creation with the syntax
+<tt class="literal"><span class="pre">C.identity=identity</span></tt> would not work;
+<tt class="literal"><span class="pre">C.identity=decorators.decorated(identity)</span></tt> is required:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.identity=decorators.decorated(identity)
+&gt;&gt;&gt; C.identity(1) # it works
+1
+</pre>
+<p>If a class misses the magic docstring, nothing happens:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; B # returns the original B
+&lt;class 'example2.B'&gt;
+</pre>
+<p>The mechanism works for old style classes too:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example2.py&gt;
+
+class D: # old style
+ &quot;[Decorated]&quot;
+ def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+D=decorated(D)
+
+d=D()
+
+# test
+assert d.identity(1) == 1
+assert D.identity(1) == 1
+
+#&lt;/example2.py&gt;
+</pre>
+</blockquote>
+<p>Under the hood <tt class="literal"><span class="pre">decorators.decorated()</span></tt> recognizes the class level
+magic docstring &quot;[Decorated]&quot; and creates an instance of the
+<tt class="literal"><span class="pre">decorators.Decorated</span></tt> metaclass; incidentally,
+this converts old style classes in new style classes:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example2 import D,d
+&gt;&gt;&gt; type(D) # D is an instance of decorator.Decorated
+&lt;class 'decorators.Decorated'&gt;
+</pre>
+<p>Internally the metaclass invokes <tt class="literal"><span class="pre">decorators.decorated()</span></tt>
+on the methods of its instances: this is why they becomes decorated
+if a suitable docstring is found. By the way, if you mispell a
+decorator name you get an helpful error message:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E:
+... &quot;[Decorated]&quot;
+... def f():
+... &quot;[staticmeth]&quot;
+&gt;&gt;&gt; E=decorators.decorated(E)
+Traceback (most recent call last):
+ .. a long and cryptic traceback here ..
+UnknownDecoratorError: staticmeth
+</pre>
+<p>The enhancement provided by the metaclass includes a new default
+printing representation for both the class</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; print D # returns the name of D and of its metaclass
+&lt;class D[Decorated]&gt;
+</pre>
+<p>and its instances:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; print d
+&lt;D instance&gt;
+</pre>
+<p>One can even forget the docstring in subclasses of decorated
+classes, since metaclasses are inherited:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E(D):
+... def name(cls):
+... &quot;[classmethod]&quot;
+... return cls.__name__
+&gt;&gt;&gt; print E.name()
+E
+</pre>
+<p>This approach presents another advantage: the decorated methods know
+the class where they were defined via the special attribute <tt class="literal"><span class="pre">__klass__</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.__dict__['name'].__klass__ # the class where 'name' is defined
+&lt;class 'E'&gt;
+</pre>
+<p>This is useful for introspection and debugging purposes.</p>
+</div>
+<div class="section" id="adding-magic">
+<h1><a class="toc-backref" href="#id4" name="adding-magic">Adding magic</a></h1>
+<p>The problem of the previous approach is that one must explicitely
+decorate the classes by hand, by invoking <tt class="literal"><span class="pre">decorators.decorated()</span></tt>
+each time. However, it is possible to add more magic
+and to decorate all the classes automatically.
+It is as easy as writing <tt class="literal"><span class="pre">decorators.enhance_classes()</span></tt>
+on top of the module. Then all methods in all classes of the module
+with a magic docstring will be checked for magic docstrings and
+automagically decorated if needed.
+For instance, the previous example would be written</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example4.py&gt;
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ &quot;[Decorated]&quot; # magic docstring here
+ def do_nothing(self):
+ &quot;No magic docstring here&quot;
+
+ def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+class D(object):
+ &quot;Undecorated&quot; # no magic docstring here
+ def name(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+
+c=C(); d=D()
+
+#&lt;/example4.py&gt;
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">C</span></tt> has a <tt class="literal"><span class="pre">[Decorated]</span></tt> docstring, so its methods
+are automatically decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example4 import *
+&gt;&gt;&gt; assert c.do_nothing() is None
+&gt;&gt;&gt; assert C.identity(1) == 1
+&gt;&gt;&gt; assert c.identity(1) == 1
+</pre>
+<p>On the other hand, since <tt class="literal"><span class="pre">D</span></tt> misses a magic docstring,
+its <tt class="literal"><span class="pre">name</span></tt> method is not decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; hasattr(D.__dict__['name'],'__func__') # not a decorator
+False
+</pre>
+<p>Since <tt class="literal"><span class="pre">D.name</span></tt> is a regular method and not a classmethod, <tt class="literal"><span class="pre">D.name()</span></tt>
+gives an error:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; D.name()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method name() must be called with D instance as first argument (got nothing instead)
+</pre>
+<p>The trick works for classes containing inner classes, too:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example5.py&gt;
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ &quot;[Decorated]&quot; # required docstring
+ def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+ class Inner:
+ &quot;[Decorated]&quot; # required docstring
+ def name(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+
+
+assert C.identity(1) == 1
+assert C.Inner.name() == 'Inner'
+
+#&lt;/example5.py&gt;
+</pre>
+</blockquote>
+<p>Under the hood, the magic works by enhancing the <tt class="literal"><span class="pre">object</span></tt> class
+of the module with a <tt class="literal"><span class="pre">decorators.ClassDecorator</span></tt> metaclass:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import example5
+&gt;&gt;&gt; type(example5.object)
+&lt;class 'decorators.ClassDecorator'&gt;
+</pre>
+<p>Notice that for safety reasons the enhancement is only on the module
+<tt class="literal"><span class="pre">object</span></tt> class, not on the <tt class="literal"><span class="pre">__builtin__.object</span></tt> class. The problem
+is that adding too much magic can be risky.</p>
+</div>
+<div class="section" id="the-dangers-of-magic">
+<h1><a class="toc-backref" href="#id5" name="the-dangers-of-magic">The dangers of magic</a></h1>
+<p>For the sake of metaclass users, in this section I will point out the
+dangers of the <tt class="literal"><span class="pre">enhance_classes()</span></tt> syntax. On the other hand, if you
+never use metaclasses, you may safely skip to the following section.</p>
+<p>The problem is that the <tt class="literal"><span class="pre">enhance_classes()</span></tt> syntax is not 100% safe,
+because of possible metaclass conflicts.
+Here is an example:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import decorators; decorators.enhance_classes()
+</pre>
+<p>This line enhances the <tt class="literal"><span class="pre">object</span></tt> class in the interpreter namespace:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; print object
+&lt;class object[ClassDecorator]&gt;
+</pre>
+<p>This shows that <tt class="literal"><span class="pre">object</span></tt> is an instance of <tt class="literal"><span class="pre">ClassDecorator</span></tt>.</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class M(type):
+... &quot;Some non-trivial code here...&quot;
+</pre>
+<p>This line creates a custom metaclass we want to use to enhance our classes.</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D(object): __metaclass__=M # does not work!
+...
+Traceback (most recent call last):
+ ...
+TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+</pre>
+<p>The problem is that the previous line tries to create a class <tt class="literal"><span class="pre">D</span></tt>
+which should have both metaclasses <tt class="literal"><span class="pre">ClassDecorator</span></tt> and <tt class="literal"><span class="pre">M</span></tt>:
+a conflict follows.</p>
+<p>Fortunately, the decorators module imports the <tt class="literal"><span class="pre">makecls</span></tt> function from my
+<tt class="literal"><span class="pre">noconflict</span></tt> module (described in the <a class="reference" href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197">cookbook</a>)
+just to avoid this kind of problems:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D(object):
+... __metaclass__=decorators.makecls(M)
+</pre>
+<p>Now the class has been safely created as an instance of the composed
+class <tt class="literal"><span class="pre">ClassDecoratorM</span></tt>.</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; type(D)
+&lt;class 'noconflict.ClassDecoratorM'&gt;
+</pre>
+<p>If we want <tt class="literal"><span class="pre">M</span></tt> to have the priority over <tt class="literal"><span class="pre">ClassDecorator</span></tt>, the
+option <tt class="literal"><span class="pre">priority=True</span></tt> makes the job:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D(object):
+... __metaclass__=decorators.makecls(M,priority=True)
+&gt;&gt;&gt; type(D)
+&lt;class 'noconflict.MClassDecorator'&gt;
+</pre>
+<p>The situation for old style classes is worse, since</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D:
+... __metaclass__=M
+... def sm():
+... &quot;[staticmethod]&quot;
+</pre>
+<p>apparently gives no error, but actually the metaclass <tt class="literal"><span class="pre">M</span></tt> overrides
+<tt class="literal"><span class="pre">ClassDecorator</span></tt>, so <tt class="literal"><span class="pre">D</span></tt> will not recognize magic docstrings:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; type(D)
+&lt;class 'M'&gt;
+&gt;&gt;&gt; D.sm()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with D instance as first argument (got nothing instead)
+</pre>
+<p>Using <tt class="literal"><span class="pre">decorators.makecls(M)</span></tt> will not help here (because of the way Python
+assigns metaclasses) and the only solution is to be completely explicit:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D:
+... __metaclass__=decorators.makecls(decorators.ClassDecorator,M)
+... def sm():
+... &quot;[staticmethod]&quot;
+&gt;&gt;&gt; type(D)
+&lt;class 'noconflict.ClassDecoratorM'&gt;
+</pre>
+<p>Now <tt class="literal"><span class="pre">D</span></tt> is not decorated since it does miss a magic docstring, but
+it provides the ability to recognizing magic docstrings, so <tt class="literal"><span class="pre">D</span></tt>
+subclasses with a &quot;[Decorated]&quot; docstring will be decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E(D):
+... &quot;[Decorated]&quot;
+... def cm(cls):
+... &quot;[classmethod]&quot;
+... print '.cm() called from',cls
+</pre>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.cm() # it works
+.cm() called from &lt;class E[ClassDecoratorMDecorated]&gt;
+</pre>
+<p>Notice that <tt class="literal"><span class="pre">sm</span></tt> was defined in <tt class="literal"><span class="pre">D</span></tt>, the undecorated class: therefore
+it is not decorated:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.sm() # correctly, does not work
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with E instance as first argument (got nothing instead)
+</pre>
+<p>The error message says clearly that <tt class="literal"><span class="pre">sm</span></tt> is an unbound method and not
+a static method.</p>
+</div>
+<div class="section" id="defining-method-decorators">
+<h1><a class="toc-backref" href="#id6" name="defining-method-decorators">Defining method decorators</a></h1>
+<p>The <tt class="literal"><span class="pre">decorators</span> <span class="pre">module</span></tt> contains two predefinite method decorators,
+<tt class="literal"><span class="pre">staticmethod</span></tt> and <tt class="literal"><span class="pre">classmethod</span></tt>, which emulate the built-ins
+with the same names. However, it is possible to write your own
+custom decorators. The <tt class="literal"><span class="pre">decorators.MethodDecorator</span></tt> class which is here
+exactly for that purpose.</p>
+<p>Custom decorators are expected to be implemented by subclassing
+<tt class="literal"><span class="pre">MethodDecorator</span></tt> and by overriding its <tt class="literal"><span class="pre">get</span></tt> method. The
+<tt class="literal"><span class="pre">get</span></tt> method automagically induces a <tt class="literal"><span class="pre">__get__</span></tt> method, turning the
+class in a descriptor. The machinery is needed since <tt class="literal"><span class="pre">__get__</span></tt> cannot
+be made cooperative using the standard <tt class="literal"><span class="pre">super</span></tt> mechanism because
+there would be a confusion between <tt class="literal"><span class="pre">super.__get__</span></tt> and the decorator
+<tt class="literal"><span class="pre">__get__</span></tt>. This is a bit tricky, but the causal programmer is not
+expected to write custom decorators, and actually I don't want to make
+the access to decorators <em>too</em> easy, since they are potentially dangerous.</p>
+<p>In order to give a simple example, let me show the implementation
+of a <tt class="literal"><span class="pre">chattymethod</span></tt> that prints a message when it is called:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+from decorators import *
+
+class chattymethod(MethodDecorator):
+ logfile=sys.stdout # default
+ def get(self,obj,cls=None): # same signature as __get__
+ self.logfile.write('calling %s from %s\n' % (self,obj or cls))
+ return super(chattymethod,self).get(obj,cls)
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p>Notice the usage of the <tt class="literal"><span class="pre">super().get</span></tt> trick. This guarantees that
+<tt class="literal"><span class="pre">chattymethod</span></tt> will play well with other decorators (i.e. it
+can be nicely composed via multiple inheritance). The point will
+be fully discussed in the section on composing decorators.</p>
+<p>Here is an example of usage:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import customdec # adds chattymethod to the list of known decorators
+&gt;&gt;&gt; customdec.enhance_classes() # automagically enhances classes when needed
+&gt;&gt;&gt; class C:
+... &quot; [Decorated] &quot;
+... def f(self):
+... &quot;&quot;&quot;
+... [ chattymethod ]
+... &quot;&quot;&quot;
+&gt;&gt;&gt; c=C()
+&gt;&gt;&gt; c.f()
+calling &lt;chattymethod:f&gt; from &lt;C instance&gt;
+</pre>
+<p>By the way, this shows that one can safely add whitespaces (including
+newlines) to the magic docstring: they are simply ignored.</p>
+<p>One can check that the syntax <tt class="literal"><span class="pre">C.f(c)</span></tt> works too:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.f(c)
+calling &lt;chattymethod:f&gt; from &lt;class C[Decorated]&gt;
+</pre>
+<p>A tricky point of the decorators mechanism is the issue of parameter passing.
+In comp.lang.python there was the proposal of allowing explicit parameter
+passing to decorators, with a syntax of kind</p>
+<blockquote>
+<pre class="literal-block">
+def f(self)[chattymethod(logfile=file('file1.log','w'))]
+</pre>
+</blockquote>
+<p>In my view, there are too many parenthesis in this syntax, and it may
+become rapidly unreadable. Moreover, it complicates the implementation
+without any real benefit, so the decorators module does not allow
+this kind of parameter passings. There are however viable
+workarounds, so you should not miss the syntax.</p>
+<p>A simple minded solution is to change the defaults by hand:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from customdec import chattymethod,decorated
+&gt;&gt;&gt; chattymethod.logfile=file('file.log','w')
+&gt;&gt;&gt; def g(self):
+... &quot;[chattymethod]&quot;
+&gt;&gt;&gt; C.g=decorated(g)
+&gt;&gt;&gt; c.g() # will print a message on file.log
+</pre>
+<p>This approach has the drawback that chattymethods created before changing
+the logfile will also print to the new logfile, if invoked after the
+change. Therefore</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; c.f()
+</pre>
+<p>will print a message to <tt class="literal"><span class="pre">file.log</span></tt> too, and not to standard output.
+Here is the confirmation:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; chattymethod.logfile.close()
+&gt;&gt;&gt; print file('file.log').read().rstrip()
+calling &lt;chattymethod:g&gt; from &lt;C instance&gt;
+calling &lt;chattymethod:f&gt; from &lt;C instance&gt;
+</pre>
+<p>A much better solution is to pass
+parameters to method decorators as function attributes: then the function
+attributes can be converted to attributes of the decorator
+in the <tt class="literal"><span class="pre">__init__</span></tt> method. Here is an example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+class chattymethod2(chattymethod):
+ logfile=sys.stdout # default
+ def __init__(self,objfunc):
+ super(chattymethod2,self).__init__(objfunc)
+ logfile=getattr(self.__func__,'logfile',None)
+ if logfile: self.logfile=logfile
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p>Notice that the <tt class="literal"><span class="pre">__init__</span></tt> method has the signature
+<tt class="literal"><span class="pre">__init__(self,objfunc)</span></tt>, where the <tt class="literal"><span class="pre">objfunc</span></tt> object is a
+decorator object or the function to be converted in the decorator
+object, and that it is cooperative.
+This is the suggested way of overriding <tt class="literal"><span class="pre">__init__</span></tt> (see also
+<tt class="literal"><span class="pre">help(decorators.MethodDecorator.__init__)</span></tt>).</p>
+<p>Here is the testing:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;chatty2.py&gt;
+
+import customdec; customdec.enhance_classes(&quot;[Decorated]&quot;)
+
+# sets the log files
+log1=file('file1.log','w')
+log2=file('file2.log','w')
+
+class C:
+ def f(self):
+ &quot;[chattymethod2]&quot;
+ f.logfile=log1 # function attribute
+ def g(self):
+ &quot;[chattymethod2]&quot;
+ g.logfile=log2 # function attribute
+
+assert C.__dict__['f'].logfile is log1 # check the conversion
+assert C.__dict__['g'].logfile is log2 # function attr. -&gt; decorator attr.
+
+c=C() # C instantiation
+
+c.f() # print a message in file1.log
+c.g() # print a message in file2.log
+
+log1.close(); log2.close() # finally
+
+#&lt;/chatty2.py&gt;
+</pre>
+</blockquote>
+<p>Let me check the contents of the log files:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import chatty2
+&gt;&gt;&gt; print file('file1.log').read().rstrip()
+calling &lt;chattymethod2:f&gt; from &lt;C instance&gt;
+&gt;&gt;&gt; print file('file2.log').read().rstrip()
+calling &lt;chattymethod2:g&gt; from &lt;C instance&gt;
+</pre>
+<p><tt class="literal"><span class="pre">chattymethod</span></tt> is the poor man version of <tt class="literal"><span class="pre">tracedmethod</span></tt>, a
+sophisticated decorator for tracing methods.
+Here is the code, given for pedagogical purposes; the lazy reader can
+skip it and go directly to the usage section.</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+class tracedmethod(MethodDecorator):
+ &quot;Descriptor class, converts a method in a traced method&quot;
+ indent=0; output=sys.stdout # defaults
+
+ def __init__(self,objfunc):
+ super(tracedmethod,self).__init__(objfunc)
+ self.funcname=self.__func__.__name__
+ output=getattr(self.__func__,'output',None)
+ if output: self.output=output # func.attr. -&gt; dec.attr.
+
+ def get(self,obj,cls):
+ clsname=self.__klass__.__name__ # definition clas
+ def tracedmeth(obj,*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write(&quot;%sCalling '%s.%s' with arguments &quot; %
+ (i,clsname,self.funcname))
+ self.output.write(&quot;%s%s ...\n&quot; % (obj or '',str(args)+str(kw)))
+ res=super(tracedmethod,self).get(obj,cls)(*args,**kw)
+ self.output.write(&quot;%s'%s.%s' called with result: %s\n&quot;
+ % (i,clsname,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return tracedmeth.__get__(obj,cls) # method wrapper
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">tracedmethod.get</span></tt> returns a method wrapper object, so it is
+possible to use <tt class="literal"><span class="pre">im_func</span></tt> to retrieve the internal function
+<tt class="literal"><span class="pre">tracedmeth</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C:
+... &quot;[Decorated]&quot;
+... def f(self):
+... &quot;[tracedmethod]&quot;
+&gt;&gt;&gt; c=C(); c.f()
+Calling 'C.f' with arguments &lt;C instance&gt;(){} ...
+'C.f' called with result: None
+&gt;&gt;&gt; c.f.im_func.__name__
+'tracedmeth'
+</pre>
+<p>As soon as the <tt class="literal"><span class="pre">tracedmethod</span></tt> module is loaded, the <tt class="literal"><span class="pre">tracedmethod</span></tt> class
+is added to the list of know decorators, so one should use the
+&quot;[tracedmethod]&quot; docstring and not something like
+&quot;[customdec.tracedmethod]&quot;.</p>
+<p>Here is a less trivial example of usage, writing in a log file the
+internal working of a recursive function:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example9.py&gt;
+
+import customdec; customdec.enhance_classes()
+
+logfile=file('file3.log','w')
+
+class C(object):
+ &quot;[Decorated]&quot;
+ def fact(self,n):
+ &quot;[tracedmethod] The good old factorial.&quot;
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact.output=logfile
+
+C().fact(2) # write a message to logfile
+
+logfile.close()
+
+#&lt;/example9.py&gt;
+</pre>
+</blockquote>
+<p>Here is the content of the <tt class="literal"><span class="pre">file3.log</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import example9
+&gt;&gt;&gt; print file('file3.log').read().rstrip()
+Calling 'C.fact' with arguments &lt;C instance&gt;(2,){} ...
+ Calling 'C.fact' with arguments &lt;C instance&gt;(1,){} ...
+ Calling 'C.fact' with arguments &lt;C instance&gt;(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+</pre>
+</div>
+<div class="section" id="composing-decorators">
+<h1><a class="toc-backref" href="#id7" name="composing-decorators">Composing decorators</a></h1>
+<p>Decorators can be composed by using magic docstrings with comma-separated
+decorator names. For instance, you can trace a classmethod as in this example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example6.py&gt;
+
+&quot;How to trace a class method&quot;
+
+import customdec; customdec.enhance_classes()
+
+class C(object):
+ &quot;[Decorated]&quot;
+ def fact(cls,n): # a traced classmethod
+ &quot;[classmethod,tracedmethod]&quot;
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+#&lt;/example6.py&gt;
+</pre>
+</blockquote>
+<p>Here is the testing:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example6 import C
+&gt;&gt;&gt; C.fact(2)
+Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(2,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(1,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+</pre>
+<p>You may easily check that calling <tt class="literal"><span class="pre">.fact</span></tt> from the instance will work too.</p>
+<p>Under the hood the syntax</p>
+<blockquote>
+<pre class="literal-block">
+[classmethod,tracedmethod]
+</pre>
+</blockquote>
+<p>generates a <tt class="literal"><span class="pre">classmethodtracedmethod</span></tt> class obtained via
+multiple inheritance:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.__dict__['fact'].__class__
+&lt;class 'noconflict.classmethodtracedmethod'&gt;
+</pre>
+<p>Notice that the order does matter and using the docstring
+&quot;[tracedmethod,classmethod]&quot; will not work:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D:
+... &quot;[Decorated]&quot;
+... def f(cls):
+... &quot;[tracedmethod,classmethod]&quot;
+&gt;&gt;&gt; D.f()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with D instance as first argument (got nothing instead)
+</pre>
+<p>The problem here is that <tt class="literal"><span class="pre">tracedmethod.get</span></tt> returns a method-wrapper object
+which expects a D instance as first argument whereas it gets <tt class="literal"><span class="pre">None</span></tt> since
+it is called from the class. On the other hand,</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; D().f()
+Calling 'D.f' with arguments &lt;D instance&gt;(){} ...
+'D.f' called with result: None
+</pre>
+<p>will work. When <tt class="literal"><span class="pre">classmethod</span></tt> precedes <tt class="literal"><span class="pre">tracedmethod</span></tt>, then
+<tt class="literal"><span class="pre">classmethod</span></tt> passes to <tt class="literal"><span class="pre">tracedmeth</span></tt> a non-empty first argument,
+i.e. the calling class, even when called from the instance:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C().fact(2)
+Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(2,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(1,){} ...
+ Calling 'C.fact' with arguments &lt;class C[Decorated]&gt;(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+</pre>
+<p>If we try to trace a staticmethod, we will get a different error with
+the order &quot;tracedmethod, staticmethod&quot;:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class F(object):
+... &quot;[Decorated]&quot;
+... def fact(n):
+... &quot;[tracedmethod,staticmethod]&quot;
+... if n==0: return 1
+... else: return n*F.fact(n-1)
+&gt;&gt;&gt; F.fact(2)
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with F instance as first argument (got int instance instead)
+</pre>
+<p>The message is self-explanatory.</p>
+<p>On the other hand, composing the decorators in the other order
+&quot;[tracedmethod,staticmethod]&quot; will work just fine.</p>
+</div>
+<div class="section" id="defining-class-decorators">
+<h1><a class="toc-backref" href="#id8" name="defining-class-decorators">Defining class decorators</a></h1>
+<p>PEP 318 proposes to decorate methods by using descriptors; it is
+quite natural to extend this idea and to decorate classes by using
+class decorators implemented as metaclasses. We already saw a
+class decorator at work, the metaclass <tt class="literal"><span class="pre">Decorated</span></tt>, giving
+to its instances the ability to interpret magic docstrings,
+and converting functions in method decorators.</p>
+<p>To define a custom class decorator is easy: one defines a custom metaclass
+as usual, with the only difference from deriving by <tt class="literal"><span class="pre">ClassDecorator</span></tt> instead
+of deriving from <tt class="literal"><span class="pre">type</span></tt>. To understand how this works in practice, let me
+show how to add logging capabilities to a given class. The first
+step is to define a suitable class decorator, such as the following:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+class Logged(ClassDecorator):
+ output=sys.stdout
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print &gt;&gt; cls.output,&quot;%s created&quot; % cls
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">Logged</span></tt> is derived by the metaclass <tt class="literal"><span class="pre">ClassDecorator</span></tt>,
+which provides a certain amount of magic under the hood (in particular
+its printing representation and its calling syntax are redefined by its
+metaclass <tt class="literal"><span class="pre">MetaDecorator</span></tt>). Logging capabilities can be added to a class
+by simply using the magic docstring syntax:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;logged.py&gt;
+
+import customdec; customdec.enhance_classes()
+
+class D(object): # will print a message at D creation
+ &quot;[Logged]&quot;
+
+#&lt;/logged.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; import logged
+&lt;class D[Logged]&gt; created
+</pre>
+<p>Notice that the printing representation of <tt class="literal"><span class="pre">D</span></tt> involves the name
+of <tt class="literal"><span class="pre">D</span></tt> preceded by the name of its metaclass, which in this case
+is <tt class="literal"><span class="pre">Logged</span></tt></p>
+<p>Each time an instance of <tt class="literal"><span class="pre">Logged</span></tt> is created, a similar message is printed:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E(logged.D):
+... pass
+&lt;class E[Logged]&gt; created
+</pre>
+<p>Notice that <tt class="literal"><span class="pre">E</span></tt> does not have any magic docstring</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.__doc__ # no docstring
+</pre>
+<p>but still it inherits its magic from <tt class="literal"><span class="pre">D</span></tt>.</p>
+<p>Another simple example of class decorator is the following metaclass
+which modifies the docstrings of the methods of its instances,
+by magically inducing tracing capabilities on them:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;customdec.py&gt;
+
+from types import FunctionType
+
+class Traced(ClassDecorator):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType): # modifies the docstring
+ func.__doc__=&quot;[tracedmethod] &quot; + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d)
+
+
+#&lt;/customdec.py&gt;
+</pre>
+</blockquote>
+<p>Here is an example of usage:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C(object):
+... &quot;&quot;&quot;[Decorated,Traced] The class decorator adds the magic docstring
+... '[tracedmethod]' to f1 and f2, which are then converted
+... to method decorator objects.&quot;&quot;&quot;
+... def f1(self): pass
+... def f2(self): pass
+...
+&gt;&gt;&gt; type(C)
+&lt;class 'noconflict.DecoratedTraced'&gt;
+&gt;&gt;&gt; c=C()
+&gt;&gt;&gt; c.f1()
+Calling 'C.f1' with arguments &lt;C instance&gt;(){} ...
+'C.f1' called with result: None
+&gt;&gt;&gt; c.f2()
+Calling 'C.f2' with arguments &lt;C instance&gt;(){} ...
+'C.f2' called with result: None
+</pre>
+<p>By default, the decorators module only decorates classes with a magic
+docstring (and they subclasses, even without magic docstrings).
+If all the classes of your module have the same magic docstring,
+it makes sense to decorate them all
+with a single command. It is enough to use <tt class="literal"><span class="pre">decorators.enhance_classes()</span></tt>
+with a magic docstring corresponding to a class decorator as argument,
+as in this example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example.py&gt;
+
+from example2 import identity,name
+import inspect, decorators; decorators.enhance_classes(&quot;[Decorated]&quot;)
+
+class C1: # automagically converted to a decorated class
+ identity=identity
+
+class C2: # automagically converted to a DecoratedLogged class
+ &quot;[Logged]&quot;
+ name=name
+
+c1=C1() # C1 instance
+c2=C2() # C2 instance
+
+#&lt;/example.py&gt;
+</pre>
+</blockquote>
+<p>Notice that class <tt class="literal"><span class="pre">C2</span></tt> has already a magic docstring. This means that
+<tt class="literal"><span class="pre">C2</span></tt> has to be enhanced both from <tt class="literal"><span class="pre">Logged</span></tt> and from <tt class="literal"><span class="pre">Decorated</span></tt>.
+This is done by automagically creating a <tt class="literal"><span class="pre">DecoratedLogged</span></tt> class
+decorator:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example import C1,C2,c1,c2
+&lt;class C2[DecoratedLogged]&gt; created
+</pre>
+<p>The second line is printed because of the logging capabilities of <tt class="literal"><span class="pre">C2</span></tt>.
+Moreover, since <tt class="literal"><span class="pre">C2</span></tt> is decorated too, the following will work:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert C2.name() == 'C2'
+&gt;&gt;&gt; assert c2.name() == 'C2'
+</pre>
+<p>Idem for <tt class="literal"><span class="pre">C1</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; assert C1.identity(1) == 1
+&gt;&gt;&gt; assert c1.identity(1) == 1
+</pre>
+<p>You may check that the magic works both for new style classes (decorating
+module <tt class="literal"><span class="pre">object</span></tt> class) and old style classes (by setting the module level
+<tt class="literal"><span class="pre">__metaclass</span></tt> attribute and by implicitly converting the classes
+to new style classes).</p>
+<p>This magical approach is the easiest way to go if you want to trace
+inheritance hierarchies. For instance, here is how to trace cooperative
+methods in complicate (which is useful for debugging):</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;tracing.py&gt;
+
+import customdec; customdec.enhance_classes(&quot;[Decorated]&quot;)
+
+class B(object):
+ def __init__(self):
+ &quot;[tracedmethod]&quot;
+ super(B,self).__init__()
+
+class D(object):
+ def __init__(self):
+ &quot;[tracedmethod]&quot;
+ super(D,self).__init__()
+
+class E(B,D):
+ def __init__(self):
+ &quot;[tracedmethod]&quot;
+ super(E,self).__init__()
+
+ #&lt;/tracing.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; from tracing import E
+&gt;&gt;&gt; e=E()
+Calling 'E.__init__' with arguments &lt;E instance&gt;(){} ...
+ Calling 'B.__init__' with arguments &lt;E instance&gt;(){} ...
+ Calling 'D.__init__' with arguments &lt;E instance&gt;(){} ...
+ 'D.__init__' called with result: None
+ 'B.__init__' called with result: None
+'E.__init__' called with result: None
+</pre>
+</div>
+<div class="section" id="advanced-usage">
+<h1><a class="toc-backref" href="#id9" name="advanced-usage">Advanced usage</a></h1>
+<p>Whereas the average programmer is expected to use the
+<tt class="literal"><span class="pre">decorators.decorated</span></tt> function only, the module provides access to
+its underlining implementation, which may be useful to the advanced
+programmer.</p>
+<p>The module provides an utility functions to retrieve the list of
+recognized decorators: <tt class="literal"><span class="pre">decorators.get(docstring)</span></tt>, where <tt class="literal"><span class="pre">docstring</span></tt>
+is a magic docstring, i.e. a bracketed comma-separated list
+of decorator names. For instance <tt class="literal"><span class="pre">decorators.get('[MethodDecorator]')</span></tt>
+gives the list of all subclasses of <tt class="literal"><span class="pre">MethodDecorator</span></tt>, i.e. all method
+decorators, whereas <tt class="literal"><span class="pre">decorators.get('[ClassDecorator]')</span></tt>
+gives the list of the known class decorators. It is even possible
+to use the comma notation:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; decorators.get(&quot;[classmethod,tracedmethod]&quot;)
+[&lt;class 'noconflict.classmethodtracedmethod'&gt;]
+</pre>
+<p>For instance, it is possible to decorate functions by hand,
+without using magic docstring. Here is an example:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; do_nothing=decorators.staticmethod(lambda:None)
+&gt;&gt;&gt; print do_nothing # ``do_nothing`` is a static method
+&lt;staticmethod:&lt;lambda&gt;&gt;
+</pre>
+<p>One can even compose decorators by hand:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class B: pass
+...
+&gt;&gt;&gt; B.chattystatic=customdec.chattymethod2(do_nothing)
+&gt;&gt;&gt; B.chattystatic()
+calling &lt;chattymethod2staticmethod:&lt;lambda&gt;&gt; from &lt;class B[ClassDecorator]&gt;
+</pre>
+<p>In other words</p>
+<blockquote>
+<tt class="literal"><span class="pre">decorator1(decorator2(obj))</span></tt></blockquote>
+<p>automagically creates a composed class <tt class="literal"><span class="pre">decorator1decorator2</span></tt> in the
+<tt class="literal"><span class="pre">noconflict</span></tt> module (or recycle it, if <tt class="literal"><span class="pre">decorator1decorator2</span></tt> has
+been already created) and it is equivalent to</p>
+<blockquote>
+<tt class="literal"><span class="pre">decorator1decorator2(obj)</span></tt></blockquote>
+<p>Here is the check:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; decorators.get(&quot;[chattymethod2staticmethod]&quot;)
+[&lt;class 'noconflict.chattymethod2staticmethod'&gt;]
+</pre>
+<p>Here is another example:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from customdec import tracedmethod
+&gt;&gt;&gt; class C(object):
+... def fact(self,n):
+... if n==0: return 1
+... else: return n*self.fact(n-1)
+... fact=tracedmethod(fact)
+&gt;&gt;&gt; c=C()
+&gt;&gt;&gt; c.fact(2)
+Calling '?.fact' with arguments &lt;C instance&gt;(2,){} ...
+ Calling '?.fact' with arguments &lt;C instance&gt;(1,){} ...
+ Calling '?.fact' with arguments &lt;C instance&gt;(0,){} ...
+ '?.fact' called with result: 1
+ '?.fact' called with result: 1
+'?.fact' called with result: 2
+2
+</pre>
+<p>In this second syntax <tt class="literal"><span class="pre">fact</span></tt> does not know where it
+is defined, unless the containing class is explicitly set:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; C.__dict__['fact'].__klass__=C
+</pre>
+<p>Now the code will work as with the docstring syntax.</p>
+<p>What happens if you try to decorate something which is already
+decorated? You get <tt class="literal"><span class="pre">None</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; def f(x): &quot;[tracedmethod]&quot;
+...
+&gt;&gt;&gt; tm=decorators.decorated(f) # creates a tracedmethod from f
+&gt;&gt;&gt; print decorators.decorated(tm) # trying to decorate a tracedmethod
+None
+</pre>
+<p>You can compose decorators in a trivial way:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; cmtm=decorators.classmethod(tm)
+&gt;&gt;&gt; print cmtm
+&lt;classmethodtracedmethod:f&gt;
+</pre>
+<p>whereas you can compose classes:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C: &quot;[Decorated]&quot;
+...
+&gt;&gt;&gt; print customdec.Traced(C)
+&lt;class C[TracedDecorated]&gt;
+</pre>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D: pass
+...
+&gt;&gt;&gt; print customdec.Decorated(customdec.Traced(D))
+&lt;class D[DecoratedTraced]&gt;
+</pre>
+<p>This is the hierarchy:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; for C in type(cmtm).mro(): print C
+...
+&lt;class 'noconflict.classmethodtracedmethod'&gt;
+&lt;class 'decorators.classmethod'&gt;
+&lt;class 'customdec.tracedmethod'&gt;
+&lt;class 'decorators.MethodDecorator'&gt;
+&lt;class 'decorators.Decorator'&gt;
+&lt;type 'object'&gt;
+</pre>
+<p>One can also decorate classes by hand, by using class decorators.
+<tt class="literal"><span class="pre">decorators.ClassDecorator</span></tt> which converts a regular (both old
+style or new style) class in a class with the ability to recognize
+magic docstrings. Actually, the <tt class="literal"><span class="pre">decorators.enhance_classes()</span></tt>
+trick works by decorating the <tt class="literal"><span class="pre">object</span></tt> class with
+<tt class="literal"><span class="pre">decorators.ClassDecorator</span></tt> and by setting the custom metaclass to
+<tt class="literal"><span class="pre">decorators.ClassDecorator</span></tt> and it is equivalent to write</p>
+<blockquote>
+<pre class="literal-block">
+import decorators
+object=decorators.ClassDecorator(object) # decorates all new style classes
+__metaclass__= decorators.ClassDecorator # decorates all old style classes
+</pre>
+</blockquote>
+<p>on top of your module.
+If you want the magic to work only for new style classes only, you may
+forget the
+second line; if you want the magic to work for old style classes only, you
+may forget the first line.</p>
+<p>If the module contains a magic docstring which is an explicit class decorator,
+such as <tt class="literal"><span class="pre">decorators.Decorated</span></tt>, then <tt class="literal"><span class="pre">decorators.decorated</span></tt> look at the
+magic docstring and executes something like</p>
+<blockquote>
+<pre class="literal-block">
+import decorators
+object=decorators.Decorated(object) # decorates all new style classes
+__metaclass__= decorators.Decorated # decorates all old style classes
+</pre>
+</blockquote>
+<p>It is possible to go even deeper in black magic, and to decorate all
+the new style classes in <em>all</em> modules, by decorating <tt class="literal"><span class="pre">__builtin__.object</span></tt>:</p>
+<blockquote>
+<pre class="literal-block">
+import decorators,__builtin__
+__builtin.object=decorators.decorated(object)
+</pre>
+</blockquote>
+<p>Still, redefining <tt class="literal"><span class="pre">__builtin__object</span></tt> is not recommended since it
+may induce metaclass conflicts in other modules using metaclasses.
+It will work only if you import modules not using metaclasses, or
+modules using metaclasses safely, i.e. modules taking care of
+possible conflicts by using the <tt class="literal"><span class="pre">makecls</span></tt> function or an equivalent one.</p>
+</div>
+<div class="section" id="the-implementation">
+<h1><a class="toc-backref" href="#id10" name="the-implementation">The implementation</a></h1>
+<p>This part can be safely skipped, unless you are a <em>really</em> curious and
+you want to know how the implementation works.</p>
+<p>The module is rather short (~150 lines) but far from being trivial,
+since it is based on extensive usage of metaclass wizardry.</p>
+<p>The main class-metaclass hierarchy is represented in figure 1, where
+boxes denote classes and ovals denote metaclasses; instantiation is
+denoted by dashed green lines whereas inheritance is denoted by continuous
+blue lines.</p>
+<div class="figure">
+<p><img alt="decorators.png" src="decorators.png" /></p>
+</div>
+<p>Notice that <tt class="literal"><span class="pre">MetaDecorator</span></tt> (inherited via <tt class="literal"><span class="pre">Decorator</span></tt>) is the
+metaclass of all decorators. Class decorators are already metaclasses,
+so <tt class="literal"><span class="pre">MetaDecorator</span></tt> is actually a meta-metaclass with respect to
+instances of decorated classes, whereas it is a simple metaclass with
+respect to instances of decorated methods. For this reason in the
+presenced of class decorators the unusual relation</p>
+<p>assert object.__metaclass__ != object.__class__</p>
+<p>holds. More specifically</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; object.__class__
+&lt;class 'decorators.ClassDecorator'&gt;
+</pre>
+<p>but</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; object.__metaclass__
+&lt;class 'decorators.MetaDecorator'&gt;
+</pre>
+<p>since <tt class="literal"><span class="pre">object</span></tt> the <tt class="literal"><span class="pre">__metaclass__</span></tt>
+attribute is inherited from <tt class="literal"><span class="pre">Decorator</span></tt>.</p>
+<p>The implementation is relatively smart. Consider for instance the case of
+the logged example. In that example class <tt class="literal"><span class="pre">D</span></tt> was a subclass of a tricked
+<tt class="literal"><span class="pre">object</span></tt> class, enhanced by a metaclass <tt class="literal"><span class="pre">ClassDecorator</span></tt>. Moreover <tt class="literal"><span class="pre">D</span></tt>
+had a <tt class="literal"><span class="pre">Logged</span></tt> docstring. Therefore it should have been an instance of
+<tt class="literal"><span class="pre">_ClassDecoratorLogged</span></tt> metaclass. But logged was
+a subclass of <tt class="literal"><span class="pre">ClassDecorator</span></tt>, therefore it already had all the features
+of <tt class="literal"><span class="pre">ClassDecorator</span></tt> and it would have been redundant to create
+<tt class="literal"><span class="pre">_ClassDecoratorLogged</span></tt>, when``Logged`` would have been enough.
+So <tt class="literal"><span class="pre">Logged</span></tt>
+was used and <tt class="literal"><span class="pre">_ClassDecoratorLogged</span></tt> was never created. All the magic is in
+the <tt class="literal"><span class="pre">noconflict</span></tt> module discussed in my <a class="reference" href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197">cookbook</a> recipe.</p>
+<p>The current implementation does not make any attempt of optimization and
+there may be alternative implementations faster or more memory efficient.
+At this experimental level I didn't care to explore about performances
+issues. They does not probably matter unless one has to decorate
+thousands or millions of functions and classes.</p>
+<p>Things to do: adding more error checking.</p>
+<p>Finally, a word about bugs. The <tt class="literal"><span class="pre">decorators</span></tt> module is fairly sophisticated,
+therefore whereas I can guarantee that it passes my test suite (which involves
+~100 tests automatically extracted from the documentation you are reading),
+I cannot guarantee that it is correct.
+If somebody finds a bug or an unexpected
+behavior, please let me know and I will try to fix it.</p>
+<!-- References: -->
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="decorators.txt">View document source</a>.
+Generated on: 2003-09-17 14:45 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/pypers/pep318/working/decorators.py b/pypers/pep318/working/decorators.py
new file mode 100755
index 0000000..ddf3ec9
--- /dev/null
+++ b/pypers/pep318/working/decorators.py
@@ -0,0 +1,173 @@
+# implementation with a strong usage of metaclasses
+
+"""
+A module to implement pep318 (decorator syntax) via magic doctrings.
+For the documentation see
+
+http://www.phyast.pitt.edu/~micheles/python/decorators,html
+
+and the on-line help.
+"""
+
+import sys, re, inspect, __builtin__, noconflict
+from types import FunctionType,ClassType
+from noconflict import makecls
+#from printerr import printerr
+
+############################ UTILITIES ##############################
+
+MAGICDOC=re.compile(r'\s*\[([\w_\s,]*)\]')
+# regexp to recognize magic docstrings
+
+class UnknownDecoratorError(Exception):
+ "The name says it all"
+
+class MetaDecorator(type):
+ """Metaclass inducing a certain amount of magic on decorators:
+ 1. Each time a decorator is defined in any module, it is stored in
+ MetaDecorator.dic and MetaDecorator.ls.
+ 2. If the (method) decorator has a 'get' method, a '__get__' method
+ is automagically created as an alias to 'get'.
+ 3. Decorators calls are dispatched to the decorator _call_
+ classmethod."""
+
+ dic,ls={},[]
+
+ def __init__(dec,*args):
+ super(MetaDecorator,dec).__init__(*args)
+ MetaDecorator.dic[dec.__name__]=dec
+ MetaDecorator.ls.append(dec)
+ get=dec.__dict__.get('get') # look at get
+ if get: dec.__get__=get # alias __get__ to get
+
+ def __call__(dec,*args):
+ nargs=len(args)
+ if nargs==1: # simple call of kind dec(obj)
+ obj=args[0]
+ if isinstance(obj,Decorator):
+ dec=composed(dec,obj.__class__) # composed default decorator
+ dec=decorator_from(obj.__doc__,dec)
+ elif nargs==3: # class decorator called with three arguments
+ dec=decorator_from(args[2].get('__doc__'),dec)
+ return dec._call_(*args) # dispatch to the correct _call_ classmethod
+
+def composed(*dclasses):
+ dclasses=noconflict.remove_redundant(dclasses)
+ decname=''.join([d.__name__ for d in dclasses])
+ decorator=MetaDecorator.dic.get(decname)
+ if not decorator: decorator=makecls()(decname,dclasses,{})
+ return decorator
+
+def decorator_from(docstring,defaultdec=None):
+ """Takes a magic docstring and a default decorator
+ and returns a decorator class or None. It tries to be smart."""
+ match=MAGICDOC.match(docstring or '')
+ if not match: return defaultdec
+ decnames=map(str.strip,match.group(1).split(','))
+ try: dclasses=[MetaDecorator.dic[n] for n in decnames] # get the decorator
+ except KeyError: raise UnknownDecoratorError(n) # classes from the names
+ if defaultdec: dclasses.insert(0,defaultdec)
+ return composed(*dclasses)
+
+def decorate(objdict):
+ """Takes an object with a dictionary and decorates all its functions
+ and classes according to their docstrings."""
+ for name,obj in objdict.__dict__.items():
+ if getattr(obj,'__doc__',None): # non-empty docstring
+ dec_obj=decorated(obj) or obj
+ if dec_obj is not obj:
+ setattr(dec_obj,'__klass__',objdict)
+ setattr(objdict,name,dec_obj)
+
+def get(docstring=None):
+ "List of recognized decorators"
+ dec=decorator_from(docstring,Decorator)
+ isdecorator=lambda x: issubclass(x,dec)
+ return filter(isdecorator,MetaDecorator.ls)
+
+#################### functions of the API #################################
+
+def decorated(obj):
+ """If obj is a function or a class, returns a decorated object created
+ according to obj's docstring or the original obj if no magic docstring
+ is found; otherwise it returns None"""
+ if isinstance(obj,(FunctionType,ClassType,type)): # is function or class
+ return Decorator(obj) or obj
+
+def enhance_classes(docstring='[ClassDecorator]'):
+ """Enhances all the classes in the caller module with a metaclass
+ built from the given docstring."""
+ callerglobals=sys._getframe(1).f_globals
+ dec=decorator_from(docstring)
+ callerglobals['__metaclass__']=dec
+ callerglobals['object']=dec('object',(),{})
+
+####################### BASIC DECORATORS ###########################
+
+class Decorator(object):
+ """Instance of MetaDecorator and mothers of all decorators. When called
+ in the form Decorator(obj), with obj having a magic docstring, it returns
+ an instance of the correct decorator, otherwise it returns None."""
+ __metaclass__=MetaDecorator
+ def _call_(dec,obj):
+ "Returns None, all the interesting stuff is in MetaDecorator.__call__"
+ _call_=classmethod(_call_)
+
+class MethodDecorator(Decorator):
+ """Descriptor class callable with a function or a descriptor object
+ as argument. The calling syntax is redefined by the meta-metaclass
+ MetaDecorator. It redefines__str__ and get (i.e. __get__) on its instances.
+ """
+ __klass__=type('?',(),{}) # dummy owner class, to be overridden
+ def __init__(self,objfunc):
+ "objfunc is a decorator object or a function"
+ assert isinstance(objfunc,(FunctionType,Decorator))
+ super(MethodDecorator,self).__init__(objfunc)
+ self.__func__=getattr(objfunc,'__func__',objfunc)
+ def get(self,obj,cls=None):
+ "aliased to __get__, to be overridden"
+ return self.__func__.__get__(obj,cls)
+ def __str__(self):
+ "Printing representation of kind <decoratorclass:functionname>"
+ return '<%s:%s>' % (self.__class__.__name__,self.__func__.__name__)
+ def _call_(dec,obj):
+ "Returns a method decorator object."
+ return type.__call__(dec,obj) # calls __new__ and __init__
+ _call_=classmethod(_call_)
+
+
+class ClassDecorator(type,Decorator):
+ """Metaclass callable with one or three arguments, having its calling
+ syntax redefined by the meta-metaclass MetaDecorator. It redefines
+ __str__ both on classes and instances."""
+ def __init__(cls,name,bases,dic):
+ super(ClassDecorator,cls).__init__(name,bases,dic)
+ if cls.__str__ is object.__str__: # redefine default __str__
+ cls.__str__=lambda self: "<%s instance>" % self.__class__.__name__
+ def __str__(cls):
+ return '<class %s[%s]>' % (cls.__name__,cls.__class__.__name__)
+ def _call_(dec,*args):
+ "Returns a decorated class"
+ a=args[0] # first argument; can be a string or a class
+ if inspect.isclass(a): args=a.__name__,a.__bases__,a.__dict__.copy()
+ return makecls(dec)(*args)
+ _call_=classmethod(_call_)
+
+class Decorated(ClassDecorator):
+ """Metaclass which decorates its instances"""
+ def __init__(cls,name,bases,dic):
+ super(Decorated,cls).__init__(name,bases,dic)
+ decorate(cls)
+
+#################### Built-in Method Decorators ######################
+
+class staticmethod(MethodDecorator):
+ "Decorator, converts a function in a staticmethod"
+ def get(self,obj,cls=None):
+ return super(staticmethod,self).get(obj,cls).im_func
+
+class classmethod(MethodDecorator):
+ "Decorator, converts a function in a classmethod"
+ def get(self,obj,cls=None):
+ if cls is None: cls=type(obj)
+ return super(classmethod,self).get(cls,cls)
diff --git a/pypers/pep318/working/decorators.txt b/pypers/pep318/working/decorators.txt
new file mode 100755
index 0000000..18fb320
--- /dev/null
+++ b/pypers/pep318/working/decorators.txt
@@ -0,0 +1,1346 @@
+Implementing PEP 318 (decorators)
+======================================================================
+
+ :Module: decorators
+ :Version: 0.5
+ :Author: Michele Simionato
+ :e-mail: MicheleSimionato@libero.it
+ :Licence: Python-like
+ :Disclaimer: This is experimental code. Use it at your own risk!
+
+.. contents::
+
+Having plenty of free time in these days, I have finished an old
+project of mine, the implementation of PEP 318 in pure Python.
+
+Here is the rationale:
+
+* some kind of decorator syntax is scheduled to go in Python 2.4,
+ therefore it is interesting to play with the concept;
+
+* it is nice to play with decorators now, without having to
+ wait for one year or so;
+
+* it is much easier levelto experiment with a pure Python implementation
+ than with a C implementation;
+
+* the implementation can be seen as an exercise on modern Python
+ programming and may be valuable to people wanting to study the most
+ advanced new constructs in Python 2.2 (descriptors_, metaclasses_,
+ `cooperative methods`_, etc.)
+
+Basics
+--------------------------------------------------------------------
+
+PEP 318 has the goal of providing a nice syntactic sugar for expressions like
+
+ ::
+
+ def identity(x):
+ return x
+ identity=staticmethod(identity)
+
+or
+
+ ::
+
+ def name(cls):
+ return cls.__name__
+ name=classmethod(name)
+
+which are pretty verbose. It is clear that having new syntax (as
+for instance the proposed square bracket notation)
+
+ ::
+
+ def identity(x)[staticmethod]:
+ return x
+
+ def name(cls)[classmethod]:
+ return cls.__name__
+
+involves changing the grammar and modifying the interpreter at the
+C level. This means a lot of work. Fortunately, it is possible to
+have the same effect without changing the Python grammar.
+The idea is to use magic docstrings like this:
+
+ ::
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+The implementation is able to recognize such docstrings
+and to automagically convert those methods in decorators.
+
+Decorators are nothing else than a sophisticated kind of wrappers.
+The ``decorators`` module provides support both for method decorators,
+which wrap functions and class decorator, which wrap classes.
+``staticmethod`` and ``classmethod`` are two examples of already existing
+method decorators (actually my implementation rewrites them, but let me
+pass on this detail). Technically speaking, method decorators are classes
+taking a single function as input and producing a descriptor object
+as output (properties are not decorators according to this definition,
+since they take four functions as input, ``get, set, del_`` and ``doc``).
+Descriptors are objects with a ``__get__`` method; they are quite
+sophisticated, but fortunately they have been wonderfully explained by
+Raymond Hettinger already, so I am allowed to skip on this point ;).
+A knowledge of descriptors is not needed in order to use the ``decorator``
+module; however it is welcomed for advanced users wanting to implement
+custom method decorators.
+Class decorators are metaclasses taking a class as imput and returning
+a decorated class as output. A good understanding of metaclasses is needed
+in order to be able to write custom class decorators, but no knowledge
+at all is required in order to use the pre-defined class decorators
+provided by the module.
+Finally, the module is meant to be extensible; so one could
+define new kind of decorators. For instance, the original version of
+the module also had the concept of module decorators; however I have cut
+down that part in order to keep the module short.
+
+Admittedly, the implementation
+is not for the faint of heart, nevertheless I have tried to make the
+basic usage easy and simple to understand.
+
+Simple usage of decorators
+------------------------------------------------------------------------
+
+Before talking about the implementation details, I will show
+how the ``decorators`` module works in practice. The simplest and safest
+usage is by means of the ``decorators.decorated()`` function, which
+takes an object (a function or a class) and checks its docstring: if
+a magic docstring is found, it returns a decorated version of the object,
+otherwise it returns the original object. Using ``decorators.decorated()``
+is simple but verbose, so magic shortcuts will be discussed in the next
+section.
+
+Here, let me give an example, showing that method decorators work both for
+`new style classes and old style classes`_:
+
+ ::
+
+ #<example1.py>
+
+ import decorators
+
+ def do_nothing(self):
+ "No magic docstring here"
+ dec_do_nothing=decorators.decorated(do_nothing)
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+ dec_identity=decorators.decorated(identity)
+
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+ dec_name=decorators.decorated(name)
+
+ class OldStyle:
+ do_nothing=dec_do_nothing
+ identity=dec_identity
+
+ class NewStyle(object):
+ name=dec_name
+
+ o=OldStyle() # creates an old style instance
+ n=NewStyle() # creates a new style instance
+
+ #</example1.py>
+
+In this example, both ``dec_identity`` and ``dec_name`` are decorator objects,
+i.e. descriptors modifiying the attribute access. It is easy to recognize
+decorators objects, since they have a re-defined printing representation:
+
+>>> from example1 import *
+
+>>> print dec_identity
+<staticmethod:identity>
+
+>>> print dec_name
+<classmethod:name>
+
+Now, let me check that ``dec_ identity`` works as a staticmethod,
+
+>>> assert OldStyle.identity(1) == 1 # called from the class
+>>> assert o.identity(1) == 1 # called from the instance
+
+whereas ``dec_name`` works as a classmethod:
+
+>>> assert NewStyle.name() == 'NewStyle' # called from the class
+>>> assert n.name() == 'NewStyle' # called from the instance
+
+On the other hand, ``do_nothing`` does not have a magic
+docstring, therefore it is not converted to a decorator object;
+actually it is *exactly* the original function:
+
+>>> assert dec_do_nothing is do_nothing # not converted
+
+Therefore it works without surprises:
+
+>>> o.do_nothing() # does nothing, correct
+
+For sake of convenience, I have re-implemented the built-in
+``staticmethod`` and ``classmethod``, so
+
+>>> isinstance(dec_identity,staticmethod)
+False
+
+and
+
+>>> isinstance(dec_name,classmethod)
+False
+
+but
+
+>>> isinstance(dec_identity,decorators.staticmethod)
+True
+
+and
+
+>>> isinstance(dec_name,decorators.classmethod)
+True
+
+It is possible to recognize method decorators since they provides
+a couple of special attributes:
+
+``__func__``, returning the function from which they originated
+
+ >>> assert dec_identity.__func__ is identity
+ >>> assert dec_name.__func__ is name
+
+and ``__klass__``, returning the class where they where defined
+
+ >>> dec_identity.__klass__
+ <class 'decorators.?'>
+
+The question mark here means that the definition class is unknown.
+
+Decorating classes
+----------------------------------------------------------------------
+
+The problem with the approach described in the previous section
+is that it does not present any significant advantage over
+the already existing mechanism. A real step forward would be to
+have classes with the ability of automatically converting their
+methods to method decorators according to the docstrings.
+This sounds a bit of magic, but actually can be done very simply
+by adding to the class a docstring starting with "[Decorated]"
+and decorating the class.
+Here is an example:
+
+ ::
+
+ #<example2.py>
+
+ from decorators import decorated
+ from example1 import do_nothing,identity,name
+
+ class B(object):
+ "This is a regular class"
+
+ B=decorated(B) # does nothing
+
+ class C(B):
+ "[Decorated]"
+ do_nothing=do_nothing
+ identity=identity
+ name=name
+
+ C=decorated(C) # regenerates the class converting methods in decorators
+ c=C()
+
+ #</example2.py>
+
+Here is the testing:
+
+>>> from example2 import *
+>>> assert C.identity(1) == 1
+>>> assert C.name() == 'C'
+>>> assert c.identity(1) == 1
+>>> assert c.name() == 'C'
+
+Notice that adding ``identity`` after the class creation with the syntax
+``C.identity=identity`` would not work;
+``C.identity=decorators.decorated(identity)`` is required:
+
+>>> C.identity=decorators.decorated(identity)
+>>> C.identity(1) # it works
+1
+
+If a class misses the magic docstring, nothing happens:
+
+>>> B # returns the original B
+<class 'example2.B'>
+
+The mechanism works for old style classes too:
+
+ ::
+
+ #<example2.py>
+
+ class D: # old style
+ "[Decorated]"
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ D=decorated(D)
+
+ d=D()
+
+ # test
+ assert d.identity(1) == 1
+ assert D.identity(1) == 1
+
+ #</example2.py>
+
+Under the hood ``decorators.decorated()`` recognizes the class level
+magic docstring "[Decorated]" and creates an instance of the
+``decorators.Decorated`` metaclass; incidentally,
+this converts old style classes in new style classes:
+
+>>> from example2 import D,d
+>>> type(D) # D is an instance of decorator.Decorated
+<class 'decorators.Decorated'>
+
+Internally the metaclass invokes ``decorators.decorated()``
+on the methods of its instances: this is why they becomes decorated
+if a suitable docstring is found. By the way, if you mispell a
+decorator name you get an helpful error message:
+
+>>> class E:
+... "[Decorated]"
+... def f():
+... "[staticmeth]"
+>>> E=decorators.decorated(E)
+Traceback (most recent call last):
+ .. a long and cryptic traceback here ..
+UnknownDecoratorError: staticmeth
+
+The enhancement provided by the metaclass includes a new default
+printing representation for both the class
+
+>>> print D # returns the name of D and of its metaclass
+<class D[Decorated]>
+
+and its instances:
+
+>>> print d
+<D instance>
+
+One can even forget the docstring in subclasses of decorated
+classes, since metaclasses are inherited:
+
+>>> class E(D):
+... def name(cls):
+... "[classmethod]"
+... return cls.__name__
+>>> print E.name()
+E
+
+This approach presents another advantage: the decorated methods know
+the class where they were defined via the special attribute ``__klass__``:
+
+>>> E.__dict__['name'].__klass__ # the class where 'name' is defined
+<class 'E'>
+
+This is useful for introspection and debugging purposes.
+
+Adding magic
+----------------------------------------------------------------------------
+
+The problem of the previous approach is that one must explicitely
+decorate the classes by hand, by invoking ``decorators.decorated()``
+each time. However, it is possible to add more magic
+and to decorate all the classes automatically.
+It is as easy as writing ``decorators.enhance_classes()``
+on top of the module. Then all methods in all classes of the module
+with a magic docstring will be checked for magic docstrings and
+automagically decorated if needed.
+For instance, the previous example would be written
+
+ ::
+
+ #<example4.py>
+
+ import decorators; decorators.enhance_classes()
+
+ class C:
+ "[Decorated]" # magic docstring here
+ def do_nothing(self):
+ "No magic docstring here"
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ class D(object):
+ "Undecorated" # no magic docstring here
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+ c=C(); d=D()
+
+ #</example4.py>
+
+``C`` has a ``[Decorated]`` docstring, so its methods
+are automatically decorated:
+
+>>> from example4 import *
+>>> assert c.do_nothing() is None
+>>> assert C.identity(1) == 1
+>>> assert c.identity(1) == 1
+
+On the other hand, since ``D`` misses a magic docstring,
+its ``name`` method is not decorated:
+
+>>> hasattr(D.__dict__['name'],'__func__') # not a decorator
+False
+
+Since ``D.name`` is a regular method and not a classmethod, ``D.name()``
+gives an error:
+
+>>> D.name()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method name() must be called with D instance as first argument (got nothing instead)
+
+The trick works for classes containing inner classes, too:
+
+ ::
+
+ #<example5.py>
+
+ import decorators; decorators.enhance_classes()
+
+ class C:
+ "[Decorated]" # required docstring
+ def identity(x):
+ "[staticmethod]"
+ return x
+ class Inner:
+ "[Decorated]" # required docstring
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+
+ assert C.identity(1) == 1
+ assert C.Inner.name() == 'Inner'
+
+ #</example5.py>
+
+Under the hood, the magic works by enhancing the ``object`` class
+of the module with a ``decorators.ClassDecorator`` metaclass:
+
+>>> import example5
+>>> type(example5.object)
+<class 'decorators.ClassDecorator'>
+
+Notice that for safety reasons the enhancement is only on the module
+``object`` class, not on the ``__builtin__.object`` class. The problem
+is that adding too much magic can be risky.
+
+The dangers of magic
+-----------------------------------------------------------------------
+
+For the sake of metaclass users, in this section I will point out the
+dangers of the ``enhance_classes()`` syntax. On the other hand, if you
+never use metaclasses, you may safely skip to the following section.
+
+The problem is that the ``enhance_classes()`` syntax is not 100% safe,
+because of possible metaclass conflicts.
+Here is an example:
+
+>>> import decorators; decorators.enhance_classes()
+
+This line enhances the ``object`` class in the interpreter namespace:
+
+>>> print object
+<class object[ClassDecorator]>
+
+This shows that ``object`` is an instance of ``ClassDecorator``.
+
+>>> class M(type):
+... "Some non-trivial code here..."
+
+This line creates a custom metaclass we want to use to enhance our classes.
+
+>>> class D(object): __metaclass__=M # does not work!
+...
+Traceback (most recent call last):
+ ...
+TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+
+The problem is that the previous line tries to create a class ``D``
+which should have both metaclasses ``ClassDecorator`` and ``M``:
+a conflict follows.
+
+Fortunately, the decorators module imports the ``makecls`` function from my
+``noconflict`` module (described in the cookbook_)
+just to avoid this kind of problems:
+
+>>> class D(object):
+... __metaclass__=decorators.makecls(M)
+
+Now the class has been safely created as an instance of the composed
+class ``ClassDecoratorM``.
+
+>>> type(D)
+<class 'noconflict.ClassDecoratorM'>
+
+If we want ``M`` to have the priority over ``ClassDecorator``, the
+option ``priority=True`` makes the job:
+
+>>> class D(object):
+... __metaclass__=decorators.makecls(M,priority=True)
+>>> type(D)
+<class 'noconflict.MClassDecorator'>
+
+The situation for old style classes is worse, since
+
+>>> class D:
+... __metaclass__=M
+... def sm():
+... "[staticmethod]"
+
+apparently gives no error, but actually the metaclass ``M`` overrides
+``ClassDecorator``, so ``D`` will not recognize magic docstrings:
+
+>>> type(D)
+<class 'M'>
+>>> D.sm()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with D instance as first argument (got nothing instead)
+
+Using ``decorators.makecls(M)`` will not help here (because of the way Python
+assigns metaclasses) and the only solution is to be completely explicit:
+
+>>> class D:
+... __metaclass__=decorators.makecls(decorators.ClassDecorator,M)
+... def sm():
+... "[staticmethod]"
+>>> type(D)
+<class 'noconflict.ClassDecoratorM'>
+
+Now ``D`` is not decorated since it does miss a magic docstring, but
+it provides the ability to recognizing magic docstrings, so ``D``
+subclasses with a "[Decorated]" docstring will be decorated:
+
+>>> class E(D):
+... "[Decorated]"
+... def cm(cls):
+... "[classmethod]"
+... print '.cm() called from',cls
+
+>>> E.cm() # it works
+.cm() called from <class E[ClassDecoratorMDecorated]>
+
+Notice that ``sm`` was defined in ``D``, the undecorated class: therefore
+it is not decorated:
+
+>>> E.sm() # correctly, does not work
+Traceback (most recent call last):
+ ...
+TypeError: unbound method sm() must be called with E instance as first argument (got nothing instead)
+
+The error message says clearly that ``sm`` is an unbound method and not
+a static method.
+
+Defining method decorators
+-----------------------------------------------------------------------
+
+The ``decorators module`` contains two predefinite method decorators,
+``staticmethod`` and ``classmethod``, which emulate the built-ins
+with the same names. However, it is possible to write your own
+custom decorators. The ``decorators.MethodDecorator`` class which is here
+exactly for that purpose.
+
+Custom decorators are expected to be implemented by subclassing
+``MethodDecorator`` and by overriding its ``get`` method. The
+``get`` method automagically induces a ``__get__`` method, turning the
+class in a descriptor. The machinery is needed since ``__get__`` cannot
+be made cooperative using the standard ``super`` mechanism because
+there would be a confusion between ``super.__get__`` and the decorator
+``__get__``. This is a bit tricky, but the causal programmer is not
+expected to write custom decorators, and actually I don't want to make
+the access to decorators *too* easy, since they are potentially dangerous.
+
+In order to give a simple example, let me show the implementation
+of a ``chattymethod`` that prints a message when it is called:
+
+ ::
+
+ #<customdec.py>
+
+ from decorators import *
+
+ class chattymethod(MethodDecorator):
+ logfile=sys.stdout # default
+ def get(self,obj,cls=None): # same signature as __get__
+ self.logfile.write('calling %s from %s\n' % (self,obj or cls))
+ return super(chattymethod,self).get(obj,cls)
+
+ #</customdec.py>
+
+Notice the usage of the ``super().get`` trick. This guarantees that
+``chattymethod`` will play well with other decorators (i.e. it
+can be nicely composed via multiple inheritance). The point will
+be fully discussed in the section on composing decorators.
+
+Here is an example of usage:
+
+>>> import customdec # adds chattymethod to the list of known decorators
+>>> customdec.enhance_classes() # automagically enhances classes when needed
+>>> class C:
+... " [Decorated] "
+... def f(self):
+... """
+... [ chattymethod ]
+... """
+>>> c=C()
+>>> c.f()
+calling <chattymethod:f> from <C instance>
+
+By the way, this shows that one can safely add whitespaces (including
+newlines) to the magic docstring: they are simply ignored.
+
+One can check that the syntax ``C.f(c)`` works too:
+
+>>> C.f(c)
+calling <chattymethod:f> from <class C[Decorated]>
+
+A tricky point of the decorators mechanism is the issue of parameter passing.
+In comp.lang.python there was the proposal of allowing explicit parameter
+passing to decorators, with a syntax of kind
+
+ ::
+
+ def f(self)[chattymethod(logfile=file('file1.log','w'))]
+
+In my view, there are too many parenthesis in this syntax, and it may
+become rapidly unreadable. Moreover, it complicates the implementation
+without any real benefit, so the decorators module does not allow
+this kind of parameter passings. There are however viable
+workarounds, so you should not miss the syntax.
+
+A simple minded solution is to change the defaults by hand:
+
+>>> from customdec import chattymethod,decorated
+>>> chattymethod.logfile=file('file.log','w')
+>>> def g(self):
+... "[chattymethod]"
+>>> C.g=decorated(g)
+>>> c.g() # will print a message on file.log
+
+This approach has the drawback that chattymethods created before changing
+the logfile will also print to the new logfile, if invoked after the
+change. Therefore
+
+>>> c.f()
+
+will print a message to ``file.log`` too, and not to standard output.
+Here is the confirmation:
+
+>>> chattymethod.logfile.close()
+>>> print file('file.log').read().rstrip()
+calling <chattymethod:g> from <C instance>
+calling <chattymethod:f> from <C instance>
+
+A much better solution is to pass
+parameters to method decorators as function attributes: then the function
+attributes can be converted to attributes of the decorator
+in the ``__init__`` method. Here is an example:
+
+ ::
+
+ #<customdec.py>
+
+ class chattymethod2(chattymethod):
+ logfile=sys.stdout # default
+ def __init__(self,objfunc):
+ super(chattymethod2,self).__init__(objfunc)
+ logfile=getattr(self.__func__,'logfile',None)
+ if logfile: self.logfile=logfile
+
+ #</customdec.py>
+
+Notice that the ``__init__`` method has the signature
+``__init__(self,objfunc)``, where the ``objfunc`` object is a
+decorator object or the function to be converted in the decorator
+object, and that it is cooperative.
+This is the suggested way of overriding ``__init__`` (see also
+``help(decorators.MethodDecorator.__init__)``).
+
+Here is the testing:
+
+ ::
+
+ #<chatty2.py>
+
+ import customdec; customdec.enhance_classes("[Decorated]")
+
+ # sets the log files
+ log1=file('file1.log','w')
+ log2=file('file2.log','w')
+
+ class C:
+ def f(self):
+ "[chattymethod2]"
+ f.logfile=log1 # function attribute
+ def g(self):
+ "[chattymethod2]"
+ g.logfile=log2 # function attribute
+
+ assert C.__dict__['f'].logfile is log1 # check the conversion
+ assert C.__dict__['g'].logfile is log2 # function attr. -> decorator attr.
+
+ c=C() # C instantiation
+
+ c.f() # print a message in file1.log
+ c.g() # print a message in file2.log
+
+ log1.close(); log2.close() # finally
+
+ #</chatty2.py>
+
+Let me check the contents of the log files:
+
+>>> import chatty2
+>>> print file('file1.log').read().rstrip()
+calling <chattymethod2:f> from <C instance>
+>>> print file('file2.log').read().rstrip()
+calling <chattymethod2:g> from <C instance>
+
+``chattymethod`` is the poor man version of ``tracedmethod``, a
+sophisticated decorator for tracing methods.
+Here is the code, given for pedagogical purposes; the lazy reader can
+skip it and go directly to the usage section.
+
+ ::
+
+ #<customdec.py>
+
+ class tracedmethod(MethodDecorator):
+ "Descriptor class, converts a method in a traced method"
+ indent=0; output=sys.stdout # defaults
+
+ def __init__(self,objfunc):
+ super(tracedmethod,self).__init__(objfunc)
+ self.funcname=self.__func__.__name__
+ output=getattr(self.__func__,'output',None)
+ if output: self.output=output # func.attr. -> dec.attr.
+
+ def get(self,obj,cls):
+ clsname=self.__klass__.__name__ # definition clas
+ def tracedmeth(obj,*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write("%sCalling '%s.%s' with arguments " %
+ (i,clsname,self.funcname))
+ self.output.write("%s%s ...\n" % (obj or '',str(args)+str(kw)))
+ res=super(tracedmethod,self).get(obj,cls)(*args,**kw)
+ self.output.write("%s'%s.%s' called with result: %s\n"
+ % (i,clsname,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return tracedmeth.__get__(obj,cls) # method wrapper
+
+ #</customdec.py>
+
+``tracedmethod.get`` returns a method wrapper object, so it is
+possible to use ``im_func`` to retrieve the internal function
+``tracedmeth``:
+
+>>> class C:
+... "[Decorated]"
+... def f(self):
+... "[tracedmethod]"
+>>> c=C(); c.f()
+Calling 'C.f' with arguments <C instance>(){} ...
+'C.f' called with result: None
+>>> c.f.im_func.__name__
+'tracedmeth'
+
+As soon as the ``tracedmethod`` module is loaded, the ``tracedmethod`` class
+is added to the list of know decorators, so one should use the
+"[tracedmethod]" docstring and not something like
+"[customdec.tracedmethod]".
+
+Here is a less trivial example of usage, writing in a log file the
+internal working of a recursive function:
+
+ ::
+
+ #<example9.py>
+
+ import customdec; customdec.enhance_classes()
+
+ logfile=file('file3.log','w')
+
+ class C(object):
+ "[Decorated]"
+ def fact(self,n):
+ "[tracedmethod] The good old factorial."
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact.output=logfile
+
+ C().fact(2) # write a message to logfile
+
+ logfile.close()
+
+ #</example9.py>
+
+Here is the content of the ``file3.log``:
+
+>>> import example9
+>>> print file('file3.log').read().rstrip()
+Calling 'C.fact' with arguments <C instance>(2,){} ...
+ Calling 'C.fact' with arguments <C instance>(1,){} ...
+ Calling 'C.fact' with arguments <C instance>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+
+Composing decorators
+---------------------------------------------------------------------
+
+Decorators can be composed by using magic docstrings with comma-separated
+decorator names. For instance, you can trace a classmethod as in this example:
+
+ ::
+
+ #<example6.py>
+
+ "How to trace a class method"
+
+ import customdec; customdec.enhance_classes()
+
+ class C(object):
+ "[Decorated]"
+ def fact(cls,n): # a traced classmethod
+ "[classmethod,tracedmethod]"
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+ #</example6.py>
+
+Here is the testing:
+
+>>> from example6 import C
+>>> C.fact(2)
+Calling 'C.fact' with arguments <class C[Decorated]>(2,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(1,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+
+You may easily check that calling ``.fact`` from the instance will work too.
+
+Under the hood the syntax
+
+ ::
+
+ [classmethod,tracedmethod]
+
+generates a ``classmethodtracedmethod`` class obtained via
+multiple inheritance:
+
+>>> C.__dict__['fact'].__class__
+<class 'noconflict.classmethodtracedmethod'>
+
+Notice that the order does matter and using the docstring
+"[tracedmethod,classmethod]" will not work:
+
+>>> class D:
+... "[Decorated]"
+... def f(cls):
+... "[tracedmethod,classmethod]"
+>>> D.f()
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with D instance as first argument (got nothing instead)
+
+The problem here is that ``tracedmethod.get`` returns a method-wrapper object
+which expects a D instance as first argument whereas it gets ``None`` since
+it is called from the class. On the other hand,
+
+>>> D().f()
+Calling 'D.f' with arguments <D instance>(){} ...
+'D.f' called with result: None
+
+will work. When ``classmethod`` precedes ``tracedmethod``, then
+``classmethod`` passes to ``tracedmeth`` a non-empty first argument,
+i.e. the calling class, even when called from the instance:
+
+>>> C().fact(2)
+Calling 'C.fact' with arguments <class C[Decorated]>(2,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(1,){} ...
+ Calling 'C.fact' with arguments <class C[Decorated]>(0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+
+If we try to trace a staticmethod, we will get a different error with
+the order "tracedmethod, staticmethod":
+
+>>> class F(object):
+... "[Decorated]"
+... def fact(n):
+... "[tracedmethod,staticmethod]"
+... if n==0: return 1
+... else: return n*F.fact(n-1)
+>>> F.fact(2)
+Traceback (most recent call last):
+ ...
+TypeError: unbound method tracedmeth() must be called with F instance as first argument (got int instance instead)
+
+The message is self-explanatory.
+
+On the other hand, composing the decorators in the other order
+"[tracedmethod,staticmethod]" will work just fine.
+
+Defining class decorators
+-----------------------------------------------------------------------
+
+PEP 318 proposes to decorate methods by using descriptors; it is
+quite natural to extend this idea and to decorate classes by using
+class decorators implemented as metaclasses. We already saw a
+class decorator at work, the metaclass ``Decorated``, giving
+to its instances the ability to interpret magic docstrings,
+and converting functions in method decorators.
+
+To define a custom class decorator is easy: one defines a custom metaclass
+as usual, with the only difference from deriving by ``ClassDecorator`` instead
+of deriving from ``type``. To understand how this works in practice, let me
+show how to add logging capabilities to a given class. The first
+step is to define a suitable class decorator, such as the following:
+
+ ::
+
+ #<customdec.py>
+
+ class Logged(ClassDecorator):
+ output=sys.stdout
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print >> cls.output,"%s created" % cls
+
+ #</customdec.py>
+
+``Logged`` is derived by the metaclass ``ClassDecorator``,
+which provides a certain amount of magic under the hood (in particular
+its printing representation and its calling syntax are redefined by its
+metaclass ``MetaDecorator``). Logging capabilities can be added to a class
+by simply using the magic docstring syntax:
+
+ ::
+
+ #<logged.py>
+
+ import customdec; customdec.enhance_classes()
+
+ class D(object): # will print a message at D creation
+ "[Logged]"
+
+ #</logged.py>
+
+>>> import logged
+<class D[Logged]> created
+
+Notice that the printing representation of ``D`` involves the name
+of ``D`` preceded by the name of its metaclass, which in this case
+is ``Logged``
+
+Each time an instance of ``Logged`` is created, a similar message is printed:
+
+>>> class E(logged.D):
+... pass
+<class E[Logged]> created
+
+Notice that ``E`` does not have any magic docstring
+
+>>> E.__doc__ # no docstring
+
+but still it inherits its magic from ``D``.
+
+Another simple example of class decorator is the following metaclass
+which modifies the docstrings of the methods of its instances,
+by magically inducing tracing capabilities on them:
+
+ ::
+
+ #<customdec.py>
+
+ from types import FunctionType
+
+ class Traced(ClassDecorator):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType): # modifies the docstring
+ func.__doc__="[tracedmethod] " + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d)
+
+
+ #</customdec.py>
+
+Here is an example of usage:
+
+>>> class C(object):
+... """[Decorated,Traced] The class decorator adds the magic docstring
+... '[tracedmethod]' to f1 and f2, which are then converted
+... to method decorator objects."""
+... def f1(self): pass
+... def f2(self): pass
+...
+>>> type(C)
+<class 'noconflict.DecoratedTraced'>
+>>> c=C()
+>>> c.f1()
+Calling 'C.f1' with arguments <C instance>(){} ...
+'C.f1' called with result: None
+>>> c.f2()
+Calling 'C.f2' with arguments <C instance>(){} ...
+'C.f2' called with result: None
+
+By default, the decorators module only decorates classes with a magic
+docstring (and they subclasses, even without magic docstrings).
+If all the classes of your module have the same magic docstring,
+it makes sense to decorate them all
+with a single command. It is enough to use ``decorators.enhance_classes()``
+with a magic docstring corresponding to a class decorator as argument,
+as in this example:
+
+ ::
+
+ #<example.py>
+
+ from example2 import identity,name
+ import inspect, decorators; decorators.enhance_classes("[Decorated]")
+
+ class C1: # automagically converted to a decorated class
+ identity=identity
+
+ class C2: # automagically converted to a DecoratedLogged class
+ "[Logged]"
+ name=name
+
+ c1=C1() # C1 instance
+ c2=C2() # C2 instance
+
+ #</example.py>
+
+Notice that class ``C2`` has already a magic docstring. This means that
+``C2`` has to be enhanced both from ``Logged`` and from ``Decorated``.
+This is done by automagically creating a ``DecoratedLogged`` class
+decorator:
+
+>>> from example import C1,C2,c1,c2
+<class C2[DecoratedLogged]> created
+
+The second line is printed because of the logging capabilities of ``C2``.
+Moreover, since ``C2`` is decorated too, the following will work:
+
+>>> assert C2.name() == 'C2'
+>>> assert c2.name() == 'C2'
+
+Idem for ``C1``:
+
+>>> assert C1.identity(1) == 1
+>>> assert c1.identity(1) == 1
+
+You may check that the magic works both for new style classes (decorating
+module ``object`` class) and old style classes (by setting the module level
+``__metaclass`` attribute and by implicitly converting the classes
+to new style classes).
+
+This magical approach is the easiest way to go if you want to trace
+inheritance hierarchies. For instance, here is how to trace cooperative
+methods in complicate (which is useful for debugging):
+
+ ::
+
+ #<tracing.py>
+
+ import customdec; customdec.enhance_classes("[Decorated]")
+
+ class B(object):
+ def __init__(self):
+ "[tracedmethod]"
+ super(B,self).__init__()
+
+ class D(object):
+ def __init__(self):
+ "[tracedmethod]"
+ super(D,self).__init__()
+
+ class E(B,D):
+ def __init__(self):
+ "[tracedmethod]"
+ super(E,self).__init__()
+
+ #</tracing.py>
+
+>>> from tracing import E
+>>> e=E()
+Calling 'E.__init__' with arguments <E instance>(){} ...
+ Calling 'B.__init__' with arguments <E instance>(){} ...
+ Calling 'D.__init__' with arguments <E instance>(){} ...
+ 'D.__init__' called with result: None
+ 'B.__init__' called with result: None
+'E.__init__' called with result: None
+
+Advanced usage
+---------------------------------------------------------------------------
+
+Whereas the average programmer is expected to use the
+``decorators.decorated`` function only, the module provides access to
+its underlining implementation, which may be useful to the advanced
+programmer.
+
+
+The module provides an utility functions to retrieve the list of
+recognized decorators: ``decorators.get(docstring)``, where ``docstring``
+is a magic docstring, i.e. a bracketed comma-separated list
+of decorator names. For instance ``decorators.get('[MethodDecorator]')``
+gives the list of all subclasses of ``MethodDecorator``, i.e. all method
+decorators, whereas ``decorators.get('[ClassDecorator]')``
+gives the list of the known class decorators. It is even possible
+to use the comma notation:
+
+>>> decorators.get("[classmethod,tracedmethod]")
+[<class 'noconflict.classmethodtracedmethod'>]
+
+For instance, it is possible to decorate functions by hand,
+without using magic docstring. Here is an example:
+
+>>> do_nothing=decorators.staticmethod(lambda:None)
+>>> print do_nothing # ``do_nothing`` is a static method
+<staticmethod:<lambda>>
+
+One can even compose decorators by hand:
+
+>>> class B: pass
+...
+>>> B.chattystatic=customdec.chattymethod2(do_nothing)
+>>> B.chattystatic()
+calling <chattymethod2staticmethod:<lambda>> from <class B[ClassDecorator]>
+
+In other words
+
+ ``decorator1(decorator2(obj))``
+
+automagically creates a composed class ``decorator1decorator2`` in the
+``noconflict`` module (or recycle it, if ``decorator1decorator2`` has
+been already created) and it is equivalent to
+
+ ``decorator1decorator2(obj)``
+
+Here is the check:
+
+>>> decorators.get("[chattymethod2staticmethod]")
+[<class 'noconflict.chattymethod2staticmethod'>]
+
+Here is another example:
+
+>>> from customdec import tracedmethod
+>>> class C(object):
+... def fact(self,n):
+... if n==0: return 1
+... else: return n*self.fact(n-1)
+... fact=tracedmethod(fact)
+>>> c=C()
+>>> c.fact(2)
+Calling '?.fact' with arguments <C instance>(2,){} ...
+ Calling '?.fact' with arguments <C instance>(1,){} ...
+ Calling '?.fact' with arguments <C instance>(0,){} ...
+ '?.fact' called with result: 1
+ '?.fact' called with result: 1
+'?.fact' called with result: 2
+2
+
+In this second syntax ``fact`` does not know where it
+is defined, unless the containing class is explicitly set:
+
+>>> C.__dict__['fact'].__klass__=C
+
+Now the code will work as with the docstring syntax.
+
+
+
+
+What happens if you try to decorate something which is already
+decorated? You get ``None``:
+
+>>> def f(x): "[tracedmethod]"
+...
+>>> tm=decorators.decorated(f) # creates a tracedmethod from f
+>>> print decorators.decorated(tm) # trying to decorate a tracedmethod
+None
+
+You can compose decorators in a trivial way:
+
+>>> cmtm=decorators.classmethod(tm)
+>>> print cmtm
+<classmethodtracedmethod:f>
+
+
+whereas you can compose classes:
+
+>>> class C: "[Decorated]"
+...
+>>> print customdec.Traced(C)
+<class C[TracedDecorated]>
+
+
+
+
+>>> class D: pass
+...
+>>> print customdec.Decorated(customdec.Traced(D))
+<class D[DecoratedTraced]>
+
+
+This is the hierarchy:
+
+>>> for C in type(cmtm).mro(): print C
+...
+<class 'noconflict.classmethodtracedmethod'>
+<class 'decorators.classmethod'>
+<class 'customdec.tracedmethod'>
+<class 'decorators.MethodDecorator'>
+<class 'decorators.Decorator'>
+<type 'object'>
+
+
+
+One can also decorate classes by hand, by using class decorators.
+``decorators.ClassDecorator`` which converts a regular (both old
+style or new style) class in a class with the ability to recognize
+magic docstrings. Actually, the ``decorators.enhance_classes()``
+trick works by decorating the ``object`` class with
+``decorators.ClassDecorator`` and by setting the custom metaclass to
+``decorators.ClassDecorator`` and it is equivalent to write
+
+ ::
+
+ import decorators
+ object=decorators.ClassDecorator(object) # decorates all new style classes
+ __metaclass__= decorators.ClassDecorator # decorates all old style classes
+
+on top of your module.
+If you want the magic to work only for new style classes only, you may
+forget the
+second line; if you want the magic to work for old style classes only, you
+may forget the first line.
+
+If the module contains a magic docstring which is an explicit class decorator,
+such as ``decorators.Decorated``, then ``decorators.decorated`` look at the
+magic docstring and executes something like
+
+ ::
+
+ import decorators
+ object=decorators.Decorated(object) # decorates all new style classes
+ __metaclass__= decorators.Decorated # decorates all old style classes
+
+It is possible to go even deeper in black magic, and to decorate all
+the new style classes in *all* modules, by decorating ``__builtin__.object``:
+
+ ::
+
+ import decorators,__builtin__
+ __builtin.object=decorators.decorated(object)
+
+Still, redefining ``__builtin__object`` is not recommended since it
+may induce metaclass conflicts in other modules using metaclasses.
+It will work only if you import modules not using metaclasses, or
+modules using metaclasses safely, i.e. modules taking care of
+possible conflicts by using the ``makecls`` function or an equivalent one.
+
+The implementation
+-----------------------------------------------------------------------
+
+This part can be safely skipped, unless you are a *really* curious and
+you want to know how the implementation works.
+
+The module is rather short (~150 lines) but far from being trivial,
+since it is based on extensive usage of metaclass wizardry.
+
+The main class-metaclass hierarchy is represented in figure 1, where
+boxes denote classes and ovals denote metaclasses; instantiation is
+denoted by dashed green lines whereas inheritance is denoted by continuous
+blue lines.
+
+.. figure:: decorators.png
+
+Notice that ``MetaDecorator`` (inherited via ``Decorator``) is the
+metaclass of all decorators. Class decorators are already metaclasses,
+so ``MetaDecorator`` is actually a meta-metaclass with respect to
+instances of decorated classes, whereas it is a simple metaclass with
+respect to instances of decorated methods. For this reason in the
+presenced of class decorators the unusual relation
+
+assert object.__metaclass__ != object.__class__
+
+holds. More specifically
+
+>>> object.__class__
+<class 'decorators.ClassDecorator'>
+
+but
+
+>>> object.__metaclass__
+<class 'decorators.MetaDecorator'>
+
+since ``object`` the ``__metaclass__``
+attribute is inherited from ``Decorator``.
+
+The implementation is relatively smart. Consider for instance the case of
+the logged example. In that example class ``D`` was a subclass of a tricked
+``object`` class, enhanced by a metaclass ``ClassDecorator``. Moreover ``D``
+had a ``Logged`` docstring. Therefore it should have been an instance of
+``_ClassDecoratorLogged`` metaclass. But logged was
+a subclass of ``ClassDecorator``, therefore it already had all the features
+of ``ClassDecorator`` and it would have been redundant to create
+``_ClassDecoratorLogged``, when``Logged`` would have been enough.
+So ``Logged``
+was used and ``_ClassDecoratorLogged`` was never created. All the magic is in
+the ``noconflict`` module discussed in my cookbook_ recipe.
+
+The current implementation does not make any attempt of optimization and
+there may be alternative implementations faster or more memory efficient.
+At this experimental level I didn't care to explore about performances
+issues. They does not probably matter unless one has to decorate
+thousands or millions of functions and classes.
+
+Things to do: adding more error checking.
+
+Finally, a word about bugs. The ``decorators`` module is fairly sophisticated,
+therefore whereas I can guarantee that it passes my test suite (which involves
+~100 tests automatically extracted from the documentation you are reading),
+I cannot guarantee that it is correct.
+If somebody finds a bug or an unexpected
+behavior, please let me know and I will try to fix it.
+
+.. References:
+
+.. _cooperative methods:
+ http://www.python.org/2.3/descrintro.html
+.. _new style classes and old style classes:
+ http://www.python.org/2.3/descrintro.html
+.. _descriptors: http://users.rcn.com/python/download/Descriptor.htm
+.. _cookbook: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197
+.. _metaclasses: http://www-106.ibm.com/developerworks/library/l-pymeta2.html
diff --git a/pypers/pep318/working/doct.py b/pypers/pep318/working/doct.py
new file mode 100755
index 0000000..7e32291
--- /dev/null
+++ b/pypers/pep318/working/doct.py
@@ -0,0 +1,60 @@
+# doct.py
+
+"""Search text files for examples to run via doctest. Example of usage:
+
+$ doct doc1.txt -v doc2.txt doc3.txt
+
+This runs the tests in doc1.txt and doc3.txt in silent mode and the
+tests in doc2.txt in verbose mode."""
+
+import os,sys,doctest,time,textwrap,re
+
+sys.path[0]=os.getcwd() # explicitly puts the current directory in the path
+
+DOTNAME=r'\b[a-zA-Z_][\w\.]*', # identifier with or without dots
+SCRIPT=re.compile(r'(?s)#<(%s)>(.*?)#</\1>' % DOTNAME)
+# regular expressions to identify code blocks of the form
+#<scriptname.py>
+#...
+#</scriptname.py>
+
+TESTER=doctest.Tester(globs={},verbose=0),doctest.Tester(globs={},verbose=1)
+# regular and verbose tester instances
+
+def extractscript(txt):
+ for MO in SCRIPT.finditer(txt):
+ yield MO.group(1),textwrap.dedent(MO.group(2))
+
+def rundoct(fname,tester):
+ txt=file(fname,'U').read()
+ scriptnames=[]; scriptdict={}
+ for scriptname,script in extractscript(txt): # read scripts
+ if scriptname not in scriptnames:
+ scriptdict[scriptname]=script
+ scriptnames.append(scriptname)
+ else:
+ scriptdict[scriptname]+=script
+ for scriptname in scriptnames: # save scripts
+ code='# '+scriptname+scriptdict[scriptname]
+ print >> file(scriptname,'w'),code
+ t0=time.clock()
+ failed,total = tester.runstring(txt,fname)
+ if failed:
+ return ''
+ else:
+ return "%s: %s tests passed in %s seconds\n" % (
+ fname,total,time.clock()-t0)
+
+def main(args=sys.argv[1:]):
+ args=iter(args)
+ for a in args:
+ if a=='-v': # verbose option
+ v=1; a=args.next()
+ else: # default, non-verbose
+ v=0
+ print rundoct(fname=a,tester=TESTER[v]),
+
+if __name__=='__main__':
+ if sys.argv[1:]: main() # parse arguments
+ else: print __doc__ # no arguments given
+
diff --git a/pypers/pep318/working/example.py b/pypers/pep318/working/example.py
new file mode 100755
index 0000000..aedb6f3
--- /dev/null
+++ b/pypers/pep318/working/example.py
@@ -0,0 +1,16 @@
+# example.py
+
+from example2 import identity,name
+import inspect, decorators; decorators.enhance_classes("[Decorated]")
+
+class C1: # automagically converted to a decorated class
+ identity=identity
+
+class C2: # automagically converted to a DecoratedLogged class
+ "[Logged]"
+ name=name
+
+c1=C1() # C1 instance
+c2=C2() # C2 instance
+
+
diff --git a/pypers/pep318/working/example1.py b/pypers/pep318/working/example1.py
new file mode 100755
index 0000000..d9226d7
--- /dev/null
+++ b/pypers/pep318/working/example1.py
@@ -0,0 +1,29 @@
+# example1.py
+
+import decorators
+
+def do_nothing(self):
+ "No magic docstring here"
+dec_do_nothing=decorators.decorated(do_nothing)
+
+def identity(x):
+ "[staticmethod]"
+ return x
+dec_identity=decorators.decorated(identity)
+
+def name(cls):
+ "[classmethod]"
+ return cls.__name__
+dec_name=decorators.decorated(name)
+
+class OldStyle:
+ do_nothing=dec_do_nothing
+ identity=dec_identity
+
+class NewStyle(object):
+ name=dec_name
+
+o=OldStyle() # creates an old style instance
+n=NewStyle() # creates a new style instance
+
+
diff --git a/pypers/pep318/working/example2.py b/pypers/pep318/working/example2.py
new file mode 100755
index 0000000..6657edd
--- /dev/null
+++ b/pypers/pep318/working/example2.py
@@ -0,0 +1,36 @@
+# example2.py
+
+from decorators import decorated
+from example1 import do_nothing,identity,name
+
+class B(object):
+ "This is a regular class"
+
+B=decorated(B) # does nothing
+
+class C(B):
+ "[Decorated]"
+ do_nothing=do_nothing
+ identity=identity
+ name=name
+
+C=decorated(C) # regenerates the class converting methods in decorators
+c=C()
+
+
+
+class D: # old style
+ "[Decorated]"
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+D=decorated(D)
+
+d=D()
+
+# test
+assert d.identity(1) == 1
+assert D.identity(1) == 1
+
+
diff --git a/pypers/pep318/working/example4.py b/pypers/pep318/working/example4.py
new file mode 100755
index 0000000..25338d1
--- /dev/null
+++ b/pypers/pep318/working/example4.py
@@ -0,0 +1,22 @@
+# example4.py
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ "[Decorated]" # magic docstring here
+ def do_nothing(self):
+ "No magic docstring here"
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+class D(object):
+ "Undecorated" # no magic docstring here
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+c=C(); d=D()
+
+
diff --git a/pypers/pep318/working/example5.py b/pypers/pep318/working/example5.py
new file mode 100755
index 0000000..81ebce9
--- /dev/null
+++ b/pypers/pep318/working/example5.py
@@ -0,0 +1,20 @@
+# example5.py
+
+import decorators; decorators.enhance_classes()
+
+class C:
+ "[Decorated]" # required docstring
+ def identity(x):
+ "[staticmethod]"
+ return x
+ class Inner:
+ "[Decorated]" # required docstring
+ def name(cls):
+ "[classmethod]"
+ return cls.__name__
+
+
+assert C.identity(1) == 1
+assert C.Inner.name() == 'Inner'
+
+
diff --git a/pypers/pep318/working/example6.py b/pypers/pep318/working/example6.py
new file mode 100755
index 0000000..145c06a
--- /dev/null
+++ b/pypers/pep318/working/example6.py
@@ -0,0 +1,14 @@
+# example6.py
+
+"How to trace a class method"
+
+import customdec; customdec.enhance_classes()
+
+class C(object):
+ "[Decorated]"
+ def fact(cls,n): # a traced classmethod
+ "[classmethod,tracedmethod]"
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+
diff --git a/pypers/pep318/working/example9.py b/pypers/pep318/working/example9.py
new file mode 100755
index 0000000..8a6fd33
--- /dev/null
+++ b/pypers/pep318/working/example9.py
@@ -0,0 +1,19 @@
+# example9.py
+
+import customdec; customdec.enhance_classes()
+
+logfile=file('file3.log','w')
+
+class C(object):
+ "[Decorated]"
+ def fact(self,n):
+ "[tracedmethod] The good old factorial."
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact.output=logfile
+
+C().fact(2) # write a message to logfile
+
+logfile.close()
+
+
diff --git a/pypers/pep318/working/logged.py b/pypers/pep318/working/logged.py
new file mode 100755
index 0000000..04be3fd
--- /dev/null
+++ b/pypers/pep318/working/logged.py
@@ -0,0 +1,8 @@
+# logged.py
+
+import customdec; customdec.enhance_classes()
+
+class D(object): # will print a message at D creation
+ "[Logged]"
+
+
diff --git a/pypers/pep318/working/noconflict.py b/pypers/pep318/working/noconflict.py
new file mode 100755
index 0000000..e14a1a7
--- /dev/null
+++ b/pypers/pep318/working/noconflict.py
@@ -0,0 +1,64 @@
+"""
+Avoids metaclass conflicts by providing an additional built-in, makecls,
+to be used as __metaclass__=makecls(*metaclasses). Returns a class factory.
+"""
+
+metadic={}
+
+anyTrue=sum
+
+def remove_redundant(bases):
+ ls=list(bases); nonredundant={}
+ for c in bases:
+ if anyTrue([issubclass(C,c) and c is not C for C in ls],
+ c in nonredundant):
+ ls.remove(c) # if c is less specific or duplicated
+ else:
+ nonredundant[c]=True
+ return tuple(ls)
+
+def _generatemetaclass(bases,metas,priority):
+ metabs=tuple(map(type,bases))
+ metabases=remove_redundant((metabs+metas, metas+metabs)[priority])
+ if metabases in metadic: # already generated metaclass
+ return metadic[metabases]
+ elif not metabases: # trivial metabase
+ meta=type
+ elif len(metabases)==1: # single metabase
+ meta=metabases[0]
+ else: # multiple metabases
+ metaname=''.join([m.__name__ for m in metabases])
+ meta=makecls()(metaname,metabases,{})
+ return metadic.setdefault(metabases,meta)
+
+def makecls(*metas,**options):
+ """Class factory avoiding metatype conflicts. The invocation syntax is
+ makecls(M1,M2,..,priority=1)(name,bases,dic). If the base classes have
+ metaclasses conflicting within themselves or with the given metaclasses,
+ it automatically generates a compatible metaclass and instantiate it.
+ If priority is True, the given metaclasses have priority over the
+ bases metaclasses."""
+
+ priority=options.get('priority',False) # default, no priority
+ def clsfactory(n,b,d):
+ # workaround to allow redefinition of meta-meta.__call__
+ meta=_generatemetaclass(b,metas,priority)
+ return type.__call__(meta,n,b,d) # calls __new__ and __init__
+ return clsfactory
+
+#class Noconflict(type):
+# """Meta-metaclass tweaking the metaclass calling in such a way to
+# avoid conflicts"""
+# def __call__(mcl,n,b,d):
+# return makecls(mcl)(n,b,d)
+
+if __name__=='__main__': # test
+ import __builtin__
+ __builtin__.type=Noconflict('Type',(type,),{})
+ class M1(type): pass
+ class M2(type): pass
+ class C1: __metaclass__=M1
+ class C2: __metaclass__=M2
+ class C(C1,C2): pass
+ #__metaclass__=makecls()
+# assert type(C),__name__=='_M1M2'
diff --git a/pypers/pep318/working/pep318.html b/pypers/pep318/working/pep318.html
new file mode 100755
index 0000000..a3ce15b
--- /dev/null
+++ b/pypers/pep318/working/pep318.html
@@ -0,0 +1,1046 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="generator" content="Docutils 0.2.9: http://docutils.sourceforge.net/" />
+<title>Implementing PEP 318 (decorators)</title>
+<link rel="stylesheet" href="default.css" type="text/css" />
+</head>
+<body>
+<div class="document" id="implementing-pep-318-decorators">
+<h1 class="title">Implementing PEP 318 (decorators)</h1>
+<div class="contents topic" id="contents">
+<p class="topic-title"><a name="contents">Contents</a></p>
+<ul class="simple">
+<li><a class="reference" href="#basics" id="id1" name="id1">Basics</a></li>
+<li><a class="reference" href="#simple-usage-of-decorators" id="id2" name="id2">Simple usage of decorators</a></li>
+<li><a class="reference" href="#adding-a-bit-of-magic" id="id3" name="id3">Adding a bit of magic</a></li>
+<li><a class="reference" href="#adding-more-magic" id="id4" name="id4">Adding more magic</a></li>
+<li><a class="reference" href="#defining-method-decorators" id="id5" name="id5">Defining method decorators</a></li>
+<li><a class="reference" href="#tracing-methods" id="id6" name="id6">Tracing methods</a></li>
+<li><a class="reference" href="#composition-of-decorators" id="id7" name="id7">Composition of decorators</a></li>
+<li><a class="reference" href="#class-decorators" id="id8" name="id8">Class decorators</a></li>
+<li><a class="reference" href="#module-decorators" id="id9" name="id9">Module decorators</a></li>
+<li><a class="reference" href="#introspection-features" id="id10" name="id10">Introspection features</a></li>
+<li><a class="reference" href="#the-implementation" id="id11" name="id11">The implementation</a></li>
+</ul>
+</div>
+<p>Having plenty of free time in these days, I have finished an old
+project of mine, the implementation of PEP 318 in pure Python.</p>
+<p>Here is the rationale:</p>
+<ul class="simple">
+<li>some kind of decorator syntax is scheduled to go in Python 2.4,
+therefore it is interesting to play with the concept;</li>
+<li>it is nice to play with decorators now, without having to
+wait for one year or so;</li>
+<li>it is much easier to experiment with the pure Python implementation;</li>
+<li>the implementation can be seen as an exercise on modern Python
+programming and may be valuable to people wanting to study the most
+advanced new constructs in Python 2.2 (descriptors, metaclasses,
+cooperative methods, etc.)</li>
+</ul>
+<div class="section" id="basics">
+<h1><a class="toc-backref" href="#id1" name="basics">Basics</a></h1>
+<p>As people in this list most probably know, PEP 318 has the goal
+of providing a nice syntactic sugar for expressions like</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x):
+ return x
+identity=staticmethod(identity)
+</pre>
+</blockquote>
+<p>or</p>
+<blockquote>
+<pre class="literal-block">
+def nameof(cls):
+ return cls.__name__
+nameof=classmethod(nameof)
+</pre>
+</blockquote>
+<p>which are pretty verbose. It is clear that having new syntax (as
+for instance the proposed square bracket notation)</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x)[staticmethod]:
+ return x
+
+def nameof(cls)[classmethod]:
+ return cls.__name__
+</pre>
+</blockquote>
+<p>involves changing the grammar and modifying the interpreter at the
+C level. However, it is possible to have the same effect without
+changing the Python grammar. The idea is to use magic docstrings
+like this:</p>
+<blockquote>
+<pre class="literal-block">
+def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+def nameof(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+</pre>
+</blockquote>
+<p>The implementation is able to recognize such docstrings
+and to automagically convert the functions in (method) decorators.</p>
+<p>Method decorators are nothing else than a sophisticated kind of wrappers.
+<tt class="literal"><span class="pre">staticmethod</span></tt> and <tt class="literal"><span class="pre">classmethod</span></tt> are two examples of already existing
+decorators (actually my implementation rewrites them, but let me pass on
+this detail). Technically speaking, method decorators are classes
+taking a single function as input and producing a descriptor object
+as output (properties are not decorators according to this definition,
+since they take four functions as input, <tt class="literal"><span class="pre">get,</span> <span class="pre">set,</span> <span class="pre">del_</span></tt> and <tt class="literal"><span class="pre">doc</span></tt>).
+<a class="reference" href="http://users.rcn.com/python/download/Descriptor.htm">Descriptors</a> are objects with a <tt class="literal"><span class="pre">__get__</span></tt> method; they are quite
+sophisticated, but fortunately they have been wonderfully explained by
+Raymond Hettinger already, so I am allowed to skip this point ;). A knowledge
+of descriptors is not needed in order to use the <tt class="literal"><span class="pre">decorator</span></tt> module;
+however it is welcomed for advanced users wanting to implement
+custom decorators.</p>
+</div>
+<div class="section" id="simple-usage-of-decorators">
+<h1><a class="toc-backref" href="#id2" name="simple-usage-of-decorators">Simple usage of decorators</a></h1>
+<p>Before talking about the implementation details, I will show
+how the <tt class="literal"><span class="pre">decorators</span></tt> module works in practice. The simplest and
+safest usage is by means of the functions <tt class="literal"><span class="pre">decorators.decorate</span></tt>
+and <tt class="literal"><span class="pre">decorators.decorated</span></tt>:</p>
+<ol class="arabic simple">
+<li><tt class="literal"><span class="pre">decorators.decorated(obj)</span></tt> takes an object and checks its docstring;
+if a magic docstring is found, it returns a decorated version of the
+object, otherwise it returns <tt class="literal"><span class="pre">None</span></tt>;</li>
+<li><tt class="literal"><span class="pre">decorators.decorate(obj)</span></tt> takes a dictionary or an object with a
+<tt class="literal"><span class="pre">.__dict__</span></tt> attribute and returns <tt class="literal"><span class="pre">None</span></tt>. It works by
+invoking <tt class="literal"><span class="pre">decorators.decorated</span></tt> on the elements of the dictionary
+and by modifying them if needed.</li>
+</ol>
+<p>Here is an example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example1.py&gt;
+
+&quot;How to use ``decorators.decorate`` and ``decorators.decorated``&quot;
+
+import decorators
+
+def do_nothing(self):
+ &quot;No magic docstring here&quot;
+
+def identity(x):
+ &quot;[staticmethod]&quot; # magic docstring here
+ return x
+
+def nameof(cls):
+ &quot;[classmethod]&quot; # magic docstring here too
+ return cls.__name__
+
+dic={'nameof': nameof, 'do_nothing': do_nothing}
+decorators.decorate(dic) # converts nameof -&gt; classmethod
+
+C=type('C',(),dic) # creates the class with the modified dictionary
+C.identity=decorators.decorated(identity) # converts identity -&gt; staticmethod
+c=C() # creates the instance
+
+#&lt;/example1.py&gt;
+</pre>
+</blockquote>
+<p>and here is the testing:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example1 import C,c
+&gt;&gt;&gt; assert c.do_nothing() is None
+&gt;&gt;&gt; assert C.identity(1) == 1
+&gt;&gt;&gt; assert C.nameof() == 'C'
+&gt;&gt;&gt; assert c.identity(1) == 1
+&gt;&gt;&gt; assert c.nameof() == 'C'
+</pre>
+<p>One can even pass the <tt class="literal"><span class="pre">globals()</span></tt> dictionary since objects without
+a magic docstring are simply ignored. Therefore the previous example
+can be rewritten as</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example2.py&gt;
+
+import decorators
+
+def do_nothing(self):
+ &quot;No magic docstring here&quot;
+
+def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+def nameof(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+
+decorators.decorate(globals()) # decorates the functions
+
+class C(object):
+ identity=identity
+ nameof=nameof
+ do_nothing=do_nothing
+
+c=C()
+
+#&lt;/example2.py&gt;
+</pre>
+</blockquote>
+<p>Here is the testing:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example2 import c,C
+&gt;&gt;&gt; assert c.do_nothing() is None
+&gt;&gt;&gt; assert C.identity(1) == 1
+&gt;&gt;&gt; assert C.nameof() == 'C'
+&gt;&gt;&gt; assert c.identity(1) == 1
+&gt;&gt;&gt; assert c.nameof() == 'C'
+</pre>
+<p>Notice that the call to <tt class="literal"><span class="pre">decorators.decorate(globals())</span></tt> must be done
+<em>after</em> the function definitions, otherwise the functions would
+not converted, since they were not in the global dictionary at the
+time of the call. Moreover, one should not try to pass the <tt class="literal"><span class="pre">locals()</span></tt>
+dictionary, since it will not work when <tt class="literal"><span class="pre">locals()</span> <span class="pre">!=</span> <span class="pre">globals()</span></tt>.</p>
+<p>Alternatively, one can just decorate the class:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example3.py&gt;
+
+import decorators
+
+def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+def nameof(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+
+class C:
+ identity=identity
+ nameof=nameof
+
+decorators.decorate(C)
+
+c=C()
+
+# testing
+assert C.identity(1) == 1
+assert C.nameof() == 'C'
+assert c.identity(1) == 1
+assert c.nameof() == 'C'
+
+#&lt;/example3.py&gt;
+</pre>
+</blockquote>
+<p>This example also shows that decorators work both for <a class="reference" href="http://www.python.org/2.3/descrintro.html">new style classes
+and old style classes</a>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example3 import *
+&gt;&gt;&gt; type(C) # C is an old style class
+&lt;type 'classobj'&gt;
+</pre>
+<p>At this point the difference between <tt class="literal"><span class="pre">decorators.decorate</span></tt> and
+<tt class="literal"><span class="pre">decorators.decorated</span></tt> should be pointed out. The first syntax
+modifies the class dictionary, whereas the second creates a new
+class with the same name of the first one:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D:
+... identity=identity
+&gt;&gt;&gt; decorators.decorated(D)
+&lt;class 'D'&gt;
+&gt;&gt;&gt; D.identity(1) # this is the old D
+Traceback (most recent call last):
+ ...
+TypeError: unbound method identity() must be called with D instance as first argument (got int instance instead)
+</pre>
+<p>Therefore one has to redefine to old class in order the statement to
+have effect:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; D=decorators.decorated(D)
+&gt;&gt;&gt; D.identity(1) # this is the new D
+1
+</pre>
+</div>
+<div class="section" id="adding-a-bit-of-magic">
+<h1><a class="toc-backref" href="#id3" name="adding-a-bit-of-magic">Adding a bit of magic</a></h1>
+<p>It would be nice to have classes with the ability of automatically
+converting their methods to method decorators according to the docstrings.
+This sounds a bit of magic, but actually can be done very simply by adding
+to the class a docstring starting with &quot;[Decorated]&quot;.
+Here is an example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example.py&gt;
+
+import decorators
+
+class C: # works for old style classes too
+ &quot;[Decorated]&quot;
+ def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+
+decorators.decorate(globals())
+
+c=C()
+
+# test
+assert C.identity(1) == 1
+assert c.identity(1) == 1
+
+#&lt;/example.py&gt;
+</pre>
+</blockquote>
+<p>Under the hood, the magic docstring &quot;[Decorated]&quot; creates an instance of the
+<tt class="literal"><span class="pre">decorators.Decorated</span></tt> metaclass and replace the original class <tt class="literal"><span class="pre">C</span></tt>
+in the global namespace with the new class <tt class="literal"><span class="pre">C</span></tt>; incidentally,
+this converts <tt class="literal"><span class="pre">C</span></tt> in a new style class:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example import C
+&gt;&gt;&gt; type(C)
+&lt;class 'decorators.Decorated'&gt;
+</pre>
+<p>On the other hand using <tt class="literal"><span class="pre">decorators.decorate(C)</span></tt> would decorate <tt class="literal"><span class="pre">C</span></tt>, but
+without re-creating it as an instance of &quot;[Decorated]&quot;. One can also
+forget the docstring in subclasses of decorated classes:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D(C):
+... def nameof(cls):
+... &quot;[classmethod]&quot;
+... return cls.__name__
+&gt;&gt;&gt; print D.nameof()
+D
+</pre>
+<p>The trick works for classes containing inner classes, too:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example4.py&gt;
+
+import decorators
+
+class C:
+ &quot;[Decorated]&quot; # required docstring
+ def identity(x):
+ &quot;[staticmethod]&quot;
+ return x
+ class Inner:
+ &quot;[Decorated]&quot; # required docstring
+ def nameof(cls):
+ &quot;[classmethod]&quot;
+ return cls.__name__
+
+decorators.decorate(globals())
+
+assert C.identity(1) == 1
+assert C.Inner.nameof() == 'Inner'
+
+#&lt;/example4.py&gt;
+</pre>
+</blockquote>
+</div>
+<div class="section" id="adding-more-magic">
+<h1><a class="toc-backref" href="#id4" name="adding-more-magic">Adding more magic</a></h1>
+<p>There is a neat trick to simplify the usage of decorators: decorating the
+<tt class="literal"><span class="pre">object</span></tt> class. Then all methods in all new style classes of your module
+will be checked for magic docstrings and automagically decorated if needed.
+This can be done by simply writing</p>
+<blockquote>
+<pre class="literal-block">
+import decorators
+object=decorators.decorated(object)
+</pre>
+</blockquote>
+<p>on top of your module. Here is an example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example.py&gt;
+
+import inspect, decorators
+object=decorators.decorated(object)
+
+def identity(x):
+ &quot;[staticmethod] defined outside a class&quot;
+ return x
+
+assert inspect.isfunction(identity) # not yet a decorator
+
+class C1(object):
+ def nameof(cls):
+ &quot;[classmethod] defined inside a class&quot;
+ return cls.__name__
+ identity=identity # automagically converted to a decorator
+
+c1=C1() # C1 instance
+
+# testing
+
+assert C1.identity(1) == 1
+assert C1.nameof() == 'C1'
+assert c1.identity(1) == 1
+assert c1.nameof() == 'C1'
+
+#&lt;/example.py&gt;
+</pre>
+</blockquote>
+<p>Notice that adding <tt class="literal"><span class="pre">identity</span></tt> after the class creation with the syntax
+<tt class="literal"><span class="pre">C.identity=identity</span></tt> would not work. Moreover, the magic only works
+for new style classes, since the implementation operates
+by enhancing the <tt class="literal"><span class="pre">object</span></tt> class in the calling module.
+The enhancement includes providing a new default printing representation
+for instances:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example import c1
+&gt;&gt;&gt; print c1
+&lt;instance of C1&gt;
+</pre>
+<p>The <tt class="literal"><span class="pre">decorated(object)</span></tt> trick (and the &quot;[Decorated]&quot; syntax too)
+is not 100% safe, because of possible metaclass conflicts:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; import decorators; object=decorators.decorated(object)
+&gt;&gt;&gt; class M(type): pass
+...
+&gt;&gt;&gt; class D(object):
+... __metaclass__=M
+Traceback (most recent call last):
+ ...
+TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+</pre>
+<p>The decorators module imports the <tt class="literal"><span class="pre">makecls</span></tt> function from my
+<tt class="literal"><span class="pre">noconflict</span></tt> module just to avoid this kind of problems:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class D(object):
+... __metaclass__=decorators.makecls(M)
+&gt;&gt;&gt; type(D)
+&lt;class 'noconflict._DecoratedM'&gt;
+</pre>
+<p>It is possible to go even deeper in black magic, and to decorate all
+the new style classes in <em>all</em> modules, by decorating <tt class="literal"><span class="pre">__builtin__.object</span></tt>:</p>
+<blockquote>
+<pre class="literal-block">
+import decorators,__builtin__
+__builtin.object=decorators.decorated(object)
+</pre>
+</blockquote>
+<p>Still, redefining <tt class="literal"><span class="pre">__builtin__object</span></tt> is not recommended since it
+may induce metaclass conflicts in other modules using metaclasses.
+It will work only if you import modules not using metaclasses, or
+modules using metaclasses safely, i.e. modules taking care of
+possible conflicts by using the <tt class="literal"><span class="pre">makecls</span></tt> function or an equivalent one.</p>
+</div>
+<div class="section" id="defining-method-decorators">
+<h1><a class="toc-backref" href="#id5" name="defining-method-decorators">Defining method decorators</a></h1>
+<p>The decorators module contains two predefinite method decorators,
+<tt class="literal"><span class="pre">staticmethod</span></tt> and <tt class="literal"><span class="pre">classmethod</span></tt>, which emulate the built-ins
+with the same names. However, it is possible to write your own
+custom decorators. The <tt class="literal"><span class="pre">decorators</span></tt> module provides a
+<tt class="literal"><span class="pre">MethodDecorator</span></tt> class which is here exactly for that purpose.</p>
+<p>Custom decorators are expected to be implemented by subclassing
+<tt class="literal"><span class="pre">MethodDecorator</span></tt> and by overriding its <tt class="literal"><span class="pre">get</span></tt> method, which
+automagically induces a <tt class="literal"><span class="pre">__get__</span></tt> method, turning the class
+in a descriptor. This
+machinery is needed since <tt class="literal"><span class="pre">__get__</span></tt> cannot be made cooperative
+using the standard <tt class="literal"><span class="pre">super</span></tt> mechanism (there would be a confusion
+between <tt class="literal"><span class="pre">super.__get__</span></tt> and the decorator <tt class="literal"><span class="pre">__get__</span></tt>). This is a bit
+tricky, but the causal programmer is not expected to write custom
+decorators, and actually I don't want to make the access to decorators
+<em>too</em> easy</p>
+<p>For instance, let me show the implementation of a <tt class="literal"><span class="pre">chattymethod</span></tt>
+that prints a message when it is called:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;chatty.py&gt;
+
+from decorators import *
+object=decorated(object)
+
+class chattymethod(MethodDecorator):
+ logfile=file('file1.log','w')
+ def get(self,obj,cls=None): # same signature as __get__
+ print &gt;&gt; self.logfile,'calling %s from %s' % (self,obj or cls)
+ return super(chattymethod,self).get(obj,cls)
+
+#&lt;/chatty.py&gt;
+</pre>
+</blockquote>
+<p>Notice the usage of the <tt class="literal"><span class="pre">super().get</span></tt> trick. This guarantees that
+<tt class="literal"><span class="pre">chattymethod</span></tt> will play well with other decorators (i.e. it
+can be nicely composed via multiple inheritance)</p>
+<p>Here is an example of usage</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;chatty.py&gt;
+
+class C(object):
+ def f():
+ &quot;[chattymethod,staticmethod]&quot;
+
+c=C()
+
+c.f()
+C.f()
+
+#&lt;/chatty.py&gt;
+</pre>
+</blockquote>
+<p>The content of the logfile is then</p>
+<blockquote>
+<pre class="literal-block">
+calling &lt;chattymethodstaticmethod:f&gt; from &lt;instance of C&gt;
+calling &lt;chattymethodstaticmethod:f&gt; from &lt;class C[Decorated]&gt;
+</pre>
+</blockquote>
+<p>From this output we see how the &quot;[chattymethod,staticmethod]&quot;
+magic docstring is responsible for the creation of a new decorator class
+<tt class="literal"><span class="pre">chattymethodstaticmethod</span></tt>, obtained via multiple inheritance from
+<tt class="literal"><span class="pre">chattymethod</span></tt> and <tt class="literal"><span class="pre">staticmethod</span></tt> respectively.</p>
+<p>One can easily change the logfile, if need there is</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;chatty.py&gt;
+
+chattymethod.logfile=file('file2.log','w')
+
+def g():
+ &quot;[chattymethod,staticmethod]&quot;
+
+C.g=decorated(g)
+C.g # message written in file2.log
+C.f # message written in file2.log
+
+#&lt;/chatty.py&gt;
+</pre>
+</blockquote>
+<p>Now <tt class="literal"><span class="pre">file2.log</span></tt> will contains the messages</p>
+<blockquote>
+<pre class="literal-block">
+calling &lt;chattymethodstaticmethod:g&gt; from &lt;class C[Decorated]&gt;
+calling &lt;chattymethodstaticmethod:f&gt; from &lt;class C[Decorated]&gt;
+</pre>
+</blockquote>
+<p>This approach has the drawback that chattymethods created before changing
+the logfile will also print to the new logfile, if invoked after the
+change. This can be avoided by converting <tt class="literal"><span class="pre">logfile</span></tt> from a class variable
+to an instance variable in the <tt class="literal"><span class="pre">__init__</span></tt> method:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;chatty2.py&gt;
+
+import sys
+from chatty import *
+
+class chattymethod2(chattymethod):
+ def __init__(self,func):
+ super(chattymethod2,self).__init__(func)
+ self.logfile=self.logfile # class variable becomes instance variable
+
+class C(object):
+ chattymethod2.logfile=sys.stdout
+ f=chattymethod2(lambda self:None)
+ chattymethod2.logfile=file('file3.log','w')
+ g=chattymethod2(lambda self:None)
+
+c=C()
+
+#&lt;/chatty2.py&gt;
+</pre>
+</blockquote>
+<p>Notice that the <tt class="literal"><span class="pre">__init__</span></tt> method should have the signature
+<tt class="literal"><span class="pre">__init__(self,func)</span></tt>, where <tt class="literal"><span class="pre">func</span></tt> is the function to be
+converted in the decorator object. Here is the testing:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from chatty2 import c
+&gt;&gt;&gt; c.f()
+calling &lt;chattymethod2:&lt;lambda&gt;&gt; from &lt;instance of C&gt;
+&gt;&gt;&gt; c.g() # message written in file3.log
+&gt;&gt;&gt; c.f() # message written in stdout, not in file3.log!
+calling &lt;chattymethod2:&lt;lambda&gt;&gt; from &lt;instance of C&gt;
+</pre>
+</div>
+<div class="section" id="tracing-methods">
+<h1><a class="toc-backref" href="#id6" name="tracing-methods">Tracing methods</a></h1>
+<p>In order to show a non-trivial example, I will show how
+decorators can be used to implement traced methods.
+Here is the code (notice: the lazy reader can safely skip the
+implementation details and go directly to the usage section ;)</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;tracedmethod.py&gt;
+
+import sys,decorators
+
+class tracedmethod(decorators.MethodDecorator):
+ &quot;Descriptor class, converts a method in a traced method&quot;
+ indent=0; output=sys.stdout # defaults
+ def __init__(self,func):
+ super(tracedmethod,self).__init__(func)
+ self.funcname=self.func.__name__
+ def get(self,obj,cls):
+ if obj is None: name=self.inside.__name__ # called from class
+ else: name='&lt;%s&gt;' % self.inside.__name__ # from instance
+ methodwrapper=super(tracedmethod,self).get(obj,cls)
+ def _(*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write(&quot;%sCalling '%s.%s' with arguments &quot; %
+ (i,name,self.funcname))
+ self.output.write(&quot;%s ...\n&quot; % (str(args)+str(kw)))
+ res=methodwrapper(*args,**kw)
+ self.output.write(&quot;%s'%s.%s' called with result: %s\n&quot;
+ % (i,name,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return _
+
+#&lt;/tracedmethod.py&gt;
+</pre>
+</blockquote>
+<p>As soon as the <tt class="literal"><span class="pre">tracedmethod</span></tt> module is loaded, the <tt class="literal"><span class="pre">tracedmethod</span></tt> class
+is added to the list of know decorators, so one should use the &quot;[tracedmethod]&quot;
+docstring instead and not &quot;[tracedmethod.tracedmethod]&quot;.</p>
+<p><tt class="literal"><span class="pre">tracedmethod</span></tt> which is quite useful during
+debugging. Here is an example of usage, in tracing the internal working
+of a recursive function:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example4.py&gt;
+
+import decorators,tracedmethod
+
+class C(object):
+ def fact(self,n):
+ &quot;[tracedmethod]&quot;
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+
+decorators.decorate(C)
+
+c=C()
+
+#&lt;/example4.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example4 import c
+&gt;&gt;&gt; c.fact(2)
+Calling '&lt;C&gt;.fact' with arguments (2,){} ...
+ Calling '&lt;C&gt;.fact' with arguments (1,){} ...
+ Calling '&lt;C&gt;.fact' with arguments (0,){} ...
+ '&lt;C&gt;.fact' called with result: 1
+ '&lt;C&gt;.fact' called with result: 1
+'&lt;C&gt;.fact' called with result: 2
+2
+</pre>
+<p>An alternative spelling, not involving magic docstrings, nor the
+decorators module, is the following:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example5.py&gt;
+
+from tracedmethod import tracedmethod
+
+class C(object):
+ def fact(self,n):
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact=tracedmethod(fact)
+
+c=C()
+
+#&lt;/example5.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example5 import c
+&gt;&gt;&gt; c.fact(2)
+Calling '&lt;?&gt;.fact' with arguments (2,){} ...
+ Calling '&lt;?&gt;.fact' with arguments (1,){} ...
+ Calling '&lt;?&gt;.fact' with arguments (0,){} ...
+ '&lt;?&gt;.fact' called with result: 1
+ '&lt;?&gt;.fact' called with result: 1
+'&lt;?&gt;.fact' called with result: 2
+2
+</pre>
+<p>Notice that in this second syntax <tt class="literal"><span class="pre">fact</span></tt> does not know where it
+is defined; however the containing class can be explicitly set:</p>
+<blockquote>
+<tt class="literal"><span class="pre">C.__dict__['fact'].inside=C</span></tt></blockquote>
+<p>The <tt class="literal"><span class="pre">inside</span></tt> attribute is automagically set if the docstring syntax
+is used.</p>
+<p>Here is how to trace cooperative methods in complicate hierarchies
+(which is useful for debugging):</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;tracing.py&gt;
+
+import decorators,tracedmethod
+object=decorators.decorated(object)
+
+class B(object):
+ def __init__(self):
+ &quot;[tracedmethod]&quot;
+ super(B,self).__init__()
+
+class D(object):
+ def __init__(self):
+ &quot;[tracedmethod]&quot;
+ super(D,self).__init__()
+
+class E(B,D):
+ def __init__(self):
+ &quot;[tracedmethod]&quot;
+ super(E,self).__init__()
+
+ #&lt;/tracing.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; from tracing import E
+&gt;&gt;&gt; e=E()
+Calling '&lt;E&gt;.__init__' with arguments (){} ...
+ Calling '&lt;B&gt;.__init__' with arguments (){} ...
+ Calling '&lt;D&gt;.__init__' with arguments (){} ...
+ '&lt;D&gt;.__init__' called with result: None
+ '&lt;B&gt;.__init__' called with result: None
+'&lt;E&gt;.__init__' called with result: None
+</pre>
+<p>In this example decorating <tt class="literal"><span class="pre">object</span></tt> is the easiest way to go.</p>
+</div>
+<div class="section" id="composition-of-decorators">
+<h1><a class="toc-backref" href="#id7" name="composition-of-decorators">Composition of decorators</a></h1>
+<p>Decorators can be composed: for instance, you can trace a
+classmethod as in this example:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;example6.py&gt;
+
+import tracedmethod
+from decorators import decorated
+object=decorated(object)
+
+class C(object):
+ def fact(cls,n):
+ &quot;[tracedmethod,classmethod]&quot;
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+#&lt;/example6.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; from example6 import C
+&gt;&gt;&gt; C.fact(2)
+Calling 'C.fact' with arguments (2,){} ...
+ Calling 'C.fact' with arguments (1,){} ...
+ Calling 'C.fact' with arguments (0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+</pre>
+<p>Under the hood the syntax</p>
+<blockquote>
+<pre class="literal-block">
+[tracedmethod,classmethod]
+</pre>
+</blockquote>
+<p>generates a <tt class="literal"><span class="pre">tracedmethodclassmethod</span></tt> class obtained via
+multiple inheritance:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; for c in type(C.__dict__['fact']).__mro__: print c
+...
+&lt;class 'noconflict.tracedmethodclassmethod'&gt;
+&lt;class 'tracedmethod.tracedmethod'&gt;
+&lt;class 'decorators.classmethod'&gt;
+&lt;class 'decorators.MethodDecorator'&gt;
+&lt;class 'decorators.Decorator'&gt;
+&lt;type 'object'&gt;
+</pre>
+<p>In this case the order does not matter and using the docstring
+&quot;[classmethod,tracedmethod]&quot; would work too, but
+in general one must pay attention to precedence issues.
+For instance the following will not work:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class C(object):
+... def fact(n):
+... &quot;[staticmethod,tracedmethod]&quot;
+... if n==0: return 1
+... else: return n*C.fact(n-1)
+&gt;&gt;&gt; C.fact(2)
+Traceback (most recent call last):
+ ...
+AttributeError: 'function' object has no attribute 'im_func'
+</pre>
+<p>The problem here is that <tt class="literal"><span class="pre">staticmethod.get</span></tt> invokes <tt class="literal"><span class="pre">tracedmethod.get</span></tt>
+which returns a function and not a method-wrapper with an <tt class="literal"><span class="pre">im_func</span></tt> method.
+On the other hand, composing the decorators in the other order
+&quot;[tracedmethod,staticmethod]&quot; will work just fine.</p>
+</div>
+<div class="section" id="class-decorators">
+<h1><a class="toc-backref" href="#id8" name="class-decorators">Class decorators</a></h1>
+<p>PEP 318 proposes to decorate methods by using descriptors; it is
+quite natural to extend this idea and to decorate classes by using
+class decorators implemented as metaclasses. We already saw a
+class decorator at work, the metaclass <tt class="literal"><span class="pre">Decorated</span></tt>, giving
+to its instances the ability to interpret magic docstrings,
+and converting functions in method decorators.</p>
+<p>To define a custom class decorator is easy: one defines a custom metaclasses
+as usual, with the only difference from deriving by <tt class="literal"><span class="pre">ClassDecorator</span></tt> instead
+of deriving from <tt class="literal"><span class="pre">type</span></tt>. To understand how this works in practice, let me
+show how to add logging capabilities to a given class. The first
+step is to define a suitable class decorator, such as the following:</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;logged.py&gt;
+
+from decorators import *
+
+class Logged(ClassDecorator):
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print &quot;%s created&quot; % cls
+
+#&lt;/logged.py&gt;
+</pre>
+</blockquote>
+<p><tt class="literal"><span class="pre">Logged</span></tt> is derived by the metaclass <tt class="literal"><span class="pre">ClassDecorator</span></tt>,
+which provides a certain amount of magic under the hood (in particular
+its printing representation and its calling syntax are redefined by its
+metaclass <tt class="literal"><span class="pre">MetaDecorator</span></tt>). Logging capabilities can be added to a class
+by simply using the magic docstring syntax:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from logged import *
+&gt;&gt;&gt; object=decorators.decorated(object)
+&gt;&gt;&gt; class D(object):
+... &quot;[Logged]&quot;
+&lt;class D[_DecoratedLogged]&gt; created
+</pre>
+<p>Notice that <tt class="literal"><span class="pre">D</span></tt> inherits the <tt class="literal"><span class="pre">Decorated</span></tt> metaclass from <tt class="literal"><span class="pre">object</span></tt>
+and the <tt class="literal"><span class="pre">Logged</span></tt> metaclass from the docstring; the conflict is
+automagically avoid by the miracolous creation of a <tt class="literal"><span class="pre">_DecoratedLogged</span></tt>
+metaclass, obtained via multiple inheritance from <tt class="literal"><span class="pre">Decorated</span></tt> and
+<tt class="literal"><span class="pre">Logged</span></tt>. All the magic is performed in the <tt class="literal"><span class="pre">noconflict</span></tt> module,
+discussed in a <a class="reference" href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197">cookbook</a> recipe of mine.</p>
+<p>Notice that the printing representation of <tt class="literal"><span class="pre">D</span></tt> involves the name
+of <tt class="literal"><span class="pre">D</span></tt> preceded by the name of its metaclass, which in this case
+is <tt class="literal"><span class="pre">_DecoratedLogged</span></tt></p>
+<p>Each time an instance of <tt class="literal"><span class="pre">Logged</span></tt> is created, a similar message is printed:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; class E(D):
+... pass
+&lt;class E[_DecoratedLogged]&gt; created
+</pre>
+<p>Notice that <tt class="literal"><span class="pre">E</span></tt> does not have any magic docstring</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; E.__doc__ # no docstring
+</pre>
+<p>but still it inherits its magic from <tt class="literal"><span class="pre">D</span></tt>.</p>
+<p>The <tt class="literal"><span class="pre">decorators</span></tt> module provides the already saw class decorator
+<tt class="literal"><span class="pre">Decorated</span></tt>, which converts methods in method decorators.</p>
+<p>Another example is</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;Traced.py&gt;
+
+import tracedmethod
+from decorators import *
+from types import FunctionType
+object=decorated(object)
+
+class Traced(ClassDecorator):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType):
+ func.__doc__=&quot;[tracedmethod] &quot; + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d)
+
+class C(object):
+ &quot;&quot;&quot;[Traced] The class decorator adds the magic docstring
+ '[tracedmethod]' to f1 and f2, which are then converted
+ to method decorator objects.&quot;&quot;&quot;
+ def f1(self): pass
+ def f2(self): pass
+
+c=C()
+
+#&lt;/Traced.py&gt;
+</pre>
+</blockquote>
+<p>Here is an example of usage:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from Traced import C; c=C()
+&gt;&gt;&gt; c.f1()
+Calling '&lt;C&gt;.f1' with arguments (){} ...
+'&lt;C&gt;.f1' called with result: None
+&gt;&gt;&gt; c.f2()
+Calling '&lt;C&gt;.f2' with arguments (){} ...
+'&lt;C&gt;.f2' called with result: None
+</pre>
+</div>
+<div class="section" id="module-decorators">
+<h1><a class="toc-backref" href="#id9" name="module-decorators">Module decorators</a></h1>
+<p>Finally, one can decorate entire modules through the concept of
+<em>module decorators</em>. Module decorators have the ability of decorating
+modules by changing their dictionary. Custom module decorators
+should be derived from the class <tt class="literal"><span class="pre">decorators.ModuleDecorator</span></tt>, by
+cooperatively overriding its <tt class="literal"><span class="pre">__init__(self,mod)</span></tt> method. Writing
+a module decorator is a bit tricky, but I do expect only
+expert programmers to play this kind of game.
+For instance, suppose one wants to trace all the functions in a module,
+unless they have the docstring &quot;-untraced-&quot; . This can be done with a
+suitable module decorator which modifies the module dictionary.
+Here is an example</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;tracefunctions.py&gt;
+
+from decorators import *
+
+class TraceFunctions(ModuleDecorator):
+ def __init__(self,mod):
+ super(TraceFunctions,self).__init__(mod)
+ for name,func in self.__dict__.items():
+ if inspect.isfunction(func):
+ doc=func.__doc__ or ''
+ if doc.startswith('-untraced-'):
+ pass # do nothing
+ else:
+ def tracedfunc(func=func): # default argument trick
+ def _(*args,**kw):
+ print 'called',func.__name__
+ return func(*args,**kw)
+ return _
+ setattr(self,name,tracedfunc())
+
+#&lt;/tracefunctions.py&gt;
+</pre>
+</blockquote>
+<p>Let me test that the module decorator does its job. Consider the module</p>
+<blockquote>
+<pre class="literal-block">
+#&lt;mod.py&gt;
+
+#&quot;[TraceFunctions]&quot;
+
+def f1(): pass
+
+def f2(): pass
+
+def f3(): &quot;-untraced-&quot;
+
+#&lt;/mod.py&gt;
+</pre>
+</blockquote>
+<p>By importing this module, only the functions <tt class="literal"><span class="pre">f1</span></tt> and <tt class="literal"><span class="pre">f2</span></tt> should
+be traced. This is indeed the case:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from tracefunctions import TraceFunctions
+&gt;&gt;&gt; mod=TraceFunctions('mod',{})
+&gt;&gt;&gt; mod.f1()
+called f1
+&gt;&gt;&gt; mod.f2()
+called f2
+&gt;&gt;&gt; mod.f3() # does nothing, correct
+</pre>
+<blockquote>
+<pre class="literal-block">
+#&lt;module.py&gt;
+
+&quot;Magically decorated module&quot;
+
+import decorators,sys
+
+thismodule=sys.modules[__name__]
+
+class MyClass: &quot;[Decorated]&quot;
+
+newmod=decorators.decorated(thismodule)
+
+#&lt;/module.py&gt;
+</pre>
+</blockquote>
+<pre class="doctest-block">
+&gt;&gt;&gt; from module import *
+&gt;&gt;&gt; assert isinstance(newmod.MyClass, decorators.Decorated)
+&gt;&gt;&gt; assert isinstance(newmod,decorators.DecoratedModule)
+</pre>
+</div>
+<div class="section" id="introspection-features">
+<h1><a class="toc-backref" href="#id10" name="introspection-features">Introspection features</a></h1>
+<p>The module provides three utilities functions to retrieve the list of
+recognized decorators: <tt class="literal"><span class="pre">decorators.methodlike()</span></tt>, <tt class="literal"><span class="pre">decorators.classlike()</span></tt>
+and <tt class="literal"><span class="pre">decorators.modulelike()</span></tt>:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; for d in decorators.methodlike(): print d
+...
+MethodDecorator
+tracedmethodclassmethod
+tracedmethod
+classmethod
+chattymethodstaticmethod
+staticmethodtracedmethod
+staticmethod
+chattymethod2
+chattymethod
+&gt;&gt;&gt; decorators.classlike()
+['Traced', 'Logged', '_DecoratedLogged', 'ClassDecorator', '_DecoratedM', 'Decorated', '_DecoratedTraced']
+&gt;&gt;&gt; decorators.modulelike()
+['ModuleDecorator', 'DecoratedModule', 'TraceFunctions']
+</pre>
+</div>
+<div class="section" id="the-implementation">
+<h1><a class="toc-backref" href="#id11" name="the-implementation">The implementation</a></h1>
+<p>This part can be safely skipped, unless you are a <em>really</em> curious and
+you want to know how the implementation works.</p>
+<p>The module is rather short (~250 lines) but far from being trivial,
+since it is based on extensive usage of metaclass wizardry.</p>
+<p>The main class-metaclass hierarchy is represented in figure 1, where
+boxes denote classes and ovals denote metaclasses; instantiation is
+denoted by dashed lines whereas inheritance is denoted by continuous
+lines.</p>
+<div class="figure">
+<p><img alt="decorators.png" src="decorators.png" /></p>
+</div>
+<p>The implementation is relatively smart. Suppose for instance
+that a programmer wrote something like</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; from decorators import *
+&gt;&gt;&gt; object=decorated(object)
+&gt;&gt;&gt; class C(object):
+... def f():
+... &quot;[staticmethod,MethodDecorator]&quot;
+</pre>
+<p>to document the fact that <tt class="literal"><span class="pre">staticmethod</span></tt> is a method decorator
+and not the built-in <tt class="literal"><span class="pre">staticmethod</span></tt>. Since <tt class="literal"><span class="pre">staticmethod</span></tt> already
+derives from <tt class="literal"><span class="pre">MethodDecorator</span></tt>, it is redundant to repeat
+<tt class="literal"><span class="pre">MethodDecorator</span></tt>. Apparently, there is the risk of generating
+an useless <tt class="literal"><span class="pre">staticmethodMethodDecorator</span></tt> class, doing the same
+as <tt class="literal"><span class="pre">staticmethod</span></tt>. Fortunately, the implementation is able
+to recognize redundant class. In this case, a class called
+<tt class="literal"><span class="pre">MethodDecoratorDecorator</span></tt> is <em>not</em> created; <tt class="literal"><span class="pre">staticmethod</span></tt>
+is used instead:</p>
+<pre class="doctest-block">
+&gt;&gt;&gt; print type(C.__dict__['f'])
+&lt;class 'decorators.staticmethod'&gt;
+</pre>
+<p>The current implementation does not make any attempt of optimization and
+there may be alternative implementations faster or more memory efficient.
+At this experimental level I didn't care to explore about performances
+issues. They does not probably matter unless one has to decorate
+thousands or millions of functions and classes.</p>
+<p>Finally, a word about bugs. The <tt class="literal"><span class="pre">decorators</span></tt> module is fairly sophisticated,
+therefore whereas I can guarantee that it passes my test suite (which is extracted
+from the documentation that you are reading), I cannot guarantee that it
+is correct. If somebody finds a bug or an unexpected behavior, please let me
+know and I will try to fix it.</p>
+<!-- References: -->
+</div>
+</div>
+<hr class="footer"/>
+<div class="footer">
+<a class="reference" href="pep318.txt">View document source</a>.
+Generated on: 2003-09-09 16:26 UTC.
+Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
+</div>
+</body>
+</html>
diff --git a/pypers/pep318/working/pep318.txt b/pypers/pep318/working/pep318.txt
new file mode 100755
index 0000000..03667bf
--- /dev/null
+++ b/pypers/pep318/working/pep318.txt
@@ -0,0 +1,1048 @@
+Implementing PEP 318 (decorators)
+======================================================================
+
+.. contents::
+
+Having plenty of free time in these days, I have finished an old
+project of mine, the implementation of PEP 318 in pure Python.
+
+Here is the rationale:
+
+* some kind of decorator syntax is scheduled to go in Python 2.4,
+ therefore it is interesting to play with the concept;
+
+* it is nice to play with decorators now, without having to
+ wait for one year or so;
+
+* it is much easier to experiment with the pure Python implementation;
+
+* the implementation can be seen as an exercise on modern Python
+ programming and may be valuable to people wanting to study the most
+ advanced new constructs in Python 2.2 (descriptors, metaclasses,
+ cooperative methods, etc.)
+
+Basics
+--------------------------------------------------------------------
+
+As people in this list most probably know, PEP 318 has the goal
+of providing a nice syntactic sugar for expressions like
+
+ ::
+
+ def identity(x):
+ return x
+ identity=staticmethod(identity)
+
+or
+
+ ::
+
+ def nameof(cls):
+ return cls.__name__
+ nameof=classmethod(nameof)
+
+which are pretty verbose. It is clear that having new syntax (as
+for instance the proposed square bracket notation)
+
+ ::
+
+ def identity(x)[staticmethod]:
+ return x
+
+ def nameof(cls)[classmethod]:
+ return cls.__name__
+
+involves changing the grammar and modifying the interpreter at the
+C level. However, it is possible to have the same effect without
+changing the Python grammar. The idea is to use magic docstrings
+like this:
+
+ ::
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ def nameof(cls):
+ "[classmethod]"
+ return cls.__name__
+
+The implementation is able to recognize such docstrings
+and to automagically convert the functions in (method) decorators.
+
+Method decorators are nothing else than a sophisticated kind of wrappers.
+``staticmethod`` and ``classmethod`` are two examples of already existing
+decorators (actually my implementation rewrites them, but let me pass on
+this detail). Technically speaking, method decorators are classes
+taking a single function as input and producing a descriptor object
+as output (properties are not decorators according to this definition,
+since they take four functions as input, ``get, set, del_`` and ``doc``).
+Descriptors_ are objects with a ``__get__`` method; they are quite
+sophisticated, but fortunately they have been wonderfully explained by
+Raymond Hettinger already, so I am allowed to skip this point ;). A knowledge
+of descriptors is not needed in order to use the ``decorator`` module;
+however it is welcomed for advanced users wanting to implement
+custom decorators.
+
+Simple usage of decorators
+------------------------------------------------------------------------
+
+Before talking about the implementation details, I will show
+how the ``decorators`` module works in practice. The simplest and
+safest usage is by means of the functions ``decorators.decorate``
+and ``decorators.decorated``:
+
+1. ``decorators.decorated(obj)`` takes an object and checks its docstring;
+ if a magic docstring is found, it returns a decorated version of the
+ object, otherwise it returns ``None``;
+
+2. ``decorators.decorate(obj)`` takes a dictionary or an object with a
+ ``.__dict__`` attribute and returns ``None``. It works by
+ invoking ``decorators.decorated`` on the elements of the dictionary
+ and by modifying them if needed.
+
+Here is an example:
+
+ ::
+
+ #<example1.py>
+
+ "How to use ``decorators.decorate`` and ``decorators.decorated``"
+
+ import decorators
+
+ def do_nothing(self):
+ "No magic docstring here"
+
+ def identity(x):
+ "[staticmethod]" # magic docstring here
+ return x
+
+ def nameof(cls):
+ "[classmethod]" # magic docstring here too
+ return cls.__name__
+
+ dic={'nameof': nameof, 'do_nothing': do_nothing}
+ decorators.decorate(dic) # converts nameof -> classmethod
+
+ C=type('C',(),dic) # creates the class with the modified dictionary
+ C.identity=decorators.decorated(identity) # converts identity -> staticmethod
+ c=C() # creates the instance
+
+ #</example1.py>
+
+and here is the testing:
+
+>>> from example1 import C,c
+>>> assert c.do_nothing() is None
+>>> assert C.identity(1) == 1
+>>> assert C.nameof() == 'C'
+>>> assert c.identity(1) == 1
+>>> assert c.nameof() == 'C'
+
+One can even pass the ``globals()`` dictionary since objects without
+a magic docstring are simply ignored. Therefore the previous example
+can be rewritten as
+
+ ::
+
+ #<example2.py>
+
+ import decorators
+
+ def do_nothing(self):
+ "No magic docstring here"
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ def nameof(cls):
+ "[classmethod]"
+ return cls.__name__
+
+ decorators.decorate(globals()) # decorates the functions
+
+ class C(object):
+ identity=identity
+ nameof=nameof
+ do_nothing=do_nothing
+
+ c=C()
+
+ #</example2.py>
+
+Here is the testing:
+
+>>> from example2 import c,C
+>>> assert c.do_nothing() is None
+>>> assert C.identity(1) == 1
+>>> assert C.nameof() == 'C'
+>>> assert c.identity(1) == 1
+>>> assert c.nameof() == 'C'
+
+Notice that the call to ``decorators.decorate(globals())`` must be done
+*after* the function definitions, otherwise the functions would
+not converted, since they were not in the global dictionary at the
+time of the call. Moreover, one should not try to pass the ``locals()``
+dictionary, since it will not work when ``locals() != globals()``.
+
+Alternatively, one can just decorate the class:
+
+ ::
+
+ #<example3.py>
+
+ import decorators
+
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ def nameof(cls):
+ "[classmethod]"
+ return cls.__name__
+
+ class C:
+ identity=identity
+ nameof=nameof
+
+ decorators.decorate(C)
+
+ c=C()
+
+ # testing
+ assert C.identity(1) == 1
+ assert C.nameof() == 'C'
+ assert c.identity(1) == 1
+ assert c.nameof() == 'C'
+
+ #</example3.py>
+
+This example also shows that decorators work both for `new style classes
+and old style classes`_:
+
+>>> from example3 import *
+>>> type(C) # C is an old style class
+<type 'classobj'>
+
+At this point the difference between ``decorators.decorate`` and
+``decorators.decorated`` should be pointed out. The first syntax
+modifies the class dictionary, whereas the second creates a new
+class with the same name of the first one:
+
+>>> class D:
+... identity=identity
+>>> decorators.decorated(D)
+<class 'D'>
+>>> D.identity(1) # this is the old D
+Traceback (most recent call last):
+ ...
+TypeError: unbound method identity() must be called with D instance as first argument (got int instance instead)
+
+Therefore one has to redefine to old class in order the statement to
+have effect:
+
+
+>>> D=decorators.decorated(D)
+>>> D.identity(1) # this is the new D
+1
+
+Adding a bit of magic
+----------------------------------------------------------------------
+
+It would be nice to have classes with the ability of automatically
+converting their methods to method decorators according to the docstrings.
+This sounds a bit of magic, but actually can be done very simply by adding
+to the class a docstring starting with "[Decorated]".
+Here is an example:
+
+ ::
+
+ #<example.py>
+
+ import decorators
+
+ class C: # works for old style classes too
+ "[Decorated]"
+ def identity(x):
+ "[staticmethod]"
+ return x
+
+ decorators.decorate(globals())
+
+ c=C()
+
+ # test
+ assert C.identity(1) == 1
+ assert c.identity(1) == 1
+
+ #</example.py>
+
+Under the hood, the magic docstring "[Decorated]" creates an instance of the
+``decorators.Decorated`` metaclass and replace the original class ``C``
+in the global namespace with the new class ``C``; incidentally,
+this converts ``C`` in a new style class:
+
+>>> from example import C
+>>> type(C)
+<class 'decorators.Decorated'>
+
+On the other hand using ``decorators.decorate(C)`` would decorate ``C``, but
+without re-creating it as an instance of "[Decorated]". One can also
+forget the docstring in subclasses of decorated classes:
+
+>>> class D(C):
+... def nameof(cls):
+... "[classmethod]"
+... return cls.__name__
+>>> print D.nameof()
+D
+
+The trick works for classes containing inner classes, too:
+
+ ::
+
+ #<example4.py>
+
+ import decorators
+
+ class C:
+ "[Decorated]" # required docstring
+ def identity(x):
+ "[staticmethod]"
+ return x
+ class Inner:
+ "[Decorated]" # required docstring
+ def nameof(cls):
+ "[classmethod]"
+ return cls.__name__
+
+ decorators.decorate(globals())
+
+ assert C.identity(1) == 1
+ assert C.Inner.nameof() == 'Inner'
+
+ #</example4.py>
+
+
+Adding more magic
+----------------------------------------------------------------------------
+
+There is a neat trick to simplify the usage of decorators: decorating the
+``object`` class. Then all methods in all new style classes of your module
+will be checked for magic docstrings and automagically decorated if needed.
+This can be done by simply writing
+
+ ::
+
+ import decorators
+ object=decorators.decorated(object)
+
+on top of your module. Here is an example:
+
+ ::
+
+ #<example.py>
+
+ import inspect, decorators
+ object=decorators.decorated(object)
+
+ def identity(x):
+ "[staticmethod] defined outside a class"
+ return x
+
+ assert inspect.isfunction(identity) # not yet a decorator
+
+ class C1(object):
+ def nameof(cls):
+ "[classmethod] defined inside a class"
+ return cls.__name__
+ identity=identity # automagically converted to a decorator
+
+ c1=C1() # C1 instance
+
+ # testing
+
+ assert C1.identity(1) == 1
+ assert C1.nameof() == 'C1'
+ assert c1.identity(1) == 1
+ assert c1.nameof() == 'C1'
+
+ #</example.py>
+
+Notice that adding ``identity`` after the class creation with the syntax
+``C.identity=identity`` would not work. Moreover, the magic only works
+for new style classes, since the implementation operates
+by enhancing the ``object`` class in the calling module.
+The enhancement includes providing a new default printing representation
+for instances:
+
+>>> from example import c1
+>>> print c1
+<instance of C1>
+
+
+The ``decorated(object)`` trick (and the "[Decorated]" syntax too)
+is not 100% safe, because of possible metaclass conflicts:
+
+>>> import decorators; object=decorators.decorated(object)
+>>> class M(type): pass
+...
+>>> class D(object):
+... __metaclass__=M
+Traceback (most recent call last):
+ ...
+TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
+
+The decorators module imports the ``makecls`` function from my
+``noconflict`` module just to avoid this kind of problems:
+
+>>> class D(object):
+... __metaclass__=decorators.makecls(M)
+>>> type(D)
+<class 'noconflict._DecoratedM'>
+
+It is possible to go even deeper in black magic, and to decorate all
+the new style classes in *all* modules, by decorating ``__builtin__.object``:
+
+ ::
+
+ import decorators,__builtin__
+ __builtin.object=decorators.decorated(object)
+
+Still, redefining ``__builtin__object`` is not recommended since it
+may induce metaclass conflicts in other modules using metaclasses.
+It will work only if you import modules not using metaclasses, or
+modules using metaclasses safely, i.e. modules taking care of
+possible conflicts by using the ``makecls`` function or an equivalent one.
+
+Defining method decorators
+-----------------------------------------------------------------------
+
+The decorators module contains two predefinite method decorators,
+``staticmethod`` and ``classmethod``, which emulate the built-ins
+with the same names. However, it is possible to write your own
+custom decorators. The ``decorators`` module provides a
+``MethodDecorator`` class which is here exactly for that purpose.
+
+Custom decorators are expected to be implemented by subclassing
+``MethodDecorator`` and by overriding its ``get`` method, which
+automagically induces a ``__get__`` method, turning the class
+in a descriptor. This
+machinery is needed since ``__get__`` cannot be made cooperative
+using the standard ``super`` mechanism (there would be a confusion
+between ``super.__get__`` and the decorator ``__get__``). This is a bit
+tricky, but the causal programmer is not expected to write custom
+decorators, and actually I don't want to make the access to decorators
+*too* easy
+
+For instance, let me show the implementation of a ``chattymethod``
+that prints a message when it is called:
+
+ ::
+
+ #<customdec.py>
+
+ from decorators import *
+
+ class chattymethod(MethodDecorator):
+ logfile=file('file1.log','w')
+ def get(self,obj,cls=None): # same signature as __get__
+ print >> self.logfile,'calling %s from %s' % (self,obj or cls)
+ return super(chattymethod,self).get(obj,cls)
+
+ #</customdec.py>
+
+Notice the usage of the ``super().get`` trick. This guarantees that
+``chattymethod`` will play well with other decorators (i.e. it
+can be nicely composed via multiple inheritance)
+
+Here is an example of usage
+
+ ::
+
+ #<chatty.py>
+
+ from customdec import decorated,chattymethod
+ object=decorated(object)
+
+ class C(object):
+ def f():
+ "[chattymethod,staticmethod]"
+
+ c=C()
+
+ c.f()
+ C.f()
+
+ #</chatty.py>
+
+The content of the logfile is then
+
+ ::
+
+ calling <chattymethodstaticmethod:f> from <instance of C>
+ calling <chattymethodstaticmethod:f> from <class C[Decorated]>
+
+From this output we see how the "[chattymethod,staticmethod]"
+magic docstring is responsible for the creation of a new decorator class
+``chattymethodstaticmethod``, obtained via multiple inheritance from
+``chattymethod`` and ``staticmethod`` respectively.
+
+One can easily change the logfile, if need there is
+
+ ::
+
+ #<chatty.py>
+
+ chattymethod.logfile=file('file2.log','w')
+
+ def g():
+ "[chattymethod,staticmethod]"
+
+ C.g=decorated(g)
+ C.g # message written in file2.log
+ C.f # message written in file2.log
+
+ #</chatty.py>
+
+Now ``file2.log`` will contains the messages
+
+ ::
+
+ calling <chattymethodstaticmethod:g> from <class C[Decorated]>
+ calling <chattymethodstaticmethod:f> from <class C[Decorated]>
+
+This approach has the drawback that chattymethods created before changing
+the logfile will also print to the new logfile, if invoked after the
+change. This can be avoided by converting ``logfile`` from a class variable
+to an instance variable in the ``__init__`` method:
+
+ ::
+
+ #<chatty2.py>
+
+ import sys
+ from chatty import *
+
+ class chattymethod2(chattymethod):
+ def __init__(self,func):
+ super(chattymethod2,self).__init__(func)
+ self.logfile=self.logfile # class variable becomes instance variable
+
+ class C(object):
+ chattymethod2.logfile=sys.stdout
+ f=chattymethod2(lambda self:None)
+ chattymethod2.logfile=file('file3.log','w')
+ g=chattymethod2(lambda self:None)
+
+ c=C()
+
+ #</chatty2.py>
+
+Notice that the ``__init__`` method should have the signature
+``__init__(self,func)``, where ``func`` is the function to be
+converted in the decorator object. Here is the testing:
+
+>>> from chatty2 import c
+>>> c.f()
+calling <chattymethod2:<lambda>> from <instance of C>
+>>> c.g() # message written in file3.log
+>>> c.f() # message written in stdout, not in file3.log!
+calling <chattymethod2:<lambda>> from <instance of C>
+
+Tracing methods
+--------------------------------------------------------------------------
+
+In order to show a non-trivial example, I will show how
+decorators can be used to implement traced methods.
+Here is the code (notice: the lazy reader can safely skip the
+implementation details and go directly to the usage section ;)
+
+ ::
+
+ #<customdec.py>
+
+ class tracedmethod(MethodDecorator):
+ "Descriptor class, converts a method in a traced method"
+ indent=0; output=sys.stdout # defaults
+ def __init__(self,func):
+ super(tracedmethod,self).__init__(func)
+ self.funcname=self.func.__name__
+ def get(self,obj,cls):
+ if obj is None: name=self.inside.__name__ # called from class
+ else: name='<%s>' % self.inside.__name__ # from instance
+ methodwrapper=super(tracedmethod,self).get(obj,cls)
+ def _(*args,**kw):
+ i=' '*self.indent # default indentation
+ self.__class__.indent+=4 # increases indentation
+ self.output.write("%sCalling '%s.%s' with arguments " %
+ (i,name,self.funcname))
+ self.output.write("%s ...\n" % (str(args)+str(kw)))
+ res=methodwrapper(*args,**kw)
+ self.output.write("%s'%s.%s' called with result: %s\n"
+ % (i,name,self.funcname,res))
+ self.__class__.indent-=4 # restores default indentation
+ return res
+ return _
+
+ #</customdec.py>
+
+As soon as the ``tracedmethod`` module is loaded, the ``tracedmethod`` class
+is added to the list of know decorators, so one should use the "[tracedmethod]"
+docstring instead and not "[tracedmethod.tracedmethod]".
+
+``tracedmethod`` which is quite useful during
+debugging. Here is an example of usage, in tracing the internal working
+of a recursive function:
+
+ ::
+
+ #<example4.py>
+
+ import decorators,customdec
+
+ class C(object):
+ def fact(self,n):
+ "[tracedmethod]"
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+
+ decorators.decorate(C)
+
+ c=C()
+
+ #</example4.py>
+
+>>> from example4 import c
+>>> c.fact(2)
+Calling '<C>.fact' with arguments (2,){} ...
+ Calling '<C>.fact' with arguments (1,){} ...
+ Calling '<C>.fact' with arguments (0,){} ...
+ '<C>.fact' called with result: 1
+ '<C>.fact' called with result: 1
+'<C>.fact' called with result: 2
+2
+
+An alternative spelling, not involving magic docstrings, nor the
+decorators module, is the following:
+
+ ::
+
+ #<example5.py>
+
+ from customdec import tracedmethod
+
+ class C(object):
+ def fact(self,n):
+ if n==0: return 1
+ else: return n*self.fact(n-1)
+ fact=tracedmethod(fact)
+
+ c=C()
+
+ #</example5.py>
+
+>>> from example5 import c
+>>> c.fact(2)
+Calling '<?>.fact' with arguments (2,){} ...
+ Calling '<?>.fact' with arguments (1,){} ...
+ Calling '<?>.fact' with arguments (0,){} ...
+ '<?>.fact' called with result: 1
+ '<?>.fact' called with result: 1
+'<?>.fact' called with result: 2
+2
+
+Notice that in this second syntax ``fact`` does not know where it
+is defined; however the containing class can be explicitly set:
+
+ ``C.__dict__['fact'].inside=C``
+
+The ``inside`` attribute is automagically set if the docstring syntax
+is used.
+
+Here is how to trace cooperative methods in complicate hierarchies
+(which is useful for debugging):
+
+ ::
+
+ #<tracing.py>
+
+ import decorators,customdec
+ object=decorators.decorated(object)
+
+ class B(object):
+ def __init__(self):
+ "[tracedmethod]"
+ super(B,self).__init__()
+
+ class D(object):
+ def __init__(self):
+ "[tracedmethod]"
+ super(D,self).__init__()
+
+ class E(B,D):
+ def __init__(self):
+ "[tracedmethod]"
+ super(E,self).__init__()
+
+ #</tracing.py>
+
+>>> from tracing import E
+>>> e=E()
+Calling '<E>.__init__' with arguments (){} ...
+ Calling '<B>.__init__' with arguments (){} ...
+ Calling '<D>.__init__' with arguments (){} ...
+ '<D>.__init__' called with result: None
+ '<B>.__init__' called with result: None
+'<E>.__init__' called with result: None
+
+In this example decorating ``object`` is the easiest way to go.
+
+Composition of decorators
+--------------------------------------------------------------------
+
+Decorators can be composed: for instance, you can trace a
+classmethod as in this example:
+
+ ::
+
+ #<example6.py>
+
+ import customdec
+ from decorators import decorated
+ object=decorated(object)
+
+ class C(object):
+ def fact(cls,n):
+ "[tracedmethod,classmethod]"
+ if n==0: return 1
+ else: return n*cls.fact(n-1)
+
+ #</example6.py>
+
+>>> from example6 import C
+>>> C.fact(2)
+Calling 'C.fact' with arguments (2,){} ...
+ Calling 'C.fact' with arguments (1,){} ...
+ Calling 'C.fact' with arguments (0,){} ...
+ 'C.fact' called with result: 1
+ 'C.fact' called with result: 1
+'C.fact' called with result: 2
+2
+
+Under the hood the syntax
+
+ ::
+
+ [tracedmethod,classmethod]
+
+generates a ``tracedmethodclassmethod`` class obtained via
+multiple inheritance:
+
+>>> for c in type(C.__dict__['fact']).__mro__: print c
+...
+<class 'noconflict.tracedmethodclassmethod'>
+<class 'customdec.tracedmethod'>
+<class 'decorators.classmethod'>
+<class 'decorators.MethodDecorator'>
+<class 'decorators.Decorator'>
+<type 'object'>
+
+In this case the order does not matter and using the docstring
+"[classmethod,tracedmethod]" would work too, but
+in general one must pay attention to precedence issues.
+For instance the following will not work:
+
+>>> class C(object):
+... def fact(n):
+... "[staticmethod,tracedmethod]"
+... if n==0: return 1
+... else: return n*C.fact(n-1)
+>>> C.fact(2)
+Traceback (most recent call last):
+ ...
+AttributeError: 'function' object has no attribute 'im_func'
+
+The problem here is that ``staticmethod.get`` invokes ``tracedmethod.get``
+which returns a function and not a method-wrapper with an ``im_func`` method.
+On the other hand, composing the decorators in the other order
+"[tracedmethod,staticmethod]" will work just fine.
+
+Class decorators
+-----------------------------------------------------------------------
+
+PEP 318 proposes to decorate methods by using descriptors; it is
+quite natural to extend this idea and to decorate classes by using
+class decorators implemented as metaclasses. We already saw a
+class decorator at work, the metaclass ``Decorated``, giving
+to its instances the ability to interpret magic docstrings,
+and converting functions in method decorators.
+
+To define a custom class decorator is easy: one defines a custom metaclasses
+as usual, with the only difference from deriving by ``ClassDecorator`` instead
+of deriving from ``type``. To understand how this works in practice, let me
+show how to add logging capabilities to a given class. The first
+step is to define a suitable class decorator, such as the following:
+
+ ::
+
+ #<customdec.py>
+
+ class Logged(ClassDecorator):
+ def __init__(cls,name,bases,dic):
+ super(Logged,cls).__init__(name,bases,dic)
+ print "%s created" % cls
+
+ #</customdec.py>
+
+``Logged`` is derived by the metaclass ``ClassDecorator``,
+which provides a certain amount of magic under the hood (in particular
+its printing representation and its calling syntax are redefined by its
+metaclass ``MetaDecorator``). Logging capabilities can be added to a class
+by simply using the magic docstring syntax:
+
+>>> from customdec import Logged
+>>> object=decorators.decorated(object)
+>>> class D(object):
+... "[Logged]"
+<class D[_DecoratedLogged]> created
+
+Notice that ``D`` inherits the ``Decorated`` metaclass from ``object``
+and the ``Logged`` metaclass from the docstring; the conflict is
+automagically avoid by the miracolous creation of a ``_DecoratedLogged``
+metaclass, obtained via multiple inheritance from ``Decorated`` and
+``Logged``. All the magic is performed in the ``noconflict`` module,
+discussed in a cookbook_ recipe of mine.
+
+Notice that the printing representation of ``D`` involves the name
+of ``D`` preceded by the name of its metaclass, which in this case
+is ``_DecoratedLogged``
+
+Each time an instance of ``Logged`` is created, a similar message is printed:
+
+>>> class E(D):
+... pass
+<class E[_DecoratedLogged]> created
+
+Notice that ``E`` does not have any magic docstring
+
+>>> E.__doc__ # no docstring
+
+but still it inherits its magic from ``D``.
+
+The ``decorators`` module provides the already saw class decorator
+``Decorated``, which converts methods in method decorators.
+
+Another example is
+
+ ::
+
+ #<customdec.py>
+
+ from types import FunctionType
+
+ class Traced(ClassDecorator):
+ def __init__(cls,n,b,d):
+ for name,func in d.iteritems():
+ if isinstance(func,FunctionType):
+ func.__doc__="[tracedmethod] " + (func.__doc__ or '')
+ super(Traced,cls).__init__(n,b,d)
+
+
+ #</customdec.py>
+
+Here is an example of usage:
+
+>>> from customdec import *
+>>> object=decorated(object)
+>>> class C(object):
+... """[Traced] The class decorator adds the magic docstring
+... '[tracedmethod]' to f1 and f2, which are then converted
+... to method decorator objects."""
+... def f1(self): pass
+... def f2(self): pass
+...
+>>> c=C()
+>>> c.f1()
+Calling '<C>.f1' with arguments (){} ...
+'<C>.f1' called with result: None
+>>> c.f2()
+Calling '<C>.f2' with arguments (){} ...
+'<C>.f2' called with result: None
+
+Module decorators
+-----------------------------------------------------------------------
+
+Finally, one can decorate entire modules through the concept of
+*module decorators*. Module decorators have the ability of decorating
+modules by changing their dictionary. Custom module decorators
+should be derived from the class ``decorators.ModuleDecorator``, by
+cooperatively overriding its ``__init__(self,mod)`` method. Writing
+a module decorator is a bit tricky, but I do expect only
+expert programmers to play this kind of game.
+For instance, suppose one wants to trace all the functions in a module,
+unless they have the docstring "-untraced-" . This can be done with a
+suitable module decorator which modifies the module dictionary.
+Here is an example
+
+ ::
+
+ #<customdec.py>
+
+ from decorators import *
+
+ class TraceFunctions(ModuleDecorator):
+ def __init__(self,mod):
+ super(TraceFunctions,self).__init__(mod)
+ for name,func in self.__dict__.items():
+ if inspect.isfunction(func):
+ doc=func.__doc__ or ''
+ if doc.startswith('-untraced-'):
+ pass # do nothing
+ else:
+ def tracedfunc(func=func): # default argument trick
+ def _(*args,**kw):
+ print 'called',func.__name__
+ return func(*args,**kw)
+ return _
+ setattr(self,name,tracedfunc())
+
+ #</customdec.py>
+
+Let me test that the module decorator does its job. Consider the module
+
+ ::
+
+ #<mod.py>
+
+ #"[TraceFunctions]"
+
+ def f1(): pass
+
+ def f2(): pass
+
+ def f3(): "-untraced-"
+
+ #</mod.py>
+
+By importing this module, only the functions ``f1`` and ``f2`` should
+be traced. This is indeed the case:
+
+>>> from customdec import TraceFunctions
+>>> mod=TraceFunctions('mod',{})
+>>> mod.f1()
+called f1
+>>> mod.f2()
+called f2
+>>> mod.f3() # does nothing, correct
+
+ ::
+
+ #<module.py>
+
+ "Magically decorated module"
+
+ import decorators,sys
+
+ thismodule=sys.modules[__name__]
+
+ class MyClass: "[Decorated]"
+
+ newmod=decorators.decorated(thismodule)
+
+ #</module.py>
+
+>>> from module import *
+>>> assert isinstance(newmod.MyClass, decorators.Decorated)
+>>> assert isinstance(newmod,decorators.DecoratedModule)
+
+The implementation
+-----------------------------------------------------------------------
+
+This part can be safely skipped, unless you are a *really* curious and
+you want to know how the implementation works.
+
+The module is rather short (~250 lines) but far from being trivial,
+since it is based on extensive usage of metaclass wizardry.
+
+The main class-metaclass hierarchy is represented in figure 1, where
+boxes denote classes and ovals denote metaclasses; instantiation is
+denoted by dashed lines whereas inheritance is denoted by continuous
+lines.
+
+.. figure:: decorators.png
+
+The implementation is relatively smart. Suppose for instance
+that a programmer wrote something like
+
+>>> from decorators import *
+>>> object=decorated(object)
+>>> class C(object):
+... def f():
+... "[staticmethod,MethodDecorator]"
+
+to document the fact that ``staticmethod`` is a method decorator
+and not the built-in ``staticmethod``. Since ``staticmethod`` already
+derives from ``MethodDecorator``, it is redundant to repeat
+``MethodDecorator``. Apparently, there is the risk of generating
+an useless ``staticmethodMethodDecorator`` class, doing the same
+as ``staticmethod``. Fortunately, the implementation is able
+to recognize redundant class. In this case, a class called
+``MethodDecoratorDecorator`` is *not* created; ``staticmethod``
+is used instead:
+
+>>> print type(C.__dict__['f'])
+<class 'decorators.staticmethod'>
+
+The module provides three utilities functions to retrieve the list of
+recognized decorators: ``decorators.methodlike()``, ``decorators.classlike()``
+and ``decorators.modulelike()``:
+
+>>> for d in decorators.methodlike(): print d
+...
+<class 'decorators.MethodDecorator'>
+<class 'decorators.staticmethod'>
+<class 'decorators.classmethod'>
+<class 'customdec.chattymethod'>
+<class 'customdec.tracedmethod'>
+<class 'noconflict.chattymethodstaticmethod'>
+<class 'chatty2.chattymethod2'>
+<class 'noconflict.tracedmethodclassmethod'>
+<class 'noconflict.staticmethodtracedmethod'>
+
+>>> for d in decorators.classlike(): print d
+...
+<class 'decorators.ClassDecorator'>
+<class 'decorators.Decorated'>
+<class 'noconflict._DecoratedM'>
+<class 'customdec.Logged'>
+<class 'customdec.Traced'>
+<class 'noconflict._DecoratedLogged'>
+<class 'noconflict._DecoratedTraced'>
+
+>>> for d in decorators.modulelike(): print d
+...
+<class 'decorators.ModuleDecorator'>
+<class 'decorators.DecoratedModule'>
+<class 'customdec.TraceFunctions'>
+
+The current implementation does not make any attempt of optimization and
+there may be alternative implementations faster or more memory efficient.
+At this experimental level I didn't care to explore about performances
+issues. They does not probably matter unless one has to decorate
+thousands or millions of functions and classes.
+
+Finally, a word about bugs. The ``decorators`` module is fairly sophisticated,
+therefore whereas I can guarantee that it passes my test suite (which involves
+~100 tests automatically extracted from the documentation you are reading),
+I cannot guarantee that it is correct. If somebody finds a bug or an unexpected
+behavior, please let me know and I will try to fix it.
+
+.. References:
+
+.. _new style classes and old style classes:
+ http://www.python.org/2.3/descrintro.html
+.. _Descriptors: http://users.rcn.com/python/download/Descriptor.htm
+.. _cookbook: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204197
diff --git a/pypers/pep318/working/pydoc.html b/pypers/pep318/working/pydoc.html
new file mode 100755
index 0000000..8422868
--- /dev/null
+++ b/pypers/pep318/working/pydoc.html
@@ -0,0 +1,504 @@
+
+<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head><title>Python: module decorators</title>
+</head><body bgcolor="#f0f0f8">
+
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
+<tr bgcolor="#7799ee">
+<td valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>decorators</strong></big></big></font></td
+><td align=right valign=bottom
+><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/mnt/exp/MyDocs/pypers/pep318/decorators.py">/mnt/exp/MyDocs/pypers/pep318/decorators.py</a></font></td></tr></table>
+ <p><tt>A&nbsp;module&nbsp;to&nbsp;implement&nbsp;pep318&nbsp;(decorator&nbsp;syntax)&nbsp;via&nbsp;magic&nbsp;doctrings.<br>
+For&nbsp;the&nbsp;documentation&nbsp;see<br>
+&nbsp;<br>
+<a href="http://www.phyast.pitt.edu/~micheles/python/decorators,html">http://www.phyast.pitt.edu/~micheles/python/decorators,html</a><br>
+&nbsp;<br>
+help&nbsp;and&nbsp;pydoc&nbsp;are&nbsp;useful&nbsp;too.</tt></p>
+<p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#aa55cc">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#fffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
+
+<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="__builtin__.html">__builtin__</a><br>
+<a href="inspect.html">inspect</a><br>
+</td><td width="25%" valign=top><a href="noconflict.html">noconflict</a><br>
+<a href="re.html">re</a><br>
+</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
+<a href="types.html">types</a><br>
+</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ee77aa">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
+
+<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><dl>
+<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#UnknownDecoratorError">UnknownDecoratorError</a>
+</font></dt></dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#Decorator">Decorator</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#ClassDecorator">ClassDecorator</a>(<a href="__builtin__.html#type">__builtin__.type</a>, <a href="decorators.html#Decorator">Decorator</a>)
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#Decorated">Decorated</a>
+</font></dt></dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="decorators.html#MethodDecorator">MethodDecorator</a>
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#classmethod">classmethod</a>
+</font></dt><dt><font face="helvetica, arial"><a href="decorators.html#staticmethod">staticmethod</a>
+</font></dt></dl>
+</dd>
+</dl>
+</dd>
+</dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="__builtin__.html#type">__builtin__.type</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#ClassDecorator">ClassDecorator</a>(<a href="__builtin__.html#type">__builtin__.type</a>, <a href="decorators.html#Decorator">Decorator</a>)
+</font></dt><dd>
+<dl>
+<dt><font face="helvetica, arial"><a href="decorators.html#Decorated">Decorated</a>
+</font></dt></dl>
+</dd>
+<dt><font face="helvetica, arial"><a href="decorators.html#MetaDecorator">MetaDecorator</a>
+</font></dt></dl>
+</dd>
+</dl>
+ <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="ClassDecorator">class <strong>ClassDecorator</strong></a>(<a href="__builtin__.html#type">__builtin__.type</a>, <a href="decorators.html#Decorator">Decorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Metaclass&nbsp;callable&nbsp;with&nbsp;one&nbsp;or&nbsp;three&nbsp;arguments,&nbsp;having&nbsp;its&nbsp;__call__<br>
+method&nbsp;redefined&nbsp;by&nbsp;the&nbsp;meta-metaclass&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.&nbsp;It&nbsp;redefines<br>
+__str__&nbsp;both&nbsp;on&nbsp;classes&nbsp;and&nbsp;instances.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#ClassDecorator">ClassDecorator</a></dd>
+<dd><a href="__builtin__.html#type">__builtin__.type</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="ClassDecorator-__init__"><strong>__init__</strong></a>(cls, name, bases, dic)</dt></dl>
+
+<dl><dt><a name="ClassDecorator-__str__"><strong>__str__</strong></a>(cls)</dt></dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><a name="ClassDecorator-__call__"><strong>__call__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__call__">__call__</a>(...)&nbsp;&lt;==&gt;&nbsp;x(...)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__cmp__"><strong>__cmp__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__cmp__">__cmp__</a>(y)&nbsp;&lt;==&gt;&nbsp;cmp(x,y)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ClassDecorator-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-__subclasses__"><strong>__subclasses__</strong></a>(...)</dt><dd><tt><a href="#ClassDecorator-__subclasses__">__subclasses__</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;immediate&nbsp;subclasses</tt></dd></dl>
+
+<dl><dt><a name="ClassDecorator-mro"><strong>mro</strong></a>(...)</dt><dd><tt><a href="#ClassDecorator-mro">mro</a>()&nbsp;-&gt;&nbsp;list<br>
+return&nbsp;a&nbsp;<a href="__builtin__.html#type">type</a>'s&nbsp;method&nbsp;resolution&nbsp;order</tt></dd></dl>
+
+<hr>
+Data and other attributes inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><strong>__base__</strong> = &lt;type 'type'&gt;</dl>
+
+<dl><dt><strong>__bases__</strong> = (&lt;type 'type'&gt;, &lt;class 'decorators.Decorator'&gt;)</dl>
+
+<dl><dt><strong>__basicsize__</strong> = 420</dl>
+
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;</dl>
+
+<dl><dt><strong>__dictoffset__</strong> = 132</dl>
+
+<dl><dt><strong>__flags__</strong> = 22523</dl>
+
+<dl><dt><strong>__itemsize__</strong> = 20</dl>
+
+<dl><dt><strong>__mro__</strong> = (&lt;class 'decorators.ClassDecorator'&gt;, &lt;type 'type'&gt;, &lt;class 'decorators.Decorator'&gt;, &lt;type 'object'&gt;)</dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ClassDecorator-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;<a href="__builtin__.html#type">type</a>&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>__weakrefoffset__</strong> = 184</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Guarantees&nbsp;the&nbsp;calling&nbsp;syntax&nbsp;decorator(obj)<br>
+2.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+3.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="Decorated">class <strong>Decorated</strong></a>(<a href="decorators.html#ClassDecorator">ClassDecorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Metaclass&nbsp;which&nbsp;decorates&nbsp;its&nbsp;instances<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#Decorated">Decorated</a></dd>
+<dd><a href="decorators.html#ClassDecorator">ClassDecorator</a></dd>
+<dd><a href="__builtin__.html#type">__builtin__.type</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="Decorated-__init__"><strong>__init__</strong></a>(cls, name, bases, dic)</dt></dl>
+
+<hr>
+Methods inherited from <a href="decorators.html#ClassDecorator">ClassDecorator</a>:<br>
+<dl><dt><a name="Decorated-__str__"><strong>__str__</strong></a>(cls)</dt></dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><a name="Decorated-__call__"><strong>__call__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__call__">__call__</a>(...)&nbsp;&lt;==&gt;&nbsp;x(...)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__cmp__"><strong>__cmp__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__cmp__">__cmp__</a>(y)&nbsp;&lt;==&gt;&nbsp;cmp(x,y)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Decorated-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<dl><dt><a name="Decorated-__subclasses__"><strong>__subclasses__</strong></a>(...)</dt><dd><tt><a href="#Decorated-__subclasses__">__subclasses__</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;immediate&nbsp;subclasses</tt></dd></dl>
+
+<dl><dt><a name="Decorated-mro"><strong>mro</strong></a>(...)</dt><dd><tt><a href="#Decorated-mro">mro</a>()&nbsp;-&gt;&nbsp;list<br>
+return&nbsp;a&nbsp;<a href="__builtin__.html#type">type</a>'s&nbsp;method&nbsp;resolution&nbsp;order</tt></dd></dl>
+
+<hr>
+Data and other attributes inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><strong>__base__</strong> = &lt;class 'decorators.ClassDecorator'&gt;</dl>
+
+<dl><dt><strong>__bases__</strong> = (&lt;class 'decorators.ClassDecorator'&gt;,)</dl>
+
+<dl><dt><strong>__basicsize__</strong> = 420</dl>
+
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;</dl>
+
+<dl><dt><strong>__dictoffset__</strong> = 132</dl>
+
+<dl><dt><strong>__flags__</strong> = 22523</dl>
+
+<dl><dt><strong>__itemsize__</strong> = 20</dl>
+
+<dl><dt><strong>__mro__</strong> = (&lt;class 'decorators.Decorated'&gt;, &lt;class 'decorators.ClassDecorator'&gt;, &lt;type 'type'&gt;, &lt;class 'decorators.Decorator'&gt;, &lt;type 'object'&gt;)</dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#Decorated-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;<a href="__builtin__.html#type">type</a>&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>__weakrefoffset__</strong> = 184</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Guarantees&nbsp;the&nbsp;calling&nbsp;syntax&nbsp;decorator(obj)<br>
+2.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+3.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="Decorator">class <strong>Decorator</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Instance&nbsp;of&nbsp;<a href="#MetaDecorator">MetaDecorator</a>,&nbsp;i.e.&nbsp;each&nbsp;time&nbsp;<a href="#Decorator">Decorator</a>&nbsp;is<br>
+subclassed,&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic&nbsp;is&nbsp;updated.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%">Data and other attributes defined here:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Guarantees&nbsp;the&nbsp;calling&nbsp;syntax&nbsp;decorator(obj)<br>
+2.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+3.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="MetaDecorator">class <strong>MetaDecorator</strong></a>(<a href="__builtin__.html#type">__builtin__.type</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Guarantees&nbsp;the&nbsp;calling&nbsp;syntax&nbsp;decorator(obj)<br>
+2.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+3.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#MetaDecorator">MetaDecorator</a></dd>
+<dd><a href="__builtin__.html#type">__builtin__.type</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="MetaDecorator-__call__"><strong>__call__</strong></a>(dec, *args)</dt><dd><tt>Dispatch&nbsp;to&nbsp;the&nbsp;decorator&nbsp;_call_&nbsp;<a href="#classmethod">classmethod</a></tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__init__"><strong>__init__</strong></a>(dec, *args)</dt></dl>
+
+<hr>
+Data and other attributes defined here:<br>
+<dl><dt><strong>dic</strong> = {'ClassDecorator': &lt;class 'decorators.ClassDecorator'&gt;, 'Decorated': &lt;class 'decorators.Decorated'&gt;, 'Decorator': &lt;class 'decorators.Decorator'&gt;, 'MethodDecorator': &lt;class 'decorators.MethodDecorator'&gt;, 'classmethod': &lt;class 'decorators.classmethod'&gt;, 'staticmethod': &lt;class 'decorators.staticmethod'&gt;}</dl>
+
+<dl><dt><strong>ls</strong> = [&lt;class 'decorators.Decorator'&gt;, &lt;class 'decorators.MethodDecorator'&gt;, &lt;class 'decorators.ClassDecorator'&gt;, &lt;class 'decorators.Decorated'&gt;, &lt;class 'decorators.staticmethod'&gt;, &lt;class 'decorators.classmethod'&gt;]</dl>
+
+<hr>
+Methods inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><a name="MetaDecorator-__cmp__"><strong>__cmp__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__cmp__">__cmp__</a>(y)&nbsp;&lt;==&gt;&nbsp;cmp(x,y)</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MetaDecorator-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-__subclasses__"><strong>__subclasses__</strong></a>(...)</dt><dd><tt><a href="#MetaDecorator-__subclasses__">__subclasses__</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;immediate&nbsp;subclasses</tt></dd></dl>
+
+<dl><dt><a name="MetaDecorator-mro"><strong>mro</strong></a>(...)</dt><dd><tt><a href="#MetaDecorator-mro">mro</a>()&nbsp;-&gt;&nbsp;list<br>
+return&nbsp;a&nbsp;<a href="__builtin__.html#type">type</a>'s&nbsp;method&nbsp;resolution&nbsp;order</tt></dd></dl>
+
+<hr>
+Data and other attributes inherited from <a href="__builtin__.html#type">__builtin__.type</a>:<br>
+<dl><dt><strong>__base__</strong> = &lt;type 'type'&gt;</dl>
+
+<dl><dt><strong>__bases__</strong> = (&lt;type 'type'&gt;,)</dl>
+
+<dl><dt><strong>__basicsize__</strong> = 420</dl>
+
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;</dl>
+
+<dl><dt><strong>__dictoffset__</strong> = 132</dl>
+
+<dl><dt><strong>__flags__</strong> = 22523</dl>
+
+<dl><dt><strong>__itemsize__</strong> = 20</dl>
+
+<dl><dt><strong>__mro__</strong> = (&lt;class 'decorators.MetaDecorator'&gt;, &lt;type 'type'&gt;, &lt;type 'object'&gt;)</dl>
+
+<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MetaDecorator-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;<a href="__builtin__.html#type">type</a>&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
+
+<dl><dt><strong>__weakrefoffset__</strong> = 184</dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="MethodDecorator">class <strong>MethodDecorator</strong></a>(<a href="decorators.html#Decorator">Decorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt><a href="#MethodDecorator">MethodDecorator</a>&nbsp;objects&nbsp;provide&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'str'&nbsp;method<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#MethodDecorator">MethodDecorator</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="MethodDecorator-__get__"><strong>__get__</strong></a> = <a href="#MethodDecorator-get">get</a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<dl><dt><a name="MethodDecorator-__init__"><strong>__init__</strong></a>(self, func)</dt></dl>
+
+<dl><dt><a name="MethodDecorator-__str__"><strong>__str__</strong></a>(self)</dt></dl>
+
+<dl><dt><a name="MethodDecorator-get"><strong>get</strong></a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<hr>
+Data and other attributes defined here:<br>
+<dl><dt><strong>__klass__</strong> = &lt;class 'decorators.?'&gt;</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Guarantees&nbsp;the&nbsp;calling&nbsp;syntax&nbsp;decorator(obj)<br>
+2.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+3.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="UnknownDecoratorError">class <strong>UnknownDecoratorError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt>The&nbsp;name&nbsp;says&nbsp;it&nbsp;all<br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%">Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
+<dl><dt><a name="UnknownDecoratorError-__getitem__"><strong>__getitem__</strong></a>(...)</dt></dl>
+
+<dl><dt><a name="UnknownDecoratorError-__init__"><strong>__init__</strong></a>(...)</dt></dl>
+
+<dl><dt><a name="UnknownDecoratorError-__str__"><strong>__str__</strong></a>(...)</dt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="classmethod">class <strong>classmethod</strong></a>(<a href="decorators.html#MethodDecorator">MethodDecorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt><a href="#Decorator">Decorator</a>,&nbsp;converts&nbsp;a&nbsp;function&nbsp;in&nbsp;a&nbsp;<a href="#classmethod">classmethod</a><br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#classmethod">classmethod</a></dd>
+<dd><a href="decorators.html#MethodDecorator">MethodDecorator</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="classmethod-__get__"><strong>__get__</strong></a> = <a href="#classmethod-get">get</a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<dl><dt><a name="classmethod-get"><strong>get</strong></a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<hr>
+Methods inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><a name="classmethod-__init__"><strong>__init__</strong></a>(self, func)</dt></dl>
+
+<dl><dt><a name="classmethod-__str__"><strong>__str__</strong></a>(self)</dt></dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><strong>__klass__</strong> = &lt;class 'decorators.?'&gt;</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Guarantees&nbsp;the&nbsp;calling&nbsp;syntax&nbsp;decorator(obj)<br>
+2.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+3.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table> <p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#ffc8d8">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#000000" face="helvetica, arial"><a name="staticmethod">class <strong>staticmethod</strong></a>(<a href="decorators.html#MethodDecorator">MethodDecorator</a>)</font></td></tr>
+
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
+<td colspan=2><tt><a href="#Decorator">Decorator</a>,&nbsp;converts&nbsp;a&nbsp;function&nbsp;in&nbsp;a&nbsp;<a href="#staticmethod">staticmethod</a><br>&nbsp;</tt></td></tr>
+<tr><td>&nbsp;</td>
+<td width="100%"><dl><dt>Method resolution order:</dt>
+<dd><a href="decorators.html#staticmethod">staticmethod</a></dd>
+<dd><a href="decorators.html#MethodDecorator">MethodDecorator</a></dd>
+<dd><a href="decorators.html#Decorator">Decorator</a></dd>
+<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
+</dl>
+<hr>
+Methods defined here:<br>
+<dl><dt><a name="staticmethod-__get__"><strong>__get__</strong></a> = <a href="#staticmethod-get">get</a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<dl><dt><a name="staticmethod-get"><strong>get</strong></a>(self, obj, cls<font color="#909090">=None</font>)</dt></dl>
+
+<hr>
+Methods inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><a name="staticmethod-__init__"><strong>__init__</strong></a>(self, func)</dt></dl>
+
+<dl><dt><a name="staticmethod-__str__"><strong>__str__</strong></a>(self)</dt></dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#MethodDecorator">MethodDecorator</a>:<br>
+<dl><dt><strong>__klass__</strong> = &lt;class 'decorators.?'&gt;</dl>
+
+<hr>
+Data and other attributes inherited from <a href="decorators.html#Decorator">Decorator</a>:<br>
+<dl><dt><strong>__dict__</strong> = &lt;dictproxy object&gt;<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dl>
+
+<dl><dt><strong>__metaclass__</strong> = &lt;class 'decorators.MetaDecorator'&gt;<dd><tt>Metaclass&nbsp;inducing&nbsp;a&nbsp;certain&nbsp;amount&nbsp;of&nbsp;magic&nbsp;on&nbsp;decorators:<br>
+1.&nbsp;Guarantees&nbsp;the&nbsp;calling&nbsp;syntax&nbsp;decorator(obj)<br>
+2.&nbsp;Each&nbsp;time&nbsp;a&nbsp;decorator&nbsp;is&nbsp;defined,&nbsp;it&nbsp;is&nbsp;stored&nbsp;in&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.dic<br>
+&nbsp;&nbsp;&nbsp;and&nbsp;<a href="#MetaDecorator">MetaDecorator</a>.ls.<br>
+3.&nbsp;If&nbsp;the&nbsp;(method)&nbsp;decorator&nbsp;has&nbsp;a&nbsp;'get'&nbsp;method,&nbsp;a&nbsp;'__get__'&nbsp;method<br>
+is&nbsp;automagically&nbsp;created&nbsp;as&nbsp;an&nbsp;alias&nbsp;to&nbsp;'get'.</tt></dl>
+
+<dl><dt><strong>__weakref__</strong> = &lt;attribute '__weakref__' of 'Decorator' objects&gt;<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;(if&nbsp;defined)</tt></dl>
+
+</td></tr></table></td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#eeaa77">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
+
+<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><dl><dt><a name="-anyTrue"><strong>anyTrue</strong></a> = sum(...)</dt><dd><tt>sum(sequence,&nbsp;start=0)&nbsp;-&gt;&nbsp;value<br>
+&nbsp;<br>
+Returns&nbsp;the&nbsp;sum&nbsp;of&nbsp;a&nbsp;sequence&nbsp;of&nbsp;numbers&nbsp;(NOT&nbsp;strings)&nbsp;plus&nbsp;the&nbsp;value<br>
+of&nbsp;parameter&nbsp;'start'.&nbsp;&nbsp;When&nbsp;the&nbsp;sequence&nbsp;is&nbsp;empty,&nbsp;returns&nbsp;start.</tt></dd></dl>
+ <dl><dt><a name="-decorate"><strong>decorate</strong></a>(objdict)</dt><dd><tt>takes&nbsp;an&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;a&nbsp;dictionary&nbsp;and&nbsp;decorates&nbsp;all&nbsp;its&nbsp;functions<br>
+and&nbsp;classes&nbsp;according&nbsp;to&nbsp;their&nbsp;docstrings.</tt></dd></dl>
+ <dl><dt><a name="-decorated"><strong>decorated</strong></a>(obj<font color="#909090">=None</font>)</dt><dd><tt>Returns&nbsp;a&nbsp;new&nbsp;decorated&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;created&nbsp;from&nbsp;obj,&nbsp;or&nbsp;None,&nbsp;if&nbsp;obj<br>
+cannot&nbsp;be&nbsp;decorated.</tt></dd></dl>
+ <dl><dt><a name="-decorator_from"><strong>decorator_from</strong></a>(magicstring)</dt><dd><tt>Takes&nbsp;a&nbsp;magic&nbsp;string,&nbsp;i.e.&nbsp;a&nbsp;list&nbsp;of&nbsp;comma-separated&nbsp;decorator&nbsp;names,<br>
+and&nbsp;returns&nbsp;a&nbsp;decorator&nbsp;class&nbsp;or&nbsp;None&nbsp;(if&nbsp;the&nbsp;string&nbsp;is&nbsp;not&nbsp;matched).</tt></dd></dl>
+ <dl><dt><a name="-get"><strong>get</strong></a>(magicstring<font color="#909090">='Decorator'</font>)</dt><dd><tt>List&nbsp;of&nbsp;recognized&nbsp;decorators</tt></dd></dl>
+ <dl><dt><a name="-magicstring"><strong>magicstring</strong></a>(docstring)</dt></dl>
+ <dl><dt><a name="-printerr"><strong>printerr</strong></a>(*args)</dt><dd><tt>For&nbsp;debugging&nbsp;purposes</tt></dd></dl>
+</td></tr></table><p>
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
+<tr bgcolor="#55aa55">
+<td colspan=3 valign=bottom>&nbsp;<br>
+<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
+
+<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
+<td width="100%"><strong>MAGICDOC</strong> = &lt;_sre.SRE_Pattern object&gt;<br>
+<strong>err</strong> = &lt;open file 'err', mode 'w'&gt;</td></tr></table>
+</body></html> \ No newline at end of file
diff --git a/pypers/pep318/working/tracing.py b/pypers/pep318/working/tracing.py
new file mode 100755
index 0000000..05f94b4
--- /dev/null
+++ b/pypers/pep318/working/tracing.py
@@ -0,0 +1,20 @@
+# tracing.py
+
+import customdec; customdec.enhance_classes("[Decorated]")
+
+class B(object):
+ def __init__(self):
+ "[tracedmethod]"
+ super(B,self).__init__()
+
+class D(object):
+ def __init__(self):
+ "[tracedmethod]"
+ super(D,self).__init__()
+
+class E(B,D):
+ def __init__(self):
+ "[tracedmethod]"
+ super(E,self).__init__()
+
+
diff --git a/pypers/pep318/x.py b/pypers/pep318/x.py
new file mode 100755
index 0000000..fb6f93d
--- /dev/null
+++ b/pypers/pep318/x.py
@@ -0,0 +1,17 @@
+"[Decorated]"
+
+import decorators,customdec; decorators.decorated()
+
+class desc(object):
+ def __get__(self,obj,cls):
+ print obj,cls
+
+class C(object):
+ def f(cls):
+ "[classmethod]"
+ print cls
+ g=desc()
+
+
+C.g
+C().g
diff --git a/pypers/pep318/x.txt b/pypers/pep318/x.txt
new file mode 100755
index 0000000..870e527
--- /dev/null
+++ b/pypers/pep318/x.txt
@@ -0,0 +1,7 @@
+>>> import customdec; customdec.enhance_classes()
+>>> class C:
+... "[Decorated,Logged]"
+... def f():
+... "[staticmethod]"
+... return 'it works!'
+<class C[DecoratedLogged]> created