summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichele.simionato <devnull@localhost>2009-02-16 06:14:07 +0000
committermichele.simionato <devnull@localhost>2009-02-16 06:14:07 +0000
commitd1f45f65e6150e3c16d261375df400b3e7e5f89b (patch)
tree45919746b90d95e02651b91a1e81802f01ee13e4
parent53aea0e07b603b1f617b33a7c4ace8bd7e288981 (diff)
downloadpython-decorator-git-d1f45f65e6150e3c16d261375df400b3e7e5f89b.tar.gz
Version 3.0.1 released
-rwxr-xr-xCHANGES.txt3
-rw-r--r--Makefile3
-rwxr-xr-xdecorator.py7
-rw-r--r--documentation.py51
-rw-r--r--setup.py2
5 files changed, 53 insertions, 13 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 852ca8b..dc09489 100755
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,6 +1,9 @@
HISTORY
----------
+3.0.1. Improved the error message in case a bound/unbound method is passed
+ instead of a function and documented this case; that should make life
+ easier for users like Gustavo Nerea (16/02/2009)
3.0. New major version introducing ``FunctionMaker`` and the two-argument
syntax for ``decorator``. Moreover, added support for getting the
source code. This version is Python 3.0 ready.
diff --git a/Makefile b/Makefile
index 41eab7c..35d92a5 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,8 @@
RST=/home/micheles/trunk/ROnline/RCommon/Python/ms/tools/rst.py
+rst: documentation.py
+ python /home/micheles/trunk/ROnline/RCommon/Python/ms/tools/minidoc.py -dH documentation.py
+
pdf: /tmp/documentation.rst
$(RST) -ptd /tmp/documentation.rst; cp /tmp/documentation.pdf /tmp/documentation.html .
upload: documentation.pdf
diff --git a/decorator.py b/decorator.py
index ea38aeb..d775a67 100755
--- a/decorator.py
+++ b/decorator.py
@@ -40,7 +40,8 @@ class FunctionMaker(object):
"""
def __init__(self, func=None, name=None, signature=None,
defaults=None, doc=None, module=None, funcdict=None):
- if func: # func can also be a class or a callable
+ if func:
+ # func can also be a class or a callable, but not an instance method
self.name = func.__name__
if self.name == '<lambda>': # small hack for lambda functions
self.name = '_lambda_'
@@ -64,7 +65,9 @@ class FunctionMaker(object):
if funcdict:
self.dict = funcdict
# check existence required attributes
- assert self.name and hasattr(self, 'signature')
+ assert hasattr(self, 'name')
+ if not hasattr(self, 'signature'):
+ raise TypeError('You are decorating a non function: %s' % func)
def update(self, func, **kw):
"Update the signature of func with the data in self"
diff --git a/documentation.py b/documentation.py
index 82b4fa4..665e45c 100644
--- a/documentation.py
+++ b/documentation.py
@@ -491,7 +491,7 @@ $$identity_dec
@identity_dec
def example(): pass
- >>> print getsource(example)
+ >>> print inspect.getsource(example)
def wrapper(*args, **kw):
return func(*args, **kw)
<BLANKLINE>
@@ -506,7 +506,7 @@ undecorated function:
.. code-block:: python
- >>> print getsource(factorial.undecorated)
+ >>> print inspect.getsource(factorial.undecorated)
@tail_recursive
def factorial(n, acc=1):
"The good old factorial"
@@ -625,13 +625,13 @@ function is decorated the traceback will be longer:
.. code-block:: python
>>> f()
- calling f with args (), {}
Traceback (most recent call last):
- File "<stdin>", line 1, in <module>
- File "<string>", line 2, in f
- File "documentation.py", line 799, in _trace
- return f(*args, **kw)
- File "<stdin>", line 3, in f
+ ...
+ File "<string>", line 2, in f
+ File "<doctest __main__[18]>", line 4, in trace
+ return f(*args, **kw)
+ File "<doctest __main__[47]>", line 3, in f
+ 1/0
ZeroDivisionError: integer division or modulo by zero
You see here the inner call to the decorator ``trace``, which calls
@@ -656,8 +656,39 @@ Actually, this is one of the main reasons why I am releasing version 3.0.
In the present implementation, decorators generated by ``decorator``
can only be used on user-defined Python functions or methods, not on generic
callable objects, nor on built-in functions, due to limitations of the
-``inspect`` module in the standard library.
-
+``inspect`` module in the standard library. Moreover, notice
+that you can decorate a method, but only before if becomes a bound or unbound
+method, i.e. inside the class.
+Here is an example of valid decoration:
+
+.. code-block:: python
+
+ >>> class C(object):
+ ... @trace
+ ... def meth(self):
+ ... pass
+
+Here is an example of invalid decoration, when the decorator in
+called too late:
+
+.. code-block:: python
+
+ >>> class C(object):
+ ... def meth(self):
+ ... pass
+ ...
+ >>> trace(C.meth)
+ Traceback (most recent call last):
+ ...
+ TypeError: You are decorating a non function: <unbound method C.meth>
+
+The solution is to extract the inner function from the unbound method:
+
+.. code-block:: python
+
+ >>> trace(C.meth.im_func) # doctest: +ELLIPSIS
+ <function meth at 0x...>
+
There is a restriction on the names of the arguments: for instance,
if try to call an argument ``_call_`` or ``_func_``
you will get a ``NameError``:
diff --git a/setup.py b/setup.py
index f56a3b1..83e990d 100644
--- a/setup.py
+++ b/setup.py
@@ -3,7 +3,7 @@ try:
except ImportError:
from distutils.core import setup
-VERSION = '3.0.0'
+VERSION = '3.0.1'
if __name__ == '__main__':
try: