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>
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">>>></span> <span class="nd">@memoize25</span>
212
<div class="highlight"><pre><span class="o">>>></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>
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">>>></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">>>></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">'args'</span><span class="p">,</span> <span class="s">'kw'</span><span class="p">,</span> <span class="bp">None</span><span class="p">)</span>
224
<span class="o">>>></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">'args'</span><span class="p">,</span> <span class="n">keywords</span><span class="o">=</span><span class="s">'kw'</span><span class="p">,</span> <span class="n">defaults</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
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">>>></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">>>></span> <span class="kn">from</span> <span class="nn">decorator</span> <span class="kn">import</span> <span class="n">decorator</span>
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>
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">>>></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>
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>
379
379
in Python 2.6 and removed in Python 3.0.</p>
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">
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">"decorator_factory(decfac) returns a one-parameter family of decorators"</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>
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">>>></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>
449
<div class="codeblock python">
450
<div class="highlight"><pre><span class="o">>>></span> <span class="n">trace_factory</span>
451
<span class="o"><</span><span class="n">functools</span><span class="o">.</span><span class="n">partial</span> <span class="nb">object</span> <span class="n">at</span> <span class="mf">0</span><span class="n">x</span><span class="o">...></span>
453
<span class="o">>>></span> <span class="n">trace</span> <span class="o">=</span> <span class="n">trace_factory</span><span class="p">(</span><span class="s">'Calling </span><span class="si">%(name)s</span><span class="s"> with args </span><span class="si">%(args)s</span><span class="s"> '</span>
454
<span class="o">...</span> <span class="s">'and keywords </span><span class="si">%(kw)s</span><span class="s">'</span><span class="p">)</span>
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">>>></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>
468
<span class="o">>>></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>
423
<tt class="docutils literal">decorator</tt> module provides a poor man replacement for
424
<tt class="docutils literal">functools.partial</tt>.</p>
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 "busy" 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">"thread"</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">"thread"</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>
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">
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">
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
>>> write("data1")
626
<Thread(write-1, started...)>
628
<pre class="doctest-block">
629
>>> time.sleep(.1) # wait a bit, so we are sure data2 is written after data1
631
<pre class="doctest-block">
632
>>> write("data2")
633
<Thread(write-2, started...)>
635
<pre class="doctest-block">
636
>>> time.sleep(2) # wait for the writers to complete
638
<pre class="doctest-block">
639
>>> print datalist
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">>>></span> <span class="n">write</span><span class="p">(</span><span class="s">"data1"</span><span class="p">)</span>
579
<span class="o"><</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">></span>
581
<span class="o">>>></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>
583
<span class="o">>>></span> <span class="n">write</span><span class="p">(</span><span class="s">"data2"</span><span class="p">)</span>
584
<span class="o"><</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">></span>
586
<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">2</span><span class="p">)</span> <span class="c"># wait for the writers to complete</span>
588
<span class="o">>>></span> <span class="k">print</span> <span class="n">datalist</span>
589
<span class="p">[</span><span class="s">'data1'</span><span class="p">,</span> <span class="s">'data2'</span><span class="p">]</span>
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">>>></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>
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">>>></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
<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>
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>
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">"<string>",</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">"<string>",</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>
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">"A decorator for deprecated functions"</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">'Calling the deprecated function </span><span class="si">%r</span><span class="se">\n</span><span class="s">'</span>
1031
<span class="s">'Downgrade to decorator 2.3 if you want to use this functionality'</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>
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).
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>
1069
1010
<div class="section" id="licence">
1070
1011
<h1><a class="toc-backref" href="#id16">LICENCE</a></h1>