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

« back to all changes in this revision

Viewing changes to documentation.html

  • Committer: Bazaar Package Importer
  • Author(s): Piotr Ożarowski
  • Date: 2010-05-25 21:55:03 UTC
  • mfrom: (1.1.5 upstream)
  • Revision ID: james.westby@ubuntu.com-20100525215503-4xq1iyhjijh0t8o6
Tags: 3.2.0-1
* New upstream release
  - changelog no longer available
* python added to Build-Depends (clean rule needs it)
* debian/watch file points to PyPI now

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4
4
<head>
5
5
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6
 
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
 
6
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
7
7
<title>The decorator module</title>
8
8
<meta name="author" content="Michele Simionato" />
9
9
<style type="text/css">
73
73
</head>
74
74
<body>
75
75
<div class="document" id="the-decorator-module">
76
 
<h1 class="title">The <tt class="docutils literal"><span class="pre">decorator</span></tt> module</h1>
 
76
<h1 class="title">The <tt class="docutils literal">decorator</tt> module</h1>
77
77
<table class="docinfo" frame="void" rules="none">
78
78
<col class="docinfo-name" />
79
79
<col class="docinfo-content" />
83
83
<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>
84
84
</tr>
85
85
<tr><th class="docinfo-name">Version:</th>
86
 
<td>3.1.1 (2009-08-25)</td></tr>
 
86
<td>3.2.0 (2010-05-25)</td></tr>
87
87
<tr class="field"><th class="docinfo-name">Requires:</th><td class="field-body">Python 2.4+</td>
88
88
</tr>
89
 
<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>
 
89
<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.2.0">http://pypi.python.org/pypi/decorator/3.2.0</a></td>
90
90
</tr>
91
 
<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>
 
91
<tr class="field"><th class="docinfo-name">Installation:</th><td class="field-body"><tt class="docutils literal">easy_install decorator</tt></td>
92
92
</tr>
93
93
<tr class="field"><th class="docinfo-name">License:</th><td class="field-body">BSD license</td>
94
94
</tr>
101
101
<li><a class="reference internal" href="#definitions" id="id4">Definitions</a></li>
102
102
<li><a class="reference internal" href="#statement-of-the-problem" id="id5">Statement of the problem</a></li>
103
103
<li><a class="reference internal" href="#the-solution" id="id6">The solution</a></li>
104
 
<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>
105
 
<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>
106
 
<li><a class="reference internal" href="#blocking" id="id9"><tt class="docutils literal"><span class="pre">blocking</span></tt></a></li>
107
 
<li><a class="reference internal" href="#async" id="id10"><tt class="docutils literal"><span class="pre">async</span></tt></a></li>
108
 
<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>
 
104
<li><a class="reference internal" href="#a-trace-decorator" id="id7">A <tt class="docutils literal">trace</tt> decorator</a></li>
 
105
<li><a class="reference internal" href="#decorator-is-a-decorator" id="id8"><tt class="docutils literal">decorator</tt> is a decorator</a></li>
 
106
<li><a class="reference internal" href="#blocking" id="id9"><tt class="docutils literal">blocking</tt></a></li>
 
107
<li><a class="reference internal" href="#async" id="id10"><tt class="docutils literal">async</tt></a></li>
 
108
<li><a class="reference internal" href="#the-functionmaker-class" id="id11">The <tt class="docutils literal">FunctionMaker</tt> class</a></li>
109
109
<li><a class="reference internal" href="#getting-the-source-code" id="id12">Getting the source code</a></li>
110
110
<li><a class="reference internal" href="#dealing-with-third-party-decorators" id="id13">Dealing with third party decorators</a></li>
111
111
<li><a class="reference internal" href="#caveats-and-limitations" id="id14">Caveats and limitations</a></li>
132
132
some experience and it is not as easy as it could be. For instance,
133
133
typical implementations of decorators involve nested functions, and
134
134
we all know that flat is better than nested.</p>
135
 
<p>The aim of the <tt class="docutils literal"><span class="pre">decorator</span></tt> module it to simplify the usage of
 
135
<p>The aim of the <tt class="docutils literal">decorator</tt> module it to simplify the usage of
136
136
decorators for the average programmer, and to popularize decorators by
137
137
showing various non-trivial examples. Of course, as all techniques,
138
138
decorators can be abused (I have seen that) and you should not try to
139
139
solve every problem with a decorator, just because you can.</p>
140
140
<p>You may find the source code for all the examples
141
 
discussed here in the <tt class="docutils literal"><span class="pre">documentation.py</span></tt> file, which contains
 
141
discussed here in the <tt class="docutils literal">documentation.py</tt> file, which contains
142
142
this documentation in the form of doctests.</p>
143
143
</div>
144
144
<div class="section" id="definitions">
156
156
non-callable objects.</li>
157
157
</ul>
158
158
<p>Signature-changing decorators have their use: for instance the
159
 
builtin classes <tt class="docutils literal"><span class="pre">staticmethod</span></tt> and <tt class="docutils literal"><span class="pre">classmethod</span></tt> are in this
 
159
builtin classes <tt class="docutils literal">staticmethod</tt> and <tt class="docutils literal">classmethod</tt> are in this
160
160
group, since they take functions and return descriptor objects which
161
161
are not functions, nor callables.</p>
162
162
<p>However, signature-preserving decorators are more common and easier to
170
170
<div class="section" id="statement-of-the-problem">
171
171
<h1><a class="toc-backref" href="#id5">Statement of the problem</a></h1>
172
172
<p>A very common use case for decorators is the memoization of functions.
173
 
A <tt class="docutils literal"><span class="pre">memoize</span></tt> decorator works by caching
 
173
A <tt class="docutils literal">memoize</tt> decorator works by caching
174
174
the result of the function call in a dictionary, so that the next time
175
175
the function is called with the same input parameters the result is retrieved
176
176
from the cache and not recomputed. There are many implementations of
177
 
<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>,
 
177
<tt class="docutils literal">memoize</tt> in <a class="reference external" href="http://www.python.org/moin/PythonDecoratorLibrary">http://www.python.org/moin/PythonDecoratorLibrary</a>,
178
178
but they do not preserve the signature.
179
 
A simple implementation for Python 2.5 could be the following (notice
 
179
A simple implementation could be the following (notice
180
180
that in general it is impossible to memoize correctly something
181
181
that depends on non-hashable arguments):</p>
182
182
<div class="codeblock python">
183
 
<div class="highlight"><pre><span class="k">def</span> <span class="nf">memoize25</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
 
183
<div class="highlight"><pre><span class="k">def</span> <span class="nf">memoize_uw</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
184
184
    <span class="n">func</span><span class="o">.</span><span class="n">cache</span> <span class="o">=</span> <span class="p">{}</span>
185
185
    <span class="k">def</span> <span class="nf">memoize</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>
186
186
        <span class="k">if</span> <span class="n">kw</span><span class="p">:</span> <span class="c"># frozenset is used to ensure hashability</span>
200
200
<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
201
201
been added in Python 2.5 expressly to simplify the definition of decorators
202
202
(in older versions of Python you need to copy the function attributes
203
 
<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>
 
203
<tt class="docutils literal">__name__</tt>, <tt class="docutils literal">__doc__</tt>, <tt class="docutils literal">__module__</tt> and <tt class="docutils literal">__dict__</tt>
204
204
from the original function to the decorated function by hand).</p>
205
205
<p>The implementation above works in the sense that the decorator
206
206
can accept functions with generic signatures; unfortunately this
207
207
implementation does <em>not</em> define a signature-preserving decorator, since in
208
 
general <tt class="docutils literal"><span class="pre">memoize25</span></tt> returns a function with a
 
208
general <tt class="docutils literal">memoize_uw</tt> returns a function with a
209
209
<em>different signature</em> from the original function.</p>
210
210
<p>Consider for instance the following case:</p>
211
211
<div class="codeblock python">
212
 
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="nd">@memoize25</span>
 
212
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="nd">@memoize_uw</span>
213
213
<span class="o">...</span> <span class="k">def</span> <span class="nf">f1</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
214
214
<span class="o">...</span>     <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span> <span class="c"># simulate some long computation</span>
215
215
<span class="o">...</span>     <span class="k">return</span> <span class="n">x</span>
216
216
</pre></div>
217
217
 
218
218
</div>
219
 
<p>Here the original function takes a single argument named <tt class="docutils literal"><span class="pre">x</span></tt>,
 
219
<p>Here the original function takes a single argument named <tt class="docutils literal">x</tt>,
220
220
but the decorated function takes any number of arguments and
221
221
keyword arguments:</p>
222
222
<div class="codeblock python">
223
223
<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>
224
 
<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>
225
 
<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>
 
224
<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> <span class="c"># I am using Python 2.6+ here</span>
 
225
<span class="n">ArgSpec</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">[],</span> <span class="n">varargs</span><span class="o">=</span><span class="s">&#39;args&#39;</span><span class="p">,</span> <span class="n">keywords</span><span class="o">=</span><span class="s">&#39;kw&#39;</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
226
226
</pre></div>
227
227
 
228
228
</div>
229
229
<p>This means that introspection tools such as pydoc will give
230
 
wrong informations about the signature of <tt class="docutils literal"><span class="pre">f1</span></tt>. This is pretty bad:
 
230
wrong informations about the signature of <tt class="docutils literal">f1</tt>. This is pretty bad:
231
231
pydoc will tell you that the function accepts a generic signature
232
 
<tt class="docutils literal"><span class="pre">*args</span></tt>, <tt class="docutils literal"><span class="pre">**kw</span></tt>, but when you try to call the function with more than an
 
232
<tt class="docutils literal">*args</tt>, <tt class="docutils literal">**kw</tt>, but when you try to call the function with more than an
233
233
argument, you will get an error:</p>
234
234
<div class="codeblock python">
235
235
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">f1</span><span class="p">(</span><span class="mf">0</span><span class="p">,</span> <span class="mf">1</span><span class="p">)</span>
244
244
<h1><a class="toc-backref" href="#id6">The solution</a></h1>
245
245
<p>The solution is to provide a generic factory of generators, which
246
246
hides the complexity of making signature-preserving decorators
247
 
from the application programmer. The <tt class="docutils literal"><span class="pre">decorator</span></tt> function in
248
 
the <tt class="docutils literal"><span class="pre">decorator</span></tt> module is such a factory:</p>
 
247
from the application programmer. The <tt class="docutils literal">decorator</tt> function in
 
248
the <tt class="docutils literal">decorator</tt> module is such a factory:</p>
249
249
<div class="codeblock python">
250
250
<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>
251
251
</pre></div>
252
252
 
253
253
</div>
254
 
<p><tt class="docutils literal"><span class="pre">decorator</span></tt> takes two arguments, a caller function describing the
 
254
<p><tt class="docutils literal">decorator</tt> takes two arguments, a caller function describing the
255
255
functionality of the decorator and a function to be decorated; it
256
256
returns the decorated function. The caller function must have
257
 
signature <tt class="docutils literal"><span class="pre">(f,</span> <span class="pre">*args,</span> <span class="pre">**kw)</span></tt> and it must call the original function <tt class="docutils literal"><span class="pre">f</span></tt>
258
 
with arguments <tt class="docutils literal"><span class="pre">args</span></tt> and <tt class="docutils literal"><span class="pre">kw</span></tt>, implementing the wanted capability,
 
257
signature <tt class="docutils literal">(f, *args, **kw)</tt> and it must call the original function <tt class="docutils literal">f</tt>
 
258
with arguments <tt class="docutils literal">args</tt> and <tt class="docutils literal">kw</tt>, implementing the wanted capability,
259
259
i.e. memoization in this case:</p>
260
260
<div class="codeblock python">
261
261
<div class="highlight"><pre><span class="k">def</span> <span class="nf">_memoize</span><span class="p">(</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>
280
280
</pre></div>
281
281
 
282
282
</div>
283
 
<p>The difference with respect to the Python 2.5 approach, which is based
 
283
<p>The difference with respect to the <tt class="docutils literal">memoize_uw</tt> approach, which is based
284
284
on nested functions, is that the decorator module forces you to lift
285
285
the inner function at the outer level (<em>flat is better than nested</em>).
286
286
Moreover, you are forced to pass explicitly the function you want to
300
300
</pre></div>
301
301
 
302
302
</div>
303
 
<p>The signature of <tt class="docutils literal"><span class="pre">heavy_computation</span></tt> is the one you would expect:</p>
 
303
<p>The signature of <tt class="docutils literal">heavy_computation</tt> is the one you would expect:</p>
304
304
<div class="codeblock python">
305
305
<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">heavy_computation</span><span class="p">)</span>
306
 
<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>
 
306
<span class="n">ArgSpec</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">[],</span> <span class="n">varargs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">keywords</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
307
307
</pre></div>
308
308
 
309
309
</div>
310
310
</div>
311
311
<div class="section" id="a-trace-decorator">
312
 
<h1><a class="toc-backref" href="#id7">A <tt class="docutils literal"><span class="pre">trace</span></tt> decorator</a></h1>
 
312
<h1><a class="toc-backref" href="#id7">A <tt class="docutils literal">trace</tt> decorator</a></h1>
313
313
<p>As an additional example, here is how you can define a trivial
314
 
<tt class="docutils literal"><span class="pre">trace</span></tt> decorator, which prints a message everytime the traced
 
314
<tt class="docutils literal">trace</tt> decorator, which prints a message everytime the traced
315
315
function is called:</p>
316
316
<div class="codeblock python">
317
317
<div class="highlight"><pre><span class="k">def</span> <span class="nf">_trace</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>
334
334
</pre></div>
335
335
 
336
336
</div>
337
 
<p>It is immediate to verify that <tt class="docutils literal"><span class="pre">f1</span></tt> works</p>
 
337
<p>It is immediate to verify that <tt class="docutils literal">f1</tt> works</p>
338
338
<div class="codeblock python">
339
339
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">f1</span><span class="p">(</span><span class="mf">0</span><span class="p">)</span>
340
340
<span class="n">calling</span> <span class="n">f1</span> <span class="k">with</span> <span class="n">args</span> <span class="p">(</span><span class="mf">0</span><span class="p">,),</span> <span class="p">{}</span>
344
344
<p>and it that it has the correct signature:</p>
345
345
<div class="codeblock python">
346
346
<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">f1</span><span class="p">)</span>
347
 
<span class="p">([</span><span class="s">&#39;x&#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>
 
347
<span class="n">ArgSpec</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;x&#39;</span><span class="p">],</span> <span class="n">varargs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">keywords</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
348
348
</pre></div>
349
349
 
350
350
</div>
358
358
<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="mf">0</span><span class="p">,</span> <span class="mf">3</span><span class="p">,</span> <span class="mf">2</span><span class="p">),</span> <span class="p">{}</span>
359
359
 
360
360
<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
361
 
<span class="p">([</span><span class="s">&#39;x&#39;</span><span class="p">,</span> <span class="s">&#39;y&#39;</span><span class="p">,</span> <span class="s">&#39;z&#39;</span><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="p">(</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">))</span>
 
361
<span class="n">ArgSpec</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">[</span><span class="s">&#39;x&#39;</span><span class="p">,</span> <span class="s">&#39;y&#39;</span><span class="p">,</span> <span class="s">&#39;z&#39;</span><span class="p">],</span> <span class="n">varargs</span><span class="o">=</span><span class="s">&#39;args&#39;</span><span class="p">,</span> <span class="n">keywords</span><span class="o">=</span><span class="s">&#39;kw&#39;</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">(</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">))</span>
362
362
</pre></div>
363
363
 
364
364
</div>
368
368
<span class="o">...</span> <span class="k">def</span> <span class="nf">exotic_signature</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="o">=</span><span class="p">(</span><span class="mf">1</span><span class="p">,</span><span class="mf">2</span><span class="p">)):</span> <span class="k">return</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span>
369
369
 
370
370
<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">getargspec</span><span class="p">(</span><span class="n">exotic_signature</span><span class="p">)</span>
371
 
<span class="p">([[</span><span class="s">&#39;x&#39;</span><span class="p">,</span> <span class="s">&#39;y&#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="p">((</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">),))</span>
 
371
<span class="n">ArgSpec</span><span class="p">(</span><span class="n">args</span><span class="o">=</span><span class="p">[[</span><span class="s">&#39;x&#39;</span><span class="p">,</span> <span class="s">&#39;y&#39;</span><span class="p">]],</span> <span class="n">varargs</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">keywords</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="p">((</span><span class="mf">1</span><span class="p">,</span> <span class="mf">2</span><span class="p">),))</span>
372
372
<span class="o">&gt;&gt;&gt;</span> <span class="n">exotic_signature</span><span class="p">()</span>
373
373
<span class="n">calling</span> <span class="n">exotic_signature</span> <span class="k">with</span> <span class="n">args</span> <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>
374
374
<span class="mf">3</span>
379
379
in Python 2.6 and removed in Python 3.0.</p>
380
380
</div>
381
381
<div class="section" id="decorator-is-a-decorator">
382
 
<h1><a class="toc-backref" href="#id8"><tt class="docutils literal"><span class="pre">decorator</span></tt> is a decorator</a></h1>
383
 
<p>It may be annoying to write a caller function (like the <tt class="docutils literal"><span class="pre">_trace</span></tt>
 
382
<h1><a class="toc-backref" href="#id8"><tt class="docutils literal">decorator</tt> is a decorator</a></h1>
 
383
<p>It may be annoying to write a caller function (like the <tt class="docutils literal">_trace</tt>
384
384
function above) and then a trivial wrapper
385
 
(<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,
386
 
the <tt class="docutils literal"><span class="pre">decorator</span></tt> module provides an easy shortcut to convert
 
385
(<tt class="docutils literal">def trace(f): return decorator(_trace, f)</tt>) every time. For this reason,
 
386
the <tt class="docutils literal">decorator</tt> module provides an easy shortcut to convert
387
387
the caller function into a signature-preserving decorator:
388
 
you can just call <tt class="docutils literal"><span class="pre">decorator</span></tt> with a single argument.
389
 
In our example you can just write <tt class="docutils literal"><span class="pre">trace</span> <span class="pre">=</span> <span class="pre">decorator(_trace)</span></tt>.
390
 
The <tt class="docutils literal"><span class="pre">decorator</span></tt> function can also be used as a signature-changing
391
 
decorator, just as <tt class="docutils literal"><span class="pre">classmethod</span></tt> and <tt class="docutils literal"><span class="pre">staticmethod</span></tt>.
392
 
However, <tt class="docutils literal"><span class="pre">classmethod</span></tt> and <tt class="docutils literal"><span class="pre">staticmethod</span></tt> return generic
393
 
objects which are not callable, while <tt class="docutils literal"><span class="pre">decorator</span></tt> returns
 
388
you can just call <tt class="docutils literal">decorator</tt> with a single argument.
 
389
In our example you can just write <tt class="docutils literal">trace = decorator(_trace)</tt>.
 
390
The <tt class="docutils literal">decorator</tt> function can also be used as a signature-changing
 
391
decorator, just as <tt class="docutils literal">classmethod</tt> and <tt class="docutils literal">staticmethod</tt>.
 
392
However, <tt class="docutils literal">classmethod</tt> and <tt class="docutils literal">staticmethod</tt> return generic
 
393
objects which are not callable, while <tt class="docutils literal">decorator</tt> returns
394
394
signature-preserving decorators, i.e. functions of a single argument.
395
395
For instance, you can write directly</p>
396
396
<div class="codeblock python">
401
401
</pre></div>
402
402
 
403
403
</div>
404
 
<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>
 
404
<p>and now <tt class="docutils literal">trace</tt> will be a decorator. Actually <tt class="docutils literal">trace</tt> is a <tt class="docutils literal">partial</tt>
405
405
object which can be used as a decorator:</p>
406
406
<div class="codeblock python">
407
407
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">trace</span>
420
420
 
421
421
</div>
422
422
<p>If you are using an old Python version (Python 2.4) the
423
 
<tt class="docutils literal"><span class="pre">decorator</span></tt> module provides a poor man replacement for
424
 
<tt class="docutils literal"><span class="pre">functools.partial</span></tt>.</p>
425
 
<p>There is also an easy way to create one-parameter factories of
426
 
decorators, based on the following
427
 
<tt class="docutils literal"><span class="pre">decorator_factory</span></tt> utility:</p>
428
 
<div class="codeblock python">
429
 
<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>
430
 
    <span class="s">&quot;decorator_factory(decfac) returns a one-parameter family of decorators&quot;</span>
431
 
    <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>
432
 
</pre></div>
433
 
 
434
 
</div>
435
 
<p><tt class="docutils literal"><span class="pre">decorator_factory</span></tt> converts a function with signature
436
 
<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
437
 
of decorators. Suppose for instance you want to generated different
438
 
tracing generator, with different tracing messages.
439
 
Here is how to do it:</p>
440
 
<div class="codeblock python">
441
 
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="nd">@decorator_factory</span>
442
 
<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>
443
 
<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>
444
 
<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>
445
 
<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>
446
 
</pre></div>
447
 
 
448
 
</div>
449
 
<div class="codeblock python">
450
 
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">trace_factory</span>
451
 
<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>
452
 
 
453
 
<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>
454
 
<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>
455
 
</pre></div>
456
 
 
457
 
</div>
458
 
<p>In this example the parameter (<tt class="docutils literal"><span class="pre">message_template</span></tt>) is
459
 
just a string, but in general it can be a tuple, a dictionary, or
460
 
a generic object, so there is no real restriction (for instance,
461
 
if you want to define a two-parameter family of decorators just
462
 
use a tuple with two arguments as parameter).
463
 
Here is an example of usage:</p>
464
 
<div class="codeblock python">
465
 
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="nd">@trace</span>
466
 
<span class="o">...</span> <span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span>
467
 
 
468
 
<span class="o">&gt;&gt;&gt;</span> <span class="n">func</span><span class="p">()</span>
469
 
<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>
470
 
</pre></div>
471
 
 
472
 
</div>
 
423
<tt class="docutils literal">decorator</tt> module provides a poor man replacement for
 
424
<tt class="docutils literal">functools.partial</tt>.</p>
473
425
</div>
474
426
<div class="section" id="blocking">
475
 
<h1><a class="toc-backref" href="#id9"><tt class="docutils literal"><span class="pre">blocking</span></tt></a></h1>
476
 
<p>Sometimes one has to deal with blocking resources, such as <tt class="docutils literal"><span class="pre">stdin</span></tt>, and
 
427
<h1><a class="toc-backref" href="#id9"><tt class="docutils literal">blocking</tt></a></h1>
 
428
<p>Sometimes one has to deal with blocking resources, such as <tt class="docutils literal">stdin</tt>, and
477
429
sometimes it is best to have back a &quot;busy&quot; message than to block everything.
478
430
This behavior can be implemented with a suitable family of decorators,
479
431
where the parameter is the busy message:</p>
480
432
<div class="codeblock python">
481
 
<div class="highlight"><pre><span class="nd">@decorator_factory</span>
482
 
<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>
483
 
    <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>
484
 
        <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>
485
 
        <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>
486
 
        <span class="n">f</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
487
 
        <span class="k">return</span> <span class="n">not_avail</span>
488
 
    <span class="k">elif</span> <span class="n">f</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">isAlive</span><span class="p">():</span>
489
 
        <span class="k">return</span> <span class="n">not_avail</span>
490
 
    <span class="k">else</span><span class="p">:</span> <span class="c"># the thread is ended, return the stored result</span>
491
 
        <span class="k">del</span> <span class="n">f</span><span class="o">.</span><span class="n">thread</span>
492
 
        <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">result</span>
 
433
<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="p">):</span>
 
434
    <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>
 
435
        <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>
 
436
            <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>
 
437
            <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>
 
438
            <span class="n">f</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
 
439
            <span class="k">return</span> <span class="n">not_avail</span>
 
440
        <span class="k">elif</span> <span class="n">f</span><span class="o">.</span><span class="n">thread</span><span class="o">.</span><span class="n">isAlive</span><span class="p">():</span>
 
441
            <span class="k">return</span> <span class="n">not_avail</span>
 
442
        <span class="k">else</span><span class="p">:</span> <span class="c"># the thread is ended, return the stored result</span>
 
443
            <span class="k">del</span> <span class="n">f</span><span class="o">.</span><span class="n">thread</span>
 
444
            <span class="k">return</span> <span class="n">f</span><span class="o">.</span><span class="n">result</span>
 
445
    <span class="k">return</span> <span class="n">decorator</span><span class="p">(</span><span class="n">blocking</span><span class="p">)</span>
493
446
</pre></div>
494
447
 
495
448
</div>
496
 
<p>Functions decorated with <tt class="docutils literal"><span class="pre">blocking</span></tt> will return a busy message if
 
449
<p>Functions decorated with <tt class="docutils literal">blocking</tt> will return a busy message if
497
450
the resource is unavailable, and the intended result if the resource is
498
451
available. For instance:</p>
499
452
<div class="codeblock python">
521
474
</div>
522
475
</div>
523
476
<div class="section" id="async">
524
 
<h1><a class="toc-backref" href="#id10"><tt class="docutils literal"><span class="pre">async</span></tt></a></h1>
 
477
<h1><a class="toc-backref" href="#id10"><tt class="docutils literal">async</tt></a></h1>
525
478
<p>We have just seen an examples of a simple decorator factory,
526
479
implemented as a function returning a decorator.
527
480
For more complex situations, it is more
528
481
convenient to implement decorator factories as classes returning
529
482
callable objects that can be used as signature-preserving
530
483
decorators. The suggested pattern to do that is to introduce
531
 
a helper method <tt class="docutils literal"><span class="pre">call(self,</span> <span class="pre">func,</span> <span class="pre">*args,</span> <span class="pre">**kw)</span></tt> and to call
532
 
it in the <tt class="docutils literal"><span class="pre">__call__(self,</span> <span class="pre">func)</span></tt> method.</p>
 
484
a helper method <tt class="docutils literal">call(self, func, *args, **kw)</tt> and to call
 
485
it in the <tt class="docutils literal">__call__(self, func)</tt> method.</p>
533
486
<p>As an example, here I show a decorator
534
487
which is able to convert a blocking function into an asynchronous
535
488
function. The function, when called,
536
489
is executed in a separate thread. Moreover, it is possible to set
537
 
three callbacks <tt class="docutils literal"><span class="pre">on_success</span></tt>, <tt class="docutils literal"><span class="pre">on_failure</span></tt> and <tt class="docutils literal"><span class="pre">on_closing</span></tt>,
 
490
three callbacks <tt class="docutils literal">on_success</tt>, <tt class="docutils literal">on_failure</tt> and <tt class="docutils literal">on_closing</tt>,
538
491
to specify how to manage the function call.
539
492
The implementation is the following:</p>
540
493
<div class="codeblock python">
599
552
</div>
600
553
<p>The decorated function returns
601
554
the current execution thread, which can be stored and checked later, for
602
 
instance to verify that the thread <tt class="docutils literal"><span class="pre">.isAlive()</span></tt>.</p>
 
555
instance to verify that the thread <tt class="docutils literal">.isAlive()</tt>.</p>
603
556
<p>Here is an example of usage. Suppose one wants to write some data to
604
557
an external resource which can be accessed by a single user at once
605
558
(for instance a printer). Then the access to the writing function must
619
572
</pre></div>
620
573
 
621
574
</div>
622
 
<p>Each call to <tt class="docutils literal"><span class="pre">write</span></tt> will create a new writer thread, but there will
623
 
be no synchronization problems since <tt class="docutils literal"><span class="pre">write</span></tt> is locked.</p>
624
 
<pre class="doctest-block">
625
 
&gt;&gt;&gt; write(&quot;data1&quot;)
626
 
&lt;Thread(write-1, started...)&gt;
627
 
</pre>
628
 
<pre class="doctest-block">
629
 
&gt;&gt;&gt; time.sleep(.1) # wait a bit, so we are sure data2 is written after data1
630
 
</pre>
631
 
<pre class="doctest-block">
632
 
&gt;&gt;&gt; write(&quot;data2&quot;)
633
 
&lt;Thread(write-2, started...)&gt;
634
 
</pre>
635
 
<pre class="doctest-block">
636
 
&gt;&gt;&gt; time.sleep(2) # wait for the writers to complete
637
 
</pre>
638
 
<pre class="doctest-block">
639
 
&gt;&gt;&gt; print datalist
640
 
['data1', 'data2']
641
 
</pre>
 
575
<p>Each call to <tt class="docutils literal">write</tt> will create a new writer thread, but there will
 
576
be no synchronization problems since <tt class="docutils literal">write</tt> is locked.</p>
 
577
<div class="codeblock python">
 
578
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">write</span><span class="p">(</span><span class="s">&quot;data1&quot;</span><span class="p">)</span>
 
579
<span class="o">&lt;</span><span class="n">Thread</span><span class="p">(</span><span class="n">write</span><span class="o">-</span><span class="mf">1</span><span class="p">,</span> <span class="n">started</span><span class="o">...</span><span class="p">)</span><span class="o">&gt;</span>
 
580
 
 
581
<span class="o">&gt;&gt;&gt;</span> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="o">.</span><span class="mf">1</span><span class="p">)</span> <span class="c"># wait a bit, so we are sure data2 is written after data1</span>
 
582
 
 
583
<span class="o">&gt;&gt;&gt;</span> <span class="n">write</span><span class="p">(</span><span class="s">&quot;data2&quot;</span><span class="p">)</span>
 
584
<span class="o">&lt;</span><span class="n">Thread</span><span class="p">(</span><span class="n">write</span><span class="o">-</span><span class="mf">2</span><span class="p">,</span> <span class="n">started</span><span class="o">...</span><span class="p">)</span><span class="o">&gt;</span>
 
585
 
 
586
<span class="o">&gt;&gt;&gt;</span> <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">2</span><span class="p">)</span> <span class="c"># wait for the writers to complete</span>
 
587
 
 
588
<span class="o">&gt;&gt;&gt;</span> <span class="k">print</span> <span class="n">datalist</span>
 
589
<span class="p">[</span><span class="s">&#39;data1&#39;</span><span class="p">,</span> <span class="s">&#39;data2&#39;</span><span class="p">]</span>
 
590
</pre></div>
 
591
 
 
592
</div>
642
593
</div>
643
594
<div class="section" id="the-functionmaker-class">
644
 
<h1><a class="toc-backref" href="#id11">The <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class</a></h1>
645
 
<p>You may wonder about how the functionality of the <tt class="docutils literal"><span class="pre">decorator</span></tt> module
 
595
<h1><a class="toc-backref" href="#id11">The <tt class="docutils literal">FunctionMaker</tt> class</a></h1>
 
596
<p>You may wonder about how the functionality of the <tt class="docutils literal">decorator</tt> module
646
597
is implemented. The basic building block is
647
 
a <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class which is able to generate on the fly
 
598
a <tt class="docutils literal">FunctionMaker</tt> class which is able to generate on the fly
648
599
functions with a given name and signature from a function template
649
600
passed as a string. Generally speaking, you should not need to
650
 
resort to <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> when writing ordinary decorators, but
 
601
resort to <tt class="docutils literal">FunctionMaker</tt> when writing ordinary decorators, but
651
602
it is handy in some circumstances. You will see an example shortly, in
652
 
the implementation of a cool decorator utility (<tt class="docutils literal"><span class="pre">decorator_apply</span></tt>).</p>
653
 
<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
 
603
the implementation of a cool decorator utility (<tt class="docutils literal">decorator_apply</tt>).</p>
 
604
<p><tt class="docutils literal">FunctionMaker</tt> provides a <tt class="docutils literal">.create</tt> classmethod which
654
605
takes as input the name, signature, and body of the function
655
606
we want to generate as well as the execution environment
656
 
were the function is generated by <tt class="docutils literal"><span class="pre">exec</span></tt>. Here is an example:</p>
 
607
were the function is generated by <tt class="docutils literal">exec</tt>. Here is an example:</p>
657
608
<div class="codeblock python">
658
609
<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>
659
610
<span class="o">...</span>     <span class="k">print</span> <span class="n">args</span><span class="p">,</span> <span class="n">kw</span>
665
616
 
666
617
</div>
667
618
<p>It is important to notice that the function body is interpolated
668
 
before being executed, so be careful with the <tt class="docutils literal"><span class="pre">%</span></tt> sign!</p>
669
 
<p><tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt> also accepts keyword arguments and such
 
619
before being executed, so be careful with the <tt class="docutils literal">%</tt> sign!</p>
 
620
<p><tt class="docutils literal">FunctionMaker.create</tt> also accepts keyword arguments and such
670
621
arguments are attached to the resulting function. This is useful
671
622
if you want to set some function attributes, for instance the
672
 
docstring <tt class="docutils literal"><span class="pre">__doc__</span></tt>.</p>
 
623
docstring <tt class="docutils literal">__doc__</tt>.</p>
673
624
<p>For debugging/introspection purposes it may be useful to see
674
625
the source code of the generated function; to do that, just
675
 
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
 
626
pass the flag <tt class="docutils literal">addsource=True</tt> and a <tt class="docutils literal">__source__</tt> attribute will
676
627
be added to the generated function:</p>
677
628
<div class="codeblock python">
678
629
<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>
684
635
</pre></div>
685
636
 
686
637
</div>
687
 
<p><tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt> can take as first argument a string,
 
638
<p><tt class="docutils literal">FunctionMaker.create</tt> can take as first argument a string,
688
639
as in the examples before, or a function. This is the most common
689
640
usage, since typically you want to decorate a pre-existing
690
 
function. A framework author may want to use directly <tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt>
691
 
instead of <tt class="docutils literal"><span class="pre">decorator</span></tt>, since it gives you direct access to the body
 
641
function. A framework author may want to use directly <tt class="docutils literal">FunctionMaker.create</tt>
 
642
instead of <tt class="docutils literal">decorator</tt>, since it gives you direct access to the body
692
643
of the generated function. For instance, suppose you want to instrument
693
 
the <tt class="docutils literal"><span class="pre">__init__</span></tt> methods of a set of classes, by preserving their
 
644
the <tt class="docutils literal">__init__</tt> methods of a set of classes, by preserving their
694
645
signature (such use case is not made up; this is done in SQAlchemy
695
 
and in other frameworks). When the first argument of <tt class="docutils literal"><span class="pre">FunctionMaker.create</span></tt>
696
 
is a function, a <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> object is instantiated internally,
697
 
with attributes <tt class="docutils literal"><span class="pre">args</span></tt>, <tt class="docutils literal"><span class="pre">varargs</span></tt>,
698
 
<tt class="docutils literal"><span class="pre">keywords</span></tt> and <tt class="docutils literal"><span class="pre">defaults</span></tt> which are the
699
 
the return values of the standard library function <tt class="docutils literal"><span class="pre">inspect.getargspec</span></tt>.
700
 
For each argument in the <tt class="docutils literal"><span class="pre">args</span></tt> (which is a list of strings containing
701
 
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>,
702
 
..., <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>
 
646
and in other frameworks). When the first argument of <tt class="docutils literal">FunctionMaker.create</tt>
 
647
is a function, a <tt class="docutils literal">FunctionMaker</tt> object is instantiated internally,
 
648
with attributes <tt class="docutils literal">args</tt>, <tt class="docutils literal">varargs</tt>,
 
649
<tt class="docutils literal">keywords</tt> and <tt class="docutils literal">defaults</tt> which are the
 
650
the return values of the standard library function <tt class="docutils literal">inspect.getargspec</tt>.
 
651
For each argument in the <tt class="docutils literal">args</tt> (which is a list of strings containing
 
652
the names of the mandatory arguments) an attribute <tt class="docutils literal">arg0</tt>, <tt class="docutils literal">arg1</tt>,
 
653
..., <tt class="docutils literal">argN</tt> is also generated. Finally, there is a <tt class="docutils literal">signature</tt>
703
654
attribute, a string with the signature of the original function.</p>
704
655
<p>Notice that while I do not have plans
705
656
to change or remove the functionality provided in the
706
 
<tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> class, I do not guarantee that it will stay
 
657
<tt class="docutils literal">FunctionMaker</tt> class, I do not guarantee that it will stay
707
658
unchanged forever. For instance, right now I am using the traditional
708
659
string interpolation syntax for function templates, but Python 2.6
709
660
and Python 3.0 provide a newer interpolation syntax and I may use
710
661
the new syntax in the future.
711
662
On the other hand, the functionality provided by
712
 
<tt class="docutils literal"><span class="pre">decorator</span></tt> has been there from version 0.1 and it is guaranteed to
 
663
<tt class="docutils literal">decorator</tt> has been there from version 0.1 and it is guaranteed to
713
664
stay there forever.</p>
714
665
</div>
715
666
<div class="section" id="getting-the-source-code">
716
667
<h1><a class="toc-backref" href="#id12">Getting the source code</a></h1>
717
 
<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
 
668
<p>Internally <tt class="docutils literal">FunctionMaker.create</tt> uses <tt class="docutils literal">exec</tt> to generate the
718
669
decorated function. Therefore
719
 
<tt class="docutils literal"><span class="pre">inspect.getsource</span></tt> will not work for decorated functions. That
 
670
<tt class="docutils literal">inspect.getsource</tt> will not work for decorated functions. That
720
671
means that the usual '??' trick in IPython will give you the (right on
721
 
the spot) message <tt class="docutils literal"><span class="pre">Dynamically</span> <span class="pre">generated</span> <span class="pre">function.</span> <span class="pre">No</span> <span class="pre">source</span> <span class="pre">code</span>
722
 
<span class="pre">available</span></tt>.  In the past I have considered this acceptable, since
723
 
<tt class="docutils literal"><span class="pre">inspect.getsource</span></tt> does not really work even with regular
724
 
decorators. In that case <tt class="docutils literal"><span class="pre">inspect.getsource</span></tt> gives you the wrapper
 
672
the spot) message <tt class="docutils literal">Dynamically generated function. No source code
 
673
available</tt>.  In the past I have considered this acceptable, since
 
674
<tt class="docutils literal">inspect.getsource</tt> does not really work even with regular
 
675
decorators. In that case <tt class="docutils literal">inspect.getsource</tt> gives you the wrapper
725
676
source code which is probably not what you want:</p>
726
677
<div class="codeblock python">
727
678
<div class="highlight"><pre><span class="k">def</span> <span class="nf">identity_dec</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
745
696
<p>(see bug report <a class="reference external" href="http://bugs.python.org/issue1764286">1764286</a> for an explanation of what is happening).
746
697
Unfortunately the bug is still there, even in Python 2.6 and 3.0.
747
698
There is however a workaround. The decorator module adds an
748
 
attribute <tt class="docutils literal"><span class="pre">.undecorated</span></tt> to the decorated function, containing
 
699
attribute <tt class="docutils literal">.undecorated</tt> to the decorated function, containing
749
700
a reference to the original function. The easy way to get
750
 
the source code is to call <tt class="docutils literal"><span class="pre">inspect.getsource</span></tt> on the
 
701
the source code is to call <tt class="docutils literal">inspect.getsource</tt> on the
751
702
undecorated function:</p>
752
703
<div class="codeblock python">
753
704
<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>
767
718
like to include in your code. However, more often than not the cool
768
719
decorator is not signature-preserving. Therefore you may want an easy way to
769
720
upgrade third party decorators to signature-preserving decorators without
770
 
having to rewrite them in terms of <tt class="docutils literal"><span class="pre">decorator</span></tt>. You can use a
771
 
<tt class="docutils literal"><span class="pre">FunctionMaker</span></tt> to implement that functionality as follows:</p>
 
721
having to rewrite them in terms of <tt class="docutils literal">decorator</tt>. You can use a
 
722
<tt class="docutils literal">FunctionMaker</tt> to implement that functionality as follows:</p>
772
723
<div class="codeblock python">
773
724
<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>
774
725
    <span class="sd">&quot;&quot;&quot;</span>
781
732
</pre></div>
782
733
 
783
734
</div>
784
 
<p><tt class="docutils literal"><span class="pre">decorator_apply</span></tt> sets the attribute <tt class="docutils literal"><span class="pre">.undecorated</span></tt> of the generated
 
735
<p><tt class="docutils literal">decorator_apply</tt> sets the attribute <tt class="docutils literal">.undecorated</tt> of the generated
785
736
function to the original function, so that you can get the right
786
737
source code.</p>
787
 
<p>Notice that I am not providing this functionality in the <tt class="docutils literal"><span class="pre">decorator</span></tt>
 
738
<p>Notice that I am not providing this functionality in the <tt class="docutils literal">decorator</tt>
788
739
module directly since I think it is best to rewrite the decorator rather
789
740
than adding an additional level of indirection. However, practicality
790
 
beats purity, so you can add <tt class="docutils literal"><span class="pre">decorator_apply</span></tt> to your toolbox and
 
741
beats purity, so you can add <tt class="docutils literal">decorator_apply</tt> to your toolbox and
791
742
use it if you need to.</p>
792
 
<p>In order to give an example of usage of <tt class="docutils literal"><span class="pre">decorator_apply</span></tt>, I will show a
 
743
<p>In order to give an example of usage of <tt class="docutils literal">decorator_apply</tt>, I will show a
793
744
pretty slick decorator that converts a tail-recursive function in an iterative
794
745
function. I have shamelessly stolen the basic idea from Kay Schluehr's recipe
795
746
in the Python Cookbook,
853
804
</div>
854
805
<p>This decorator is pretty impressive, and should give you some food for
855
806
your mind ;) Notice that there is no recursion limit now, and you can
856
 
easily compute <tt class="docutils literal"><span class="pre">factorial(1001)</span></tt> or larger without filling the stack
 
807
easily compute <tt class="docutils literal">factorial(1001)</tt> or larger without filling the stack
857
808
frame. Notice also that the decorator will not work on functions which
858
809
are not tail recursive, such as the following</p>
859
810
<div class="codeblock python">
891
842
    pass
892
843
&quot; &quot;f()&quot;
893
844
</pre>
894
 
<p>On my MacBook, using the <tt class="docutils literal"><span class="pre">do_nothing</span></tt> decorator instead of the
 
845
<p>On my MacBook, using the <tt class="docutils literal">do_nothing</tt> decorator instead of the
895
846
plain function is more than three times slower:</p>
896
847
<pre class="literal-block">
897
848
$ bash performance.sh
899
850
1000000 loops, best of 3: 0.273 usec per loop
900
851
</pre>
901
852
<p>It should be noted that a real life function would probably do
902
 
something more useful than <tt class="docutils literal"><span class="pre">f</span></tt> here, and therefore in real life the
 
853
something more useful than <tt class="docutils literal">f</tt> here, and therefore in real life the
903
854
performance penalty could be completely negligible.  As always, the
904
855
only way to know if there is
905
856
a penalty in your specific use case is to measure it.</p>
912
863
</pre></div>
913
864
 
914
865
</div>
915
 
<p>Calling <tt class="docutils literal"><span class="pre">f()</span></tt> will give you a <tt class="docutils literal"><span class="pre">ZeroDivisionError</span></tt>, but since the
 
866
<p>Calling <tt class="docutils literal">f()</tt> will give you a <tt class="docutils literal">ZeroDivisionError</tt>, but since the
916
867
function is decorated the traceback will be longer:</p>
917
868
<div class="codeblock python">
918
869
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="n">f</span><span class="p">()</span>
927
878
</pre></div>
928
879
 
929
880
</div>
930
 
<p>You see here the inner call to the decorator <tt class="docutils literal"><span class="pre">trace</span></tt>, which calls
931
 
<tt class="docutils literal"><span class="pre">f(*args,</span> <span class="pre">**kw)</span></tt>, and a reference to  <tt class="docutils literal"><span class="pre">File</span> <span class="pre">&quot;&lt;string&gt;&quot;,</span> <span class="pre">line</span> <span class="pre">2,</span> <span class="pre">in</span> <span class="pre">f</span></tt>.
 
881
<p>You see here the inner call to the decorator <tt class="docutils literal">trace</tt>, which calls
 
882
<tt class="docutils literal"><span class="pre">f(*args,</span> **kw)</tt>, and a reference to  <tt class="docutils literal">File <span class="pre">&quot;&lt;string&gt;&quot;,</span> line 2, in f</tt>.
932
883
This latter reference is due to the fact that internally the decorator
933
 
module uses <tt class="docutils literal"><span class="pre">exec</span></tt> to generate the decorated function. Notice that
934
 
<tt class="docutils literal"><span class="pre">exec</span></tt> is <em>not</em> responsibile for the performance penalty, since is the
 
884
module uses <tt class="docutils literal">exec</tt> to generate the decorated function. Notice that
 
885
<tt class="docutils literal">exec</tt> is <em>not</em> responsibile for the performance penalty, since is the
935
886
called <em>only once</em> at function decoration time, and not every time
936
887
the decorated function is called.</p>
937
 
<p>At present, there is no clean way to avoid <tt class="docutils literal"><span class="pre">exec</span></tt>. A clean solution
 
888
<p>At present, there is no clean way to avoid <tt class="docutils literal">exec</tt>. A clean solution
938
889
would require to change the CPython implementation of functions and
939
890
add an hook to make it possible to change their signature directly.
940
891
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
941
892
then the decorator module would become obsolete. However, at present,
942
893
even in Python 3.1 it is impossible to change the function signature
943
 
directly, therefore the <tt class="docutils literal"><span class="pre">decorator</span></tt> module is still useful.
 
894
directly, therefore the <tt class="docutils literal">decorator</tt> module is still useful.
944
895
Actually, this is one of the main reasons why I keep maintaining
945
896
the module and releasing new versions.</p>
946
 
<p>In the present implementation, decorators generated by <tt class="docutils literal"><span class="pre">decorator</span></tt>
 
897
<p>In the present implementation, decorators generated by <tt class="docutils literal">decorator</tt>
947
898
can only be used on user-defined Python functions or methods, not on generic
948
899
callable objects, nor on built-in functions, due to limitations of the
949
 
<tt class="docutils literal"><span class="pre">inspect</span></tt> module in the standard library. Moreover, notice
 
900
<tt class="docutils literal">inspect</tt> module in the standard library. Moreover, notice
950
901
that you can decorate a method, but only before if becomes a bound or unbound
951
902
method, i.e. inside the class.
952
903
Here is an example of valid decoration:</p>
980
931
 
981
932
</div>
982
933
<p>There is a restriction on the names of the arguments: for instance,
983
 
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>
984
 
you will get a <tt class="docutils literal"><span class="pre">NameError</span></tt>:</p>
 
934
if try to call an argument <tt class="docutils literal">_call_</tt> or <tt class="docutils literal">_func_</tt>
 
935
you will get a <tt class="docutils literal">NameError</tt>:</p>
985
936
<div class="codeblock python">
986
937
<div class="highlight"><pre><span class="o">&gt;&gt;&gt;</span> <span class="nd">@trace</span>
987
938
<span class="o">...</span> <span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">_func_</span><span class="p">):</span> <span class="k">print</span> <span class="n">f</span>
996
947
</div>
997
948
<p>Finally, the implementation is such that the decorated function contains
998
949
a <em>copy</em> of the original function dictionary
999
 
(<tt class="docutils literal"><span class="pre">vars(decorated_f)</span> <span class="pre">is</span> <span class="pre">not</span> <span class="pre">vars(f)</span></tt>):</p>
 
950
(<tt class="docutils literal">vars(decorated_f) is not vars(f)</tt>):</p>
1000
951
<div class="codeblock python">
1001
952
<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="k">pass</span> <span class="c"># the original function</span>
1002
953
<span class="o">&gt;&gt;&gt;</span> <span class="n">f</span><span class="o">.</span><span class="n">attr1</span> <span class="o">=</span> <span class="s">&quot;something&quot;</span> <span class="c"># setting an attribute</span>
1015
966
</div>
1016
967
<div class="section" id="compatibility-notes">
1017
968
<h1><a class="toc-backref" href="#id15">Compatibility notes</a></h1>
1018
 
<p>Version 3.0 is a complete rewrite of the original implementation.
1019
 
It is mostly compatible with the past, a part for a few differences.</p>
1020
 
<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
1021
 
in the 2.X versions, have been deprecated and they will be removed
1022
 
in the future. For the moment, using them raises a <tt class="docutils literal"><span class="pre">DeprecationWarning</span></tt>.
1023
 
Incidentally, the functionality has been implemented through a
1024
 
decorator which makes a good example for this documentation:</p>
1025
 
<div class="codeblock python">
1026
 
<div class="highlight"><pre><span class="nd">@decorator</span>
1027
 
<span class="k">def</span> <span class="nf">deprecated</span><span class="p">(</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>
1028
 
    <span class="s">&quot;A decorator for deprecated functions&quot;</span>
1029
 
    <span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span>
1030
 
        <span class="p">(</span><span class="s">&#39;Calling the deprecated function </span><span class="si">%r</span><span class="se">\n</span><span class="s">&#39;</span>
1031
 
         <span class="s">&#39;Downgrade to decorator 2.3 if you want to use this functionality&#39;</span><span class="p">)</span>
1032
 
        <span class="o">%</span> <span class="n">func</span><span class="o">.</span><span class="n">__name__</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mf">3</span><span class="p">)</span>
1033
 
    <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>
1034
 
</pre></div>
1035
 
 
1036
 
</div>
1037
 
<p><tt class="docutils literal"><span class="pre">get_info</span></tt> has been removed since it was little used and since it had
1038
 
to be changed anyway to work with Python 3.0; <tt class="docutils literal"><span class="pre">new_wrapper</span></tt> has been
1039
 
removed since it was useless: its major use case (converting
1040
 
signature changing decorators to signature preserving decorators)
1041
 
has been subsumed by <tt class="docutils literal"><span class="pre">decorator_apply</span></tt>
1042
 
and the other use case can be managed with the <tt class="docutils literal"><span class="pre">FunctionMaker</span></tt>.</p>
1043
 
<p>Finally <tt class="docutils literal"><span class="pre">decorator</span></tt> cannot be used as a class decorator and the
 
969
<p>Version 3.2 is the first version of the <tt class="docutils literal">decorator</tt> module to officially
 
970
support Python 3. Actually, the module has supported Python 3 from
 
971
the beginning, via the <tt class="docutils literal">2to3</tt> conversion tool, but this step has
 
972
been now integrated in the build process, thanks to the <a class="reference external" href="http://packages.python.org/distribute/">distribute</a>
 
973
project, the Python 3-compatible replacement of easy_install.
 
974
The hard work (for me) has been converting the documentation and the
 
975
doctests.  This has been possible only now that <a class="reference external" href="http://docutils.sourceforge.net/">docutils</a> and <a class="reference external" href="http://pygments.org/">pygments</a>
 
976
have been ported to Python 3.</p>
 
977
<p>The <tt class="docutils literal">decorator</tt> module <em>per se</em> does not contain any change, apart
 
978
from the removal of the functions <tt class="docutils literal">get_info</tt> and <tt class="docutils literal">new_wrapper</tt>,
 
979
which have been deprecated for years. <tt class="docutils literal">get_info</tt> has been removed
 
980
since it was little used and since it had to be changed anyway to work
 
981
with Python 3.0; <tt class="docutils literal">new_wrapper</tt> has been removed since it was
 
982
useless: its major use case (converting signature changing decorators
 
983
to signature preserving decorators) has been subsumed by
 
984
<tt class="docutils literal">decorator_apply</tt> and the other use case can be managed with the
 
985
<tt class="docutils literal">FunctionMaker</tt>.</p>
 
986
<p>There are a few changes in the documentation: I removed the
 
987
<tt class="docutils literal">decorator_factory</tt> example, which was confusing some of my users,
 
988
and I removed the part about exotic signatures in the Python 3
 
989
documentation, since Python 3 does not support them.
 
990
Notice that there is no support for Python 3 <a class="reference external" href="http://www.python.org/dev/peps/pep-3107/">function annotations</a>
 
991
since it seems premature at the moment, when most people are
 
992
still using Python 2.X.</p>
 
993
<p>Finally <tt class="docutils literal">decorator</tt> cannot be used as a class decorator and the
1044
994
<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
1045
995
means that in order to define decorator factories with classes you
1046
 
need to define the <tt class="docutils literal"><span class="pre">__call__</span></tt> method explicitly (no magic anymore).
1047
 
Since there is
1048
 
an easy way to define decorator factories by using <tt class="docutils literal"><span class="pre">decorator_factory</span></tt>,
1049
 
there is less need to use classes to implement decorator factories.</p>
1050
 
<p>All these changes should not cause any trouble, since they were
 
996
need to define the <tt class="docutils literal">__call__</tt> method explicitly (no magic anymore).
 
997
All these changes should not cause any trouble, since they were
1051
998
all rarely used features. Should you have any trouble, you can always
1052
999
downgrade to the 2.3 version.</p>
1053
 
<p>The examples shown here have been tested with Python 2.5. Python 2.4
1054
 
is also supported - of course the examples requiring the <tt class="docutils literal"><span class="pre">with</span></tt>
1055
 
statement will not work there. Python 2.6 works fine, but if you
1056
 
run the examples here in the interactive interpreter
 
1000
<p>The examples shown here have been tested with Python 2.6. Python 2.4
 
1001
is also supported - of course the examples requiring the <tt class="docutils literal">with</tt>
 
1002
statement will not work there. Python 2.5 works fine, but if you
 
1003
run the examples in the interactive interpreter
1057
1004
you will notice a few differences since
1058
 
<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
 
1005
<tt class="docutils literal">getargspec</tt> returns an <tt class="docutils literal">ArgSpec</tt> namedtuple instead of a regular
1059
1006
tuple. That means that running the file
1060
 
<tt class="docutils literal"><span class="pre">documentation.py</span></tt> under Python 2.5 will a few errors, but
1061
 
they are not serious. Python 3.0 is kind of supported too.
1062
 
Simply run the script <tt class="docutils literal"><span class="pre">2to3</span></tt> on the module
1063
 
<tt class="docutils literal"><span class="pre">decorator.py</span></tt> and you will get a version of the code running
1064
 
with Python 3.0 (at least, I did some simple checks and it seemed
1065
 
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
1066
 
since it seems premature at this moment (most people are
1067
 
still using Python 2.5).</p>
 
1007
<tt class="docutils literal">documentation.py</tt> under Python 2.5 will print a few errors, but
 
1008
they are not serious.</p>
1068
1009
</div>
1069
1010
<div class="section" id="licence">
1070
1011
<h1><a class="toc-backref" href="#id16">LICENCE</a></h1>
1100
1041
you are unhappy with it, send me a patch!</p>
1101
1042
</div>
1102
1043
</div>
1103
 
<div class="footer">
1104
 
<hr class="footer" />
1105
 
<a class="reference external" href="documentation.rst">View document source</a>.
1106
 
Generated on: 2009-08-25 12:37 UTC.
1107
 
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.
1108
 
 
1109
 
</div>
1110
1044
</body>
1111
1045
</html>