105
<div class="contents topic">
106
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
105
<div class="contents topic" id="contents">
106
<p class="topic-title first">Contents</p>
107
107
<ul class="simple">
108
<li><a class="reference" href="#introduction" id="id3" name="id3">Introduction</a></li>
109
<li><a class="reference" href="#definitions" id="id4" name="id4">Definitions</a></li>
110
<li><a class="reference" href="#statement-of-the-problem" id="id5" name="id5">Statement of the problem</a></li>
111
<li><a class="reference" href="#the-solution" id="id6" name="id6">The solution</a></li>
112
<li><a class="reference" href="#a-trace-decorator" id="id7" name="id7">A <tt class="docutils literal"><span class="pre">trace</span></tt> decorator</a></li>
113
<li><a class="reference" href="#decorator-is-a-decorator" id="id8" name="id8"><tt class="docutils literal"><span class="pre">decorator</span></tt> is a decorator</a></li>
114
<li><a class="reference" href="#blocking" id="id9" name="id9"><tt class="docutils literal"><span class="pre">blocking</span></tt></a></li>
115
<li><a class="reference" href="#async" id="id10" name="id10"><tt class="docutils literal"><span class="pre">async</span></tt></a></li>
116
<li><a class="reference" href="#the-functionmaker-class" id="id11" name="id11">The <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class</a></li>
117
<li><a class="reference" href="#getting-the-source-code" id="id12" name="id12">Getting the source code</a></li>
118
<li><a class="reference" href="#dealing-with-third-party-decorators" id="id13" name="id13">Dealing with third party decorators</a></li>
119
<li><a class="reference" href="#caveats-and-limitations" id="id14" name="id14">Caveats and limitations</a></li>
120
<li><a class="reference" href="#compatibility-notes" id="id15" name="id15">Compatibility notes</a></li>
121
<li><a class="reference" href="#licence" id="id16" name="id16">LICENCE</a></li>
108
<li><a class="reference internal" href="#introduction" id="id3">Introduction</a></li>
109
<li><a class="reference internal" href="#definitions" id="id4">Definitions</a></li>
110
<li><a class="reference internal" href="#statement-of-the-problem" id="id5">Statement of the problem</a></li>
111
<li><a class="reference internal" href="#the-solution" id="id6">The solution</a></li>
112
<li><a class="reference internal" href="#a-trace-decorator" id="id7">A <tt class="docutils literal"><span class="pre">trace</span></tt> decorator</a></li>
113
<li><a class="reference internal" href="#decorator-is-a-decorator" id="id8"><tt class="docutils literal"><span class="pre">decorator</span></tt> is a decorator</a></li>
114
<li><a class="reference internal" href="#blocking" id="id9"><tt class="docutils literal"><span class="pre">blocking</span></tt></a></li>
115
<li><a class="reference internal" href="#async" id="id10"><tt class="docutils literal"><span class="pre">async</span></tt></a></li>
116
<li><a class="reference internal" href="#the-functionmaker-class" id="id11">The <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class</a></li>
117
<li><a class="reference internal" href="#getting-the-source-code" id="id12">Getting the source code</a></li>
118
<li><a class="reference internal" href="#dealing-with-third-party-decorators" id="id13">Dealing with third party decorators</a></li>
119
<li><a class="reference internal" href="#caveats-and-limitations" id="id14">Caveats and limitations</a></li>
120
<li><a class="reference internal" href="#compatibility-notes" id="id15">Compatibility notes</a></li>
121
<li><a class="reference internal" href="#licence" id="id16">LICENCE</a></li>
124
<div class="section">
125
<h1><a class="toc-backref" href="#id3" id="introduction" name="introduction">Introduction</a></h1>
124
<div class="section" id="introduction">
125
<h1><a class="toc-backref" href="#id3">Introduction</a></h1>
126
126
<p>Python decorators are an interesting example of why syntactic sugar
127
127
matters. In principle, their introduction in Python 2.4 changed
128
128
nothing, since they do not provide any new functionality which was not
431
<p>For the rest of this document, I will discuss examples of useful
432
decorators built on top of <tt class="docutils literal"><span class="pre">decorator</span></tt>.</p>
434
<div class="section">
435
<h1><a class="toc-backref" href="#id9" id="blocking" name="blocking"><tt class="docutils literal"><span class="pre">blocking</span></tt></a></h1>
430
<p>If you are using an old Python version (Python 2.4) the
431
<tt class="docutils literal"><span class="pre">decorator</span></tt> module provides a poor man replacement for
432
<tt class="docutils literal"><span class="pre">functools.partial</span></tt>.</p>
433
<p>There is also an easy way to create one-parameter factories of
434
decorators, based on the following
435
<tt class="docutils literal"><span class="pre">decorator_factory</span></tt> utility:</p>
436
<div class="codeblock python">
437
<div class="highlight"><pre><span class="k">def</span> <span class="nf">decorator_factory</span><span class="p">(</span><span class="n">decfac</span><span class="p">):</span> <span class="c"># partial is functools.partial</span>
438
<span class="s">"decorator_factory(decfac) returns a one-parameter family of decorators"</span>
439
<span class="k">return</span> <span class="n">partial</span><span class="p">(</span><span class="k">lambda</span> <span class="n">df</span><span class="p">,</span> <span class="n">param</span><span class="p">:</span> <span class="n">decorator</span><span class="p">(</span><span class="n">partial</span><span class="p">(</span><span class="n">df</span><span class="p">,</span> <span class="n">param</span><span class="p">)),</span> <span class="n">decfac</span><span class="p">)</span>
443
<p><tt class="docutils literal"><span class="pre">decorator_factory</span></tt> converts a function with signature
444
<tt class="docutils literal"><span class="pre">(param,</span> <span class="pre">func,</span> <span class="pre">*args,</span> <span class="pre">**kw)</span></tt> into a one-parameter family
445
of decorators. Suppose for instance you want to generated different
446
tracing generator, with different tracing messages.
447
Here is how to do it:</p>
448
<div class="codeblock python">
449
<div class="highlight"><pre><span class="o">>>></span> <span class="nd">@decorator_factory</span>
450
<span class="o">...</span> <span class="k">def</span> <span class="nf">trace_factory</span><span class="p">(</span><span class="n">message_template</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
451
<span class="o">...</span> <span class="n">name</span> <span class="o">=</span> <span class="n">f</span><span class="o">.</span><span class="n">func_name</span>
452
<span class="o">...</span> <span class="k">print</span> <span class="n">message_template</span> <span class="o">%</span> <span class="nb">locals</span><span class="p">()</span>
453
<span class="o">...</span> <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
457
<div class="codeblock python">
458
<div class="highlight"><pre><span class="o">>>></span> <span class="n">trace_factory</span>
459
<span class="o"><</span><span class="n">functools</span><span class="o">.</span><span class="n">partial</span> <span class="nb">object</span> <span class="n">at</span> <span class="mf">0</span><span class="n">x</span><span class="o">...></span>
461
<span class="o">>>></span> <span class="n">trace</span> <span class="o">=</span> <span class="n">trace_factory</span><span class="p">(</span><span class="s">'Calling </span><span class="si">%(name)s</span><span class="s"> with args </span><span class="si">%(args)s</span><span class="s"> '</span>
462
<span class="o">...</span> <span class="s">'and keywords </span><span class="si">%(kw)s</span><span class="s">'</span><span class="p">)</span>
466
<p>In this example the parameter (<tt class="docutils literal"><span class="pre">message_template</span></tt>) is
467
just a string, but in general it can be a tuple, a dictionary, or
468
a generic object, so there is no real restriction (for instance,
469
if you want to define a two-parameter family of decorators just
470
use a tuple with two arguments as parameter).
471
Here is an example of usage:</p>
472
<div class="codeblock python">
473
<div class="highlight"><pre><span class="o">>>></span> <span class="nd">@trace</span>
474
<span class="o">...</span> <span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span>
476
<span class="o">>>></span> <span class="n">func</span><span class="p">()</span>
477
<span class="n">Calling</span> <span class="n">func</span> <span class="k">with</span> <span class="n">args</span> <span class="p">()</span> <span class="ow">and</span> <span class="n">keywords</span> <span class="p">{}</span>
482
<div class="section" id="blocking">
483
<h1><a class="toc-backref" href="#id9"><tt class="docutils literal"><span class="pre">blocking</span></tt></a></h1>
436
484
<p>Sometimes one has to deal with blocking resources, such as <tt class="docutils literal"><span class="pre">stdin</span></tt>, and
437
485
sometimes it is best to have back a "busy" message than to block everything.
438
This behavior can be implemented with a suitable decorator:</p>
486
This behavior can be implemented with a suitable family of decorators,
487
where the parameter is the busy message:</p>
439
488
<div class="codeblock python">
440
<div class="highlight"><pre><span class="k">def</span> <span class="nf">blocking</span><span class="p">(</span><span class="n">not_avail</span><span class="o">=</span><span class="s">"Not Available"</span><span class="p">):</span>
441
<span class="k">def</span> <span class="nf">_blocking</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
489
<div class="highlight"><pre><span class="nd">@decorator_factory</span>
490
<span class="k">def</span> <span class="nf">blocking</span><span class="p">(</span><span class="n">not_avail</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span>
442
491
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">"thread"</span><span class="p">):</span> <span class="c"># no thread running</span>
443
492
<span class="k">def</span> <span class="nf">set_result</span><span class="p">():</span> <span class="n">f</span><span class="o">.</span><span class="n">result</span> <span class="o">=</span> <span class="n">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">)</span>
444
493
<span class="n">f</span><span class="o">.</span><span class="n">thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="bp">None</span><span class="p">,</span> <span class="n">set_result</span><span class="p">)</span>
603
648
['data1', 'data2']
606
<div class="section">
607
<h1><a class="toc-backref" href="#id11" id="the-functionmaker-class" name="the-functionmaker-class">The <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class</a></h1>
651
<div class="section" id="the-functionmaker-class">
652
<h1><a class="toc-backref" href="#id11">The <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class</a></h1>
608
653
<p>You may wonder about how the functionality of the <tt class="docutils literal"><span class="pre">decorator</span></tt> module
609
654
is implemented. The basic building block is
610
655
a <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class which is able to generate on the fly
611
656
functions with a given name and signature from a function template
612
657
passed as a string. Generally speaking, you should not need to
613
658
resort to <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> when writing ordinary decorators, but
614
it is handy in some circumstances. We will see an example in two
615
paragraphs, when implementing a custom decorator factory
616
(<tt class="docutils literal"><span class="pre">decorator_apply</span></tt>).</p>
617
<p>Notice that while I do not have plans
618
to change or remove the functionality provided in the
619
<tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class, I do not guarantee that it will stay
620
unchanged forever. For instance, right now I am using the traditional
621
string interpolation syntax for function templates, but Python 2.6
622
and Python 3.0 provide a newer interpolation syntax and I may use
623
the new syntax in the future.
624
On the other hand, the functionality provided by
625
<tt class="docutils literal"><span class="pre">decorator</span></tt> has been there from version 0.1 and it is guaranteed to
626
stay there forever.</p>
627
<p><tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> takes the name and the signature (as a string) of a
628
function in input, or a whole function. Then, it creates a new
629
function (actually a closure) from a function template (the function
630
template must begin with <tt class="docutils literal"><span class="pre">def</span></tt> with no comments before and you cannot
631
use a <tt class="docutils literal"><span class="pre">lambda</span></tt>) via its
632
<tt class="docutils literal"><span class="pre">.make</span></tt> method: the name and the signature of the resulting function
633
are determinated by the specified name and signature. For instance,
634
here is an example of how to restrict the signature of a function:</p>
659
it is handy in some circumstances. You will see an example shortly, in
660
the implementation of a cool decorator utility (<tt class="docutils literal"><span class="pre">decorator_apply</span></tt>).</p>
661
<p><tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> provides a <tt class="docutils literal"><span class="pre">.create</span></tt> classmethod which
662
takes as input the name, signature, and body of the function
663
we want to generate as well as the execution environment
664
were the function is generated by <tt class="docutils literal"><span class="pre">exec</span></tt>. Here is an example:</p>
635
665
<div class="codeblock python">
636
666
<div class="highlight"><pre><span class="o">>>></span> <span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span> <span class="c"># a function with a generic signature</span>
637
667
<span class="o">...</span> <span class="k">print</span> <span class="n">args</span><span class="p">,</span> <span class="n">kw</span>
639
<span class="o">>>></span> <span class="n">fun</span> <span class="o">=</span> <span class="n">FunctionMaker</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s">"f1"</span><span class="p">,</span> <span class="n">signature</span><span class="o">=</span><span class="s">"a,b"</span><span class="p">)</span>
640
<span class="o">>>></span> <span class="n">f1</span> <span class="o">=</span> <span class="n">fun</span><span class="o">.</span><span class="n">make</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
641
<span class="s">... def </span><span class="si">%(name)s</span><span class="s">(</span><span class="si">%(signature)s</span><span class="s">):</span>
642
<span class="s">... f(</span><span class="si">%(signature)s</span><span class="s">)'''</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">f</span><span class="o">=</span><span class="n">f</span><span class="p">))</span>
643
<span class="o">...</span>
669
<span class="o">>>></span> <span class="n">f1</span> <span class="o">=</span> <span class="n">FunctionMaker</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="s">'f1(a, b)'</span><span class="p">,</span> <span class="s">'f(a, b)'</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">f</span><span class="o">=</span><span class="n">f</span><span class="p">))</span>
644
670
<span class="o">>>></span> <span class="n">f1</span><span class="p">(</span><span class="mf">1</span><span class="p">,</span><span class="mf">2</span><span class="p">)</span>
645
671
<span class="p">(</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">)</span> <span class="p">{}</span>
649
<p>The dictionary passed in this example (<tt class="docutils literal"><span class="pre">dict(f=f)</span></tt>) is the
650
execution environment: <tt class="docutils literal"><span class="pre">FunctionMaker.make</span></tt> actually returns a
651
closure, and the original function <tt class="docutils literal"><span class="pre">f</span></tt> is a variable in the
653
<tt class="docutils literal"><span class="pre">FunctionMaker.make</span></tt> also accepts keyword arguments and such
675
<p>It is important to notice that the function body is interpolated
676
before being executed, so be careful with the <tt class="docutils literal"><span class="pre">%</span></tt> sign!</p>
677
<p><tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt> also accepts keyword arguments and such
654
678
arguments are attached to the resulting function. This is useful
655
679
if you want to set some function attributes, for instance the
656
680
docstring <tt class="docutils literal"><span class="pre">__doc__</span></tt>.</p>
657
681
<p>For debugging/introspection purposes it may be useful to see
658
682
the source code of the generated function; to do that, just
659
683
pass the flag <tt class="docutils literal"><span class="pre">addsource=True</span></tt> and a <tt class="docutils literal"><span class="pre">__source__</span></tt> attribute will
660
be added to the decorated function:</p>
684
be added to the generated function:</p>
661
685
<div class="codeblock python">
662
<div class="highlight"><pre><span class="o">>>></span> <span class="n">f1</span> <span class="o">=</span> <span class="n">fun</span><span class="o">.</span><span class="n">make</span><span class="p">(</span><span class="s">'''</span><span class="se">\</span>
663
<span class="s">... def </span><span class="si">%(name)s</span><span class="s">(</span><span class="si">%(signature)s</span><span class="s">):</span>
664
<span class="s">... f(</span><span class="si">%(signature)s</span><span class="s">)'''</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">f</span><span class="o">=</span><span class="n">f</span><span class="p">),</span> <span class="n">addsource</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
665
<span class="o">...</span>
686
<div class="highlight"><pre><span class="o">>>></span> <span class="n">f1</span> <span class="o">=</span> <span class="n">FunctionMaker</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
687
<span class="o">...</span> <span class="s">'f1(a, b)'</span><span class="p">,</span> <span class="s">'f(a, b)'</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">f</span><span class="o">=</span><span class="n">f</span><span class="p">),</span> <span class="n">addsource</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span>
666
688
<span class="o">>>></span> <span class="k">print</span> <span class="n">f1</span><span class="o">.</span><span class="n">__source__</span>
667
<span class="k">def</span> <span class="nf">f1</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">):</span>
668
<span class="n">f</span><span class="p">(</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="p">)</span>
689
<span class="k">def</span> <span class="nf">f1</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
690
<span class="n">f</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
669
691
<span class="o"><</span><span class="n">BLANKLINE</span><span class="o">></span>
695
<p><tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt> can take as first argument a string,
696
as in the examples before, or a function. This is the most common
697
usage, since typically you want to decorate a pre-existing
698
function. A framework author may want to use directly <tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt>
699
instead of <tt class="docutils literal"><span class="pre">decorator</span></tt>, since it gives you direct access to the body
700
of the generated function. For instance, suppose you want to instrument
701
the <tt class="docutils literal"><span class="pre">__init__</span></tt> methods of a set of classes, by preserving their
702
signature (such use case is not made up; this is done in SQAlchemy
703
and in other frameworks). When the first argument of <tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt>
704
is a function, a <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> object is instantiated internally,
705
with attributes <tt class="docutils literal"><span class="pre">args</span></tt>, <tt class="docutils literal"><span class="pre">varargs</span></tt>,
706
<tt class="docutils literal"><span class="pre">keywords</span></tt> and <tt class="docutils literal"><span class="pre">defaults</span></tt> which are the
707
the return values of the standard library function <tt class="docutils literal"><span class="pre">inspect.getargspec</span></tt>.
708
For each argument in the <tt class="docutils literal"><span class="pre">args</span></tt> (which is a list of strings containing
709
the names of the mandatory arguments) an attribute <tt class="docutils literal"><span class="pre">arg0</span></tt>, <tt class="docutils literal"><span class="pre">arg1</span></tt>,
710
..., <tt class="docutils literal"><span class="pre">argN</span></tt> is also generated. Finally, there is a <tt class="docutils literal"><span class="pre">signature</span></tt>
711
attribute, a string with the signature of the original function.</p>
712
<p>Notice that while I do not have plans
713
to change or remove the functionality provided in the
714
<tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class, I do not guarantee that it will stay
715
unchanged forever. For instance, right now I am using the traditional
716
string interpolation syntax for function templates, but Python 2.6
717
and Python 3.0 provide a newer interpolation syntax and I may use
718
the new syntax in the future.
719
On the other hand, the functionality provided by
720
<tt class="docutils literal"><span class="pre">decorator</span></tt> has been there from version 0.1 and it is guaranteed to
721
stay there forever.</p>
674
<div class="section">
675
<h1><a class="toc-backref" href="#id12" id="getting-the-source-code" name="getting-the-source-code">Getting the source code</a></h1>
676
<p>Internally <tt class="docutils literal"><span class="pre">FunctionMaker.make</span></tt> uses <tt class="docutils literal"><span class="pre">exec</span></tt> to generate the
723
<div class="section" id="getting-the-source-code">
724
<h1><a class="toc-backref" href="#id12">Getting the source code</a></h1>
725
<p>Internally <tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt> uses <tt class="docutils literal"><span class="pre">exec</span></tt> to generate the
677
726
decorated function. Therefore
678
727
<tt class="docutils literal"><span class="pre">inspect.getsource</span></tt> will not work for decorated functions. That
679
728
means that the usual '??' trick in IPython will give you the (right on
750
801
pretty slick decorator that converts a tail-recursive function in an iterative
751
802
function. I have shamelessly stolen the basic idea from Kay Schluehr's recipe
752
803
in the Python Cookbook,
753
<a class="reference" href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691">http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691</a>.</p>
804
<a class="reference external" href="http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691">http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691</a>.</p>
754
805
<div class="codeblock python">
755
806
<div class="highlight"><pre><span class="k">class</span> <span class="nc">TailRecursive</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
756
807
<span class="sd">"""</span>
757
808
<span class="sd"> tail_recursive decorator based on Kay Schluehr's recipe</span>
758
809
<span class="sd"> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/496691</span>
810
<span class="sd"> with improvements by me and George Sakkis.</span>
759
811
<span class="sd"> """</span>
760
<span class="n">CONTINUE</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span> <span class="c"># sentinel</span>
762
813
<span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">):</span>
763
814
<span class="bp">self</span><span class="o">.</span><span class="n">func</span> <span class="o">=</span> <span class="n">func</span>
764
815
<span class="bp">self</span><span class="o">.</span><span class="n">firstcall</span> <span class="o">=</span> <span class="bp">True</span>
816
<span class="bp">self</span><span class="o">.</span><span class="n">CONTINUE</span> <span class="o">=</span> <span class="nb">object</span><span class="p">()</span> <span class="c"># sentinel</span>
766
818
<span class="k">def</span> <span class="nf">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwd</span><span class="p">):</span>
767
<span class="k">try</span><span class="p">:</span>
768
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">firstcall</span><span class="p">:</span> <span class="c"># start looping</span>
819
<span class="n">CONTINUE</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">CONTINUE</span>
820
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">firstcall</span><span class="p">:</span>
821
<span class="n">func</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">func</span>
769
822
<span class="bp">self</span><span class="o">.</span><span class="n">firstcall</span> <span class="o">=</span> <span class="bp">False</span>
823
<span class="k">try</span><span class="p">:</span>
770
824
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
771
<span class="n">result</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwd</span><span class="p">)</span>
772
<span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">CONTINUE</span><span class="p">:</span> <span class="c"># update arguments</span>
825
<span class="n">result</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwd</span><span class="p">)</span>
826
<span class="k">if</span> <span class="n">result</span> <span class="ow">is</span> <span class="n">CONTINUE</span><span class="p">:</span> <span class="c"># update arguments</span>
773
827
<span class="n">args</span><span class="p">,</span> <span class="n">kwd</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">argskwd</span>
774
828
<span class="k">else</span><span class="p">:</span> <span class="c"># last call</span>
775
<span class="k">break</span>
829
<span class="k">return</span> <span class="n">result</span>
830
<span class="k">finally</span><span class="p">:</span>
831
<span class="bp">self</span><span class="o">.</span><span class="n">firstcall</span> <span class="o">=</span> <span class="bp">True</span>
776
832
<span class="k">else</span><span class="p">:</span> <span class="c"># return the arguments of the tail call</span>
777
833
<span class="bp">self</span><span class="o">.</span><span class="n">argskwd</span> <span class="o">=</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwd</span>
778
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">CONTINUE</span>
779
<span class="k">except</span><span class="p">:</span> <span class="c"># reset and re-raise</span>
780
<span class="bp">self</span><span class="o">.</span><span class="n">firstcall</span> <span class="o">=</span> <span class="bp">True</span>
781
<span class="k">raise</span>
782
<span class="k">else</span><span class="p">:</span> <span class="c"># reset and exit</span>
783
<span class="bp">self</span><span class="o">.</span><span class="n">firstcall</span> <span class="o">=</span> <span class="bp">True</span>
784
<span class="k">return</span> <span class="n">result</span>
834
<span class="k">return</span> <span class="n">CONTINUE</span>
895
945
<p>At present, there is no clean way to avoid <tt class="docutils literal"><span class="pre">exec</span></tt>. A clean solution
896
946
would require to change the CPython implementation of functions and
897
947
add an hook to make it possible to change their signature directly.
898
That could happen in future versions of Python (see PEP <a class="reference" href="http://www.python.org/dev/peps/pep-0362">362</a>) and
948
That could happen in future versions of Python (see PEP <a class="reference external" href="http://www.python.org/dev/peps/pep-0362">362</a>) and
899
949
then the decorator module would become obsolete. However, at present,
900
even in Python 3.0 it is impossible to change the function signature
950
even in Python 3.1 it is impossible to change the function signature
901
951
directly, therefore the <tt class="docutils literal"><span class="pre">decorator</span></tt> module is still useful.
902
Actually, this is one of the main reasons why I am releasing version 3.0.</p>
952
Actually, this is one of the main reasons why I keep maintaining
953
the module and releasing new versions.</p>
903
954
<p>In the present implementation, decorators generated by <tt class="docutils literal"><span class="pre">decorator</span></tt>
904
955
can only be used on user-defined Python functions or methods, not on generic
905
956
callable objects, nor on built-in functions, due to limitations of the
906
<tt class="docutils literal"><span class="pre">inspect</span></tt> module in the standard library.</p>
957
<tt class="docutils literal"><span class="pre">inspect</span></tt> module in the standard library. Moreover, notice
958
that you can decorate a method, but only before if becomes a bound or unbound
959
method, i.e. inside the class.
960
Here is an example of valid decoration:</p>
961
<div class="codeblock python">
962
<div class="highlight"><pre><span class="o">>>></span> <span class="k">class</span> <span class="nc">C</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
963
<span class="o">...</span> <span class="nd">@trace</span>
964
<span class="o">...</span> <span class="k">def</span> <span class="nf">meth</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
965
<span class="o">...</span> <span class="k">pass</span>
969
<p>Here is an example of invalid decoration, when the decorator in
971
<div class="codeblock python">
972
<div class="highlight"><pre><span class="o">>>></span> <span class="k">class</span> <span class="nc">C</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
973
<span class="o">...</span> <span class="k">def</span> <span class="nf">meth</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
974
<span class="o">...</span> <span class="k">pass</span>
975
<span class="o">...</span>
976
<span class="o">>>></span> <span class="n">trace</span><span class="p">(</span><span class="n">C</span><span class="o">.</span><span class="n">meth</span><span class="p">)</span>
977
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
978
<span class="o">...</span>
979
<span class="ne">TypeError</span><span class="p">:</span> <span class="n">You</span> <span class="n">are</span> <span class="n">decorating</span> <span class="n">a</span> <span class="n">non</span> <span class="n">function</span><span class="p">:</span> <span class="o"><</span><span class="n">unbound</span> <span class="n">method</span> <span class="n">C</span><span class="o">.</span><span class="n">meth</span><span class="o">></span>
983
<p>The solution is to extract the inner function from the unbound method:</p>
984
<div class="codeblock python">
985
<div class="highlight"><pre><span class="o">>>></span> <span class="n">trace</span><span class="p">(</span><span class="n">C</span><span class="o">.</span><span class="n">meth</span><span class="o">.</span><span class="n">im_func</span><span class="p">)</span>
986
<span class="o"><</span><span class="n">function</span> <span class="n">meth</span> <span class="n">at</span> <span class="mf">0</span><span class="n">x</span><span class="o">...></span>
907
990
<p>There is a restriction on the names of the arguments: for instance,
908
991
if try to call an argument <tt class="docutils literal"><span class="pre">_call_</span></tt> or <tt class="docutils literal"><span class="pre">_func_</span></tt>
909
992
you will get a <tt class="docutils literal"><span class="pre">NameError</span></tt>:</p>
976
1062
is also supported - of course the examples requiring the <tt class="docutils literal"><span class="pre">with</span></tt>
977
1063
statement will not work there. Python 2.6 works fine, but if you
978
1064
run the examples here in the interactive interpreter
979
you will notice a couple of minor differences since
1065
you will notice a few differences since
980
1066
<tt class="docutils literal"><span class="pre">getargspec</span></tt> returns an <tt class="docutils literal"><span class="pre">ArgSpec</span></tt> namedtuple instead of a regular
981
tuple, and the string representation of a thread object returns a
982
thread identifier number. That means that running the file
1067
tuple. That means that running the file
983
1068
<tt class="docutils literal"><span class="pre">documentation.py</span></tt> under Python 2.5 will a few errors, but
984
1069
they are not serious. Python 3.0 is kind of supported too.
985
1070
Simply run the script <tt class="docutils literal"><span class="pre">2to3</span></tt> on the module
986
1071
<tt class="docutils literal"><span class="pre">decorator.py</span></tt> and you will get a version of the code running
987
1072
with Python 3.0 (at least, I did some simple checks and it seemed
988
to work). However there is no support for <a class="reference" href="http://www.python.org/dev/peps/pep-3107/">function annotations</a> yet
1073
to work). However there is no support for <a class="reference external" href="http://www.python.org/dev/peps/pep-3107/">function annotations</a> yet
989
1074
since it seems premature at this moment (most people are
990
1075
still using Python 2.5).</p>
992
<div class="section">
993
<h1><a class="toc-backref" href="#id16" id="licence" name="licence">LICENCE</a></h1>
1077
<div class="section" id="licence">
1078
<h1><a class="toc-backref" href="#id16">LICENCE</a></h1>
994
1079
<p>Redistribution and use in source and binary forms, with or without
995
1080
modification, are permitted provided that the following conditions are
997
1082
<pre class="literal-block">
1083
Copyright (c) 2005, Michele Simionato
1084
All rights reserved.
998
1086
Redistributions of source code must retain the above copyright
999
1087
notice, this list of conditions and the following disclaimer.
1000
1088
Redistributions in bytecode form must reproduce the above copyright