~ubuntu-branches/debian/squeeze/python-decorator/squeeze

« back to all changes in this revision

Viewing changes to decorator.egg-info/PKG-INFO

  • Committer: Bazaar Package Importer
  • Author(s): Oleksandr Moskalenko, Sandro Tosi
  • Date: 2009-09-21 21:57:40 UTC
  • mfrom: (1.1.4 upstream) (3.1.2 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090921215740-na96kqoqhud29tzt
* New upstream release.
* debian/docs: Removed documentation.txt.
* debian/copyright: Changed (C) to copyright and updated copyright years.
* debian/doc-base: Added a doc-base control file for registration of the
  documentation.
* debian/control:
  - Updated Standards-Version to 3.8.3.
  - Moved python-support build-deps to Build-Depends-Indep.
[Sandro Tosi]
* debian/control
  - switch Vcs-Browser field to viewsvn.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
Metadata-Version: 1.0
2
2
Name: decorator
3
 
Version: 3.0.0
 
3
Version: 3.1.2
4
4
Summary: Better living through Python with decorators
5
5
Home-page: http://pypi.python.org/pypi/decorator
6
6
Author: Michele Simionato
7
7
Author-email: michele.simionato@gmail.com
8
8
License: BSD License
9
 
Description: <?xml version="1.0" encoding="utf-8" ?>
 
9
Description: </pre><?xml version="1.0" encoding="utf-8" ?>
10
10
        <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
11
11
        <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
12
12
        <head>
13
13
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
14
 
        <meta name="generator" content="Docutils 0.4.1: http://docutils.sourceforge.net/" />
 
14
        <meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
15
15
        <title>The decorator module</title>
16
16
        <meta name="author" content="Michele Simionato" />
17
17
        <style type="text/css">
88
88
        <tbody valign="top">
89
89
        <tr><th class="docinfo-name">Author:</th>
90
90
        <td>Michele Simionato</td></tr>
91
 
        <tr class="field"><th class="docinfo-name">E-mail:</th><td class="field-body"><a class="reference" href="mailto:michele.simionato&#64;gmail.com">michele.simionato&#64;gmail.com</a></td>
 
91
        <tr class="field"><th class="docinfo-name">E-mail:</th><td class="field-body"><a class="reference external" href="mailto:michele.simionato&#64;gmail.com">michele.simionato&#64;gmail.com</a></td>
92
92
        </tr>
93
93
        <tr><th class="docinfo-name">Version:</th>
94
 
        <td>3.0.0 (2008-12-14)</td></tr>
 
94
        <td>3.1.1 (2009-08-25)</td></tr>
95
95
        <tr class="field"><th class="docinfo-name">Requires:</th><td class="field-body">Python 2.4+</td>
96
96
        </tr>
97
 
        <tr class="field"><th class="docinfo-name">Download page:</th><td class="field-body"><a class="reference" href="http://pypi.python.org/pypi/decorator">http://pypi.python.org/pypi/decorator</a></td>
 
97
        <tr class="field"><th class="docinfo-name">Download page:</th><td class="field-body"><a class="reference external" href="http://pypi.python.org/pypi/decorator/3.1.1">http://pypi.python.org/pypi/decorator/3.1.1</a></td>
98
98
        </tr>
99
99
        <tr class="field"><th class="docinfo-name">Installation:</th><td class="field-body"><tt class="docutils literal"><span class="pre">easy_install</span> <span class="pre">decorator</span></tt></td>
100
100
        </tr>
102
102
        </tr>
103
103
        </tbody>
104
104
        </table>
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>
122
122
        </ul>
123
123
        </div>
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
149
149
        discussed here in the <tt class="docutils literal"><span class="pre">documentation.py</span></tt> file, which contains
150
150
        this documentation in the form of doctests.</p>
151
151
        </div>
152
 
        <div class="section">
153
 
        <h1><a class="toc-backref" href="#id4" id="definitions" name="definitions">Definitions</a></h1>
 
152
        <div class="section" id="definitions">
 
153
        <h1><a class="toc-backref" href="#id4">Definitions</a></h1>
154
154
        <p>Technically speaking, any Python object which can be called with one argument
155
155
        can be used as  a decorator. However, this definition is somewhat too large
156
156
        to be really useful. It is more convenient to split the generic class of
175
175
        can accept functions with any signature. A simple example will clarify
176
176
        the issue.</p>
177
177
        </div>
178
 
        <div class="section">
179
 
        <h1><a class="toc-backref" href="#id5" id="statement-of-the-problem" name="statement-of-the-problem">Statement of the problem</a></h1>
 
178
        <div class="section" id="statement-of-the-problem">
 
179
        <h1><a class="toc-backref" href="#id5">Statement of the problem</a></h1>
180
180
        <p>A very common use case for decorators is the memoization of functions.
181
181
        A <tt class="docutils literal"><span class="pre">memoize</span></tt> decorator works by caching
182
182
        the result of the function call in a dictionary, so that the next time
183
183
        the function is called with the same input parameters the result is retrieved
184
184
        from the cache and not recomputed. There are many implementations of
185
 
        <tt class="docutils literal"><span class="pre">memoize</span></tt> in <a class="reference" href="http://www.python.org/moin/PythonDecoratorLibrary">http://www.python.org/moin/PythonDecoratorLibrary</a>,
 
185
        <tt class="docutils literal"><span class="pre">memoize</span></tt> in <a class="reference external" href="http://www.python.org/moin/PythonDecoratorLibrary">http://www.python.org/moin/PythonDecoratorLibrary</a>,
186
186
        but they do not preserve the signature.
187
187
        A simple implementation for Python 2.5 could be the following (notice
188
188
        that in general it is impossible to memoize correctly something
205
205
        </pre></div>
206
206
        
207
207
        </div>
208
 
        <p>Here we used the <a class="reference" href="http://www.python.org/doc/2.5.2/lib/module-functools.html">functools.update_wrapper</a> utility, which has
 
208
        <p>Here we used the <a class="reference external" href="http://www.python.org/doc/2.5.2/lib/module-functools.html">functools.update_wrapper</a> utility, which has
209
209
        been added in Python 2.5 expressly to simplify the definition of decorators
210
210
        (in older versions of Python you need to copy the function attributes
211
211
        <tt class="docutils literal"><span class="pre">__name__</span></tt>, <tt class="docutils literal"><span class="pre">__doc__</span></tt>, <tt class="docutils literal"><span class="pre">__module__</span></tt> and <tt class="docutils literal"><span class="pre">__dict__</span></tt>
228
228
        but the decorated function takes any number of arguments and
229
229
        keyword arguments:</p>
230
230
        <div class="codeblock python">
231
 
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="k">from</span> <span class="nn">inspect</span> <span class="k">import</span> <span class="n">getargspec</span>
 
231
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">inspect</span> <span class="kn">import</span> <span class="n">getargspec</span>
232
232
        <span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">f1</span><span class="p">)</span>
233
233
        <span class="p">([],</span> <span class="s">&#39;args&#39;</span><span class="p">,</span> <span class="s">&#39;kw&#39;</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
234
234
        </pre></div>
248
248
        
249
249
        </div>
250
250
        </div>
251
 
        <div class="section">
252
 
        <h1><a class="toc-backref" href="#id6" id="the-solution" name="the-solution">The solution</a></h1>
 
251
        <div class="section" id="the-solution">
 
252
        <h1><a class="toc-backref" href="#id6">The solution</a></h1>
253
253
        <p>The solution is to provide a generic factory of generators, which
254
254
        hides the complexity of making signature-preserving decorators
255
255
        from the application programmer. The <tt class="docutils literal"><span class="pre">decorator</span></tt> function in
256
256
        the <tt class="docutils literal"><span class="pre">decorator</span></tt> module is such a factory:</p>
257
257
        <div class="codeblock python">
258
 
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="k">from</span> <span class="nn">decorator</span> <span class="k">import</span> <span class="n">decorator</span>
 
258
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">decorator</span> <span class="kn">import</span> <span class="n">decorator</span>
259
259
        </pre></div>
260
260
        
261
261
        </div>
316
316
        
317
317
        </div>
318
318
        </div>
319
 
        <div class="section">
320
 
        <h1><a class="toc-backref" href="#id7" id="a-trace-decorator" name="a-trace-decorator">A <tt class="docutils literal"><span class="pre">trace</span></tt> decorator</a></h1>
 
319
        <div class="section" id="a-trace-decorator">
 
320
        <h1><a class="toc-backref" href="#id7">A <tt class="docutils literal"><span class="pre">trace</span></tt> decorator</a></h1>
321
321
        <p>As an additional example, here is how you can define a trivial
322
322
        <tt class="docutils literal"><span class="pre">trace</span></tt> decorator, which prints a message everytime the traced
323
323
        function is called:</p>
386
386
        <p>Notice that the support for exotic signatures has been deprecated
387
387
        in Python 2.6 and removed in Python 3.0.</p>
388
388
        </div>
389
 
        <div class="section">
390
 
        <h1><a class="toc-backref" href="#id8" id="decorator-is-a-decorator" name="decorator-is-a-decorator"><tt class="docutils literal"><span class="pre">decorator</span></tt> is a decorator</a></h1>
 
389
        <div class="section" id="decorator-is-a-decorator">
 
390
        <h1><a class="toc-backref" href="#id8"><tt class="docutils literal"><span class="pre">decorator</span></tt> is a decorator</a></h1>
391
391
        <p>It may be annoying to write a caller function (like the <tt class="docutils literal"><span class="pre">_trace</span></tt>
392
392
        function above) and then a trivial wrapper
393
393
        (<tt class="docutils literal"><span class="pre">def</span> <span class="pre">trace(f):</span> <span class="pre">return</span> <span class="pre">decorator(_trace,</span> <span class="pre">f)</span></tt>) every time. For this reason,
409
409
        </pre></div>
410
410
        
411
411
        </div>
412
 
        <p>and now <tt class="docutils literal"><span class="pre">trace</span></tt> will be a decorator. You
413
 
        can easily check that the signature has changed:</p>
 
412
        <p>and now <tt class="docutils literal"><span class="pre">trace</span></tt> will be a decorator. Actually <tt class="docutils literal"><span class="pre">trace</span></tt> is a <tt class="docutils literal"><span class="pre">partial</span></tt>
 
413
        object which can be used as a decorator:</p>
414
414
        <div class="codeblock python">
415
 
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">trace</span><span class="p">)</span>
416
 
        <span class="p">([</span><span class="s">&#39;f&#39;</span><span class="p">],</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
 
415
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">trace</span>
 
416
        <span class="o">&lt;</span><span class="n">function</span> <span class="n">trace</span> <span class="n">at</span> <span class="mf">0</span><span class="n">x</span><span class="o">...&gt;</span>
417
417
        </pre></div>
418
418
        
419
419
        </div>
420
 
        <p>Therefore now <tt class="docutils literal"><span class="pre">trace</span></tt> can be used as a decorator and
421
 
        the following will work:</p>
 
420
        <p>Here is an example of usage:</p>
422
421
        <div class="codeblock python">
423
422
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="nd">@trace</span>
424
423
        <span class="o">...</span> <span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span>
428
427
        </pre></div>
429
428
        
430
429
        </div>
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>
433
 
        </div>
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">&quot;decorator_factory(decfac) returns a one-parameter family of decorators&quot;</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>
 
440
        </pre></div>
 
441
        
 
442
        </div>
 
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">&gt;&gt;&gt;</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>
 
454
        </pre></div>
 
455
        
 
456
        </div>
 
457
        <div class="codeblock python">
 
458
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">trace_factory</span>
 
459
        <span class="o">&lt;</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">...&gt;</span>
 
460
        
 
461
        <span class="o">&gt;&gt;&gt;</span> <span class="n">trace</span> <span class="o">=</span> <span class="n">trace_factory</span><span class="p">(</span><span class="s">&#39;Calling </span><span class="si">%(name)s</span><span class="s"> with args </span><span class="si">%(args)s</span><span class="s"> &#39;</span>
 
462
        <span class="o">...</span>                        <span class="s">&#39;and keywords </span><span class="si">%(kw)s</span><span class="s">&#39;</span><span class="p">)</span>
 
463
        </pre></div>
 
464
        
 
465
        </div>
 
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">&gt;&gt;&gt;</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>
 
475
        
 
476
        <span class="o">&gt;&gt;&gt;</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>
 
478
        </pre></div>
 
479
        
 
480
        </div>
 
481
        </div>
 
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 &quot;busy&quot; 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">&quot;Not Available&quot;</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">&quot;thread&quot;</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>
449
498
        <span class="k">else</span><span class="p">:</span> <span class="c"># the thread is ended, return the stored result</span>
450
499
        <span class="k">del</span> <span class="n">f</span><span class="o">.</span><span class="n">thread</span>
451
500
        <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">result</span>
452
 
        <span class="k">return</span> <span class="n">decorator</span><span class="p">(</span><span class="n">_blocking</span><span class="p">)</span>
453
501
        </pre></div>
454
502
        
455
503
        </div>
456
 
        <p>(notice that without the help of <tt class="docutils literal"><span class="pre">decorator</span></tt>, an additional level of
457
 
        nesting would have been needed). This is actually an example
458
 
        of a one-parameter family of decorators.</p>
459
504
        <p>Functions decorated with <tt class="docutils literal"><span class="pre">blocking</span></tt> will return a busy message if
460
505
        the resource is unavailable, and the intended result if the resource is
461
506
        available. For instance:</p>
483
528
        
484
529
        </div>
485
530
        </div>
486
 
        <div class="section">
487
 
        <h1><a class="toc-backref" href="#id10" id="async" name="async"><tt class="docutils literal"><span class="pre">async</span></tt></a></h1>
 
531
        <div class="section" id="async">
 
532
        <h1><a class="toc-backref" href="#id10"><tt class="docutils literal"><span class="pre">async</span></tt></a></h1>
488
533
        <p>We have just seen an examples of a simple decorator factory,
489
534
        implemented as a function returning a decorator.
490
535
        For more complex situations, it is more
586
631
        be no synchronization problems since <tt class="docutils literal"><span class="pre">write</span></tt> is locked.</p>
587
632
        <pre class="doctest-block">
588
633
        &gt;&gt;&gt; write(&quot;data1&quot;)
589
 
        &lt;Thread(write-1, started)&gt;
 
634
        &lt;Thread(write-1, started...)&gt;
590
635
        </pre>
591
636
        <pre class="doctest-block">
592
637
        &gt;&gt;&gt; time.sleep(.1) # wait a bit, so we are sure data2 is written after data1
593
638
        </pre>
594
639
        <pre class="doctest-block">
595
640
        &gt;&gt;&gt; write(&quot;data2&quot;)
596
 
        &lt;Thread(write-2, started)&gt;
 
641
        &lt;Thread(write-2, started...)&gt;
597
642
        </pre>
598
643
        <pre class="doctest-block">
599
644
        &gt;&gt;&gt; time.sleep(2) # wait for the writers to complete
603
648
        ['data1', 'data2']
604
649
        </pre>
605
650
        </div>
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">&gt;&gt;&gt;</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>
638
668
        
639
 
        <span class="o">&gt;&gt;&gt;</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">&quot;f1&quot;</span><span class="p">,</span> <span class="n">signature</span><span class="o">=</span><span class="s">&quot;a,b&quot;</span><span class="p">)</span>
640
 
        <span class="o">&gt;&gt;&gt;</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">&#39;&#39;&#39;</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">)&#39;&#39;&#39;</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">&gt;&gt;&gt;</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">&#39;f1(a, b)&#39;</span><span class="p">,</span> <span class="s">&#39;f(a, b)&#39;</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">&gt;&gt;&gt;</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>
646
672
        </pre></div>
647
673
        
648
674
        </div>
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
652
 
        closure environment.
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">&gt;&gt;&gt;</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">&#39;&#39;&#39;</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">)&#39;&#39;&#39;</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">&gt;&gt;&gt;</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">&#39;f1(a, b)&#39;</span><span class="p">,</span> <span class="s">&#39;f(a, b)&#39;</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">&gt;&gt;&gt;</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">&lt;</span><span class="n">BLANKLINE</span><span class="o">&gt;</span>
670
692
        </pre></div>
671
693
        
672
694
        </div>
 
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>
673
722
        </div>
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
694
743
        <div class="highlight"><pre><span class="nd">@identity_dec</span>
695
744
        <span class="k">def</span> <span class="nf">example</span><span class="p">():</span> <span class="k">pass</span>
696
745
        
697
 
        <span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">getsource</span><span class="p">(</span><span class="n">example</span><span class="p">)</span>
 
746
        <span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">inspect</span><span class="o">.</span><span class="n">getsource</span><span class="p">(</span><span class="n">example</span><span class="p">)</span>
698
747
        <span class="k">def</span> <span class="nf">wrapper</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>
699
748
        <span class="k">return</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">kw</span><span class="p">)</span>
700
749
        <span class="o">&lt;</span><span class="n">BLANKLINE</span><span class="o">&gt;</span>
701
750
        </pre></div>
702
751
        
703
752
        </div>
704
 
        <p>(see bug report <a class="reference" href="http://bugs.python.org/issue1764286">1764286</a> for an explanation of what is happening).
 
753
        <p>(see bug report <a class="reference external" href="http://bugs.python.org/issue1764286">1764286</a> for an explanation of what is happening).
705
754
        Unfortunately the bug is still there, even in Python 2.6 and 3.0.
706
755
        There is however a workaround. The decorator module adds an
707
756
        attribute <tt class="docutils literal"><span class="pre">.undecorated</span></tt> to the decorated function, containing
709
758
        the source code is to call <tt class="docutils literal"><span class="pre">inspect.getsource</span></tt> on the
710
759
        undecorated function:</p>
711
760
        <div class="codeblock python">
712
 
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">getsource</span><span class="p">(</span><span class="n">factorial</span><span class="o">.</span><span class="n">undecorated</span><span class="p">)</span>
 
761
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">inspect</span><span class="o">.</span><span class="n">getsource</span><span class="p">(</span><span class="n">factorial</span><span class="o">.</span><span class="n">undecorated</span><span class="p">)</span>
713
762
        <span class="nd">@tail_recursive</span>
714
763
        <span class="k">def</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">acc</span><span class="o">=</span><span class="mf">1</span><span class="p">):</span>
715
764
        <span class="s">&quot;The good old factorial&quot;</span>
720
769
        
721
770
        </div>
722
771
        </div>
723
 
        <div class="section">
724
 
        <h1><a class="toc-backref" href="#id13" id="dealing-with-third-party-decorators" name="dealing-with-third-party-decorators">Dealing with third party decorators</a></h1>
 
772
        <div class="section" id="dealing-with-third-party-decorators">
 
773
        <h1><a class="toc-backref" href="#id13">Dealing with third party decorators</a></h1>
725
774
        <p>Sometimes you find on the net some cool decorator that you would
726
775
        like to include in your code. However, more often than not the cool
727
776
        decorator is not signature-preserving. Therefore you may want an easy way to
730
779
        <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> to implement that functionality as follows:</p>
731
780
        <div class="codeblock python">
732
781
        <div class="highlight"><pre><span class="k">def</span> <span class="nf">decorator_apply</span><span class="p">(</span><span class="n">dec</span><span class="p">,</span> <span class="n">func</span><span class="p">):</span>
733
 
        <span class="s">&quot;Decorate a function using a signature-non-preserving decorator&quot;</span>
734
 
        <span class="n">fun</span> <span class="o">=</span> <span class="n">FunctionMaker</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
735
 
        <span class="n">src</span> <span class="o">=</span> <span class="s">&#39;&#39;&#39;def </span><span class="si">%(name)s</span><span class="s">(</span><span class="si">%(signature)s</span><span class="s">):</span>
736
 
        <span class="s">    return decorated(</span><span class="si">%(signature)s</span><span class="s">)&#39;&#39;&#39;</span>
737
 
        <span class="k">return</span> <span class="n">fun</span><span class="o">.</span><span class="n">make</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="n">decorated</span><span class="o">=</span><span class="n">dec</span><span class="p">(</span><span class="n">func</span><span class="p">)),</span> <span class="n">undecorated</span><span class="o">=</span><span class="n">func</span><span class="p">)</span>
 
782
        <span class="sd">&quot;&quot;&quot;</span>
 
783
        <span class="sd">    Decorate a function by preserving the signature even if dec</span>
 
784
        <span class="sd">    is not a signature-preserving decorator.</span>
 
785
        <span class="sd">    &quot;&quot;&quot;</span>
 
786
        <span class="k">return</span> <span class="n">FunctionMaker</span><span class="o">.</span><span class="n">create</span><span class="p">(</span>
 
787
        <span class="n">func</span><span class="p">,</span> <span class="s">&#39;return decorated(</span><span class="si">%(signature)s</span><span class="s">)&#39;</span><span class="p">,</span>
 
788
        <span class="nb">dict</span><span class="p">(</span><span class="n">decorated</span><span class="o">=</span><span class="n">dec</span><span class="p">(</span><span class="n">func</span><span class="p">)),</span> <span class="n">undecorated</span><span class="o">=</span><span class="n">func</span><span class="p">)</span>
738
789
        </pre></div>
739
790
        
740
791
        </div>
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">&quot;&quot;&quot;</span>
757
808
        <span class="sd">    tail_recursive decorator based on Kay Schluehr&#39;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">    &quot;&quot;&quot;</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>
761
812
        
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>
765
817
        
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>
785
835
        </pre></div>
786
836
        
787
837
        </div>
825
875
        making a recursive call, or returns directly the result of a recursive
826
876
        call).</p>
827
877
        </div>
828
 
        <div class="section">
829
 
        <h1><a class="toc-backref" href="#id14" id="caveats-and-limitations" name="caveats-and-limitations">Caveats and limitations</a></h1>
 
878
        <div class="section" id="caveats-and-limitations">
 
879
        <h1><a class="toc-backref" href="#id14">Caveats and limitations</a></h1>
830
880
        <p>The first thing you should be aware of, it the fact that decorators
831
881
        have a performance penalty.
832
882
        The worse case is shown by the following example:</p>
874
924
        function is decorated the traceback will be longer:</p>
875
925
        <div class="codeblock python">
876
926
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">f</span><span class="p">()</span>
877
 
        <span class="n">calling</span> <span class="n">f</span> <span class="k">with</span> <span class="n">args</span> <span class="p">(),</span> <span class="p">{}</span>
878
927
        <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>
879
 
        <span class="n">File</span> <span class="s">&quot;&lt;stdin&gt;&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mf">1</span><span class="p">,</span> <span class="ow">in</span> <span class="o">&lt;</span><span class="n">module</span><span class="o">&gt;</span>
 
928
        <span class="o">...</span>
880
929
        <span class="n">File</span> <span class="s">&quot;&lt;string&gt;&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mf">2</span><span class="p">,</span> <span class="ow">in</span> <span class="n">f</span>
881
 
        <span class="n">File</span> <span class="s">&quot;documentation.py&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mf">799</span><span class="p">,</span> <span class="ow">in</span> <span class="n">_trace</span>
 
930
        <span class="n">File</span> <span class="s">&quot;&lt;doctest __main__[18]&gt;&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mf">4</span><span class="p">,</span> <span class="ow">in</span> <span class="n">trace</span>
882
931
        <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>
883
 
        <span class="n">File</span> <span class="s">&quot;&lt;stdin&gt;&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mf">3</span><span class="p">,</span> <span class="ow">in</span> <span class="n">f</span>
 
932
        <span class="n">File</span> <span class="s">&quot;&lt;doctest __main__[47]&gt;&quot;</span><span class="p">,</span> <span class="n">line</span> <span class="mf">3</span><span class="p">,</span> <span class="ow">in</span> <span class="n">f</span>
 
933
        <span class="mf">1</span><span class="o">/</span><span class="mf">0</span>
884
934
        <span class="ne">ZeroDivisionError</span><span class="p">:</span> <span class="n">integer</span> <span class="n">division</span> <span class="ow">or</span> <span class="n">modulo</span> <span class="n">by</span> <span class="n">zero</span>
885
935
        </pre></div>
886
936
        
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">&gt;&gt;&gt;</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>
 
966
        </pre></div>
 
967
        
 
968
        </div>
 
969
        <p>Here is an example of invalid decoration, when the decorator in
 
970
        called too late:</p>
 
971
        <div class="codeblock python">
 
972
        <div class="highlight"><pre><span class="o">&gt;&gt;&gt;</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">&gt;&gt;&gt;</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">&lt;</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">&gt;</span>
 
980
        </pre></div>
 
981
        
 
982
        </div>
 
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">&gt;&gt;&gt;</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">&lt;</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">...&gt;</span>
 
987
        </pre></div>
 
988
        
 
989
        </div>
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>
938
1021
        
939
1022
        </div>
940
1023
        </div>
941
 
        <div class="section">
942
 
        <h1><a class="toc-backref" href="#id15" id="compatibility-notes" name="compatibility-notes">Compatibility notes</a></h1>
 
1024
        <div class="section" id="compatibility-notes">
 
1025
        <h1><a class="toc-backref" href="#id15">Compatibility notes</a></h1>
943
1026
        <p>Version 3.0 is a complete rewrite of the original implementation.
944
1027
        It is mostly compatible with the past, a part for a few differences.</p>
945
1028
        <p>First of all, the utilites <tt class="docutils literal"><span class="pre">get_info</span></tt> and <tt class="docutils literal"><span class="pre">new_wrapper</span></tt>, available
966
1049
        has been subsumed by <tt class="docutils literal"><span class="pre">decorator_apply</span></tt>
967
1050
        and the other use case can be managed with the <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt>.</p>
968
1051
        <p>Finally <tt class="docutils literal"><span class="pre">decorator</span></tt> cannot be used as a class decorator and the
969
 
        <a class="reference" href="http://www.phyast.pitt.edu/~micheles/python/documentation.html#class-decorators-and-decorator-factories">functionality introduced in version 2.3</a> has been removed. That
 
1052
        <a class="reference external" href="http://www.phyast.pitt.edu/~micheles/python/documentation.html#class-decorators-and-decorator-factories">functionality introduced in version 2.3</a> has been removed. That
970
1053
        means that in order to define decorator factories with classes you
971
 
        need to define the <tt class="docutils literal"><span class="pre">__call__</span></tt> method explicitly (no magic anymore).</p>
 
1054
        need to define the <tt class="docutils literal"><span class="pre">__call__</span></tt> method explicitly (no magic anymore).
 
1055
        Since there is
 
1056
        an easy way to define decorator factories by using <tt class="docutils literal"><span class="pre">decorator_factory</span></tt>,
 
1057
        there is less need to use classes to implement decorator factories.</p>
972
1058
        <p>All these changes should not cause any trouble, since they were
973
1059
        all rarely used features. Should you have any trouble, you can always
974
1060
        downgrade to the 2.3 version.</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>
991
1076
        </div>
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
996
1081
        met:</p>
997
1082
        <pre class="literal-block">
 
1083
        Copyright (c) 2005, Michele Simionato
 
1084
        All rights reserved.
 
1085
        
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
1022
1110
        </div>
1023
1111
        <div class="footer">
1024
1112
        <hr class="footer" />
1025
 
        <a class="reference" href="documentation.rst">View document source</a>.
1026
 
        Generated on: 2008-12-14 06:10 UTC.
1027
 
        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.
 
1113
        <a class="reference external" href="documentation.rst">View document source</a>.
 
1114
        Generated on: 2009-08-25 12:37 UTC.
 
1115
        Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
1028
1116
        
1029
1117
        </div>
1030
1118
        </body>
1031
1119
        </html>
1032
 
        
 
1120
        <pre>
1033
1121
Keywords: decorators generic utility
1034
1122
Platform: All
1035
1123
Classifier: Development Status :: 5 - Production/Stable