diff options
| author | michele.simionato <devnull@localhost> | 2009-02-16 06:14:07 +0000 |
|---|---|---|
| committer | michele.simionato <devnull@localhost> | 2009-02-16 06:14:07 +0000 |
| commit | d1f45f65e6150e3c16d261375df400b3e7e5f89b (patch) | |
| tree | 45919746b90d95e02651b91a1e81802f01ee13e4 | |
| parent | 53aea0e07b603b1f617b33a7c4ace8bd7e288981 (diff) | |
| download | python-decorator-git-d1f45f65e6150e3c16d261375df400b3e7e5f89b.tar.gz | |
Version 3.0.1 released
| -rwxr-xr-x | CHANGES.txt | 3 | ||||
| -rw-r--r-- | Makefile | 3 | ||||
| -rwxr-xr-x | decorator.py | 7 | ||||
| -rw-r--r-- | documentation.py | 51 | ||||
| -rw-r--r-- | setup.py | 2 |
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. @@ -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``: @@ -3,7 +3,7 @@ try: except ImportError: from distutils.core import setup -VERSION = '3.0.0' +VERSION = '3.0.1' if __name__ == '__main__': try: |
