summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael E Brown <mebrown@michaels-house.net>2007-12-01 13:08:23 -0600
committerMichael E Brown <mebrown@michaels-house.net>2007-12-01 13:08:23 -0600
commit6c521c9c0cfab397ee0aa9764adce737e39415b4 (patch)
treea969ce2f5a66a53cdf4bf046ac51bd860b7e5e11
parent0a52ee48213f254c99b4a435f63692d2d58b3d48 (diff)
downloadmock-6c521c9c0cfab397ee0aa9764adce737e39415b4.tar.gz
mock-6c521c9c0cfab397ee0aa9764adce737e39415b4.tar.xz
mock-6c521c9c0cfab397ee0aa9764adce737e39415b4.zip
use python-decoratortools instead of shipping our own decorator.py
-rw-r--r--Makefile.am1
-rw-r--r--Makefile.in1
-rw-r--r--mock.spec.in2
-rwxr-xr-xpy/mock/decorator.py124
-rwxr-xr-xpy/mock/trace_decorator.py73
5 files changed, 37 insertions, 164 deletions
diff --git a/Makefile.am b/Makefile.am
index 9680c1e..1532a97 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -53,7 +53,6 @@ pkgpython_PYTHON = \
py/mock/exception.py \
py/mock/util.py \
py/mock/backend.py \
- py/mock/decorator.py \
py/mock/trace_decorator.py \
py/mock/uid.py
diff --git a/Makefile.in b/Makefile.in
index 7520db0..70febdb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -280,7 +280,6 @@ pkgpython_PYTHON = \
py/mock/exception.py \
py/mock/util.py \
py/mock/backend.py \
- py/mock/decorator.py \
py/mock/trace_decorator.py \
py/mock/uid.py
diff --git a/mock.spec.in b/mock.spec.in
index 6e92564..a0bde12 100644
--- a/mock.spec.in
+++ b/mock.spec.in
@@ -17,7 +17,7 @@ Group: Development/Tools
Source: http://fedoraproject.org/projects/mock/releases/%{name}-%{version}.tar.gz
URL: http://fedoraproject.org/wiki/Projects/Mock
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-Requires: python >= 2.4, yum >= 2.4, tar, gzip, python-ctypes
+Requires: python >= 2.4, yum >= 2.4, tar, gzip, python-ctypes, python-decoratortools
Requires(pre): shadow-utils
BuildRequires: python-devel
diff --git a/py/mock/decorator.py b/py/mock/decorator.py
deleted file mode 100755
index 4958a52..0000000
--- a/py/mock/decorator.py
+++ /dev/null
@@ -1,124 +0,0 @@
-## The basic trick is to generate the source code for the decorated function
-## with the right signature and to evaluate it.
-## Uncomment the statement 'print >> sys.stderr, func_src' in _decorate
-## to understand what is going on.
-
-__all__ = ["decorator", "update_wrapper", "getinfo"]
-
-import inspect, sys
-
-def getinfo(func):
- """
- Returns an info dictionary containing:
- - name (the name of the function : str)
- - argnames (the names of the arguments : list)
- - defaults (the values of the default arguments : tuple)
- - signature (the signature : str)
- - doc (the docstring : str)
- - module (the module name : str)
- - dict (the function __dict__ : str)
-
- >>> def f(self, x=1, y=2, *args, **kw): pass
-
- >>> info = getinfo(f)
-
- >>> info["name"]
- 'f'
- >>> info["argnames"]
- ['self', 'x', 'y', 'args', 'kw']
-
- >>> info["defaults"]
- (1, 2)
-
- >>> info["signature"]
- 'self, x, y, *args, **kw'
- """
- assert inspect.ismethod(func) or inspect.isfunction(func)
- regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
- argnames = list(regargs)
- if varargs:
- argnames.append(varargs)
- if varkwargs:
- argnames.append(varkwargs)
- signature = inspect.formatargspec(regargs, varargs, varkwargs, defaults,
- formatvalue=lambda value: "")[1:-1]
- return dict(name=func.__name__, argnames=argnames, signature=signature,
- defaults = func.func_defaults, doc=func.__doc__,
- module=func.__module__, dict=func.__dict__,
- globals=func.func_globals, closure=func.func_closure)
-
-def update_wrapper(wrapper, wrapped, create=False):
- """
- An improvement over functools.update_wrapper. By default it works the
- same, but if the 'create' flag is set, generates a copy of the wrapper
- with the right signature and update the copy, not the original.
- Moreovoer, 'wrapped' can be a dictionary with keys 'name', 'doc', 'module',
- 'dict', 'defaults'.
- """
- if isinstance(wrapped, dict):
- infodict = wrapped
- else: # assume wrapped is a function
- infodict = getinfo(wrapped)
- assert not '_wrapper_' in infodict["argnames"], \
- '"_wrapper_" is a reserved argument name!'
- if create: # create a brand new wrapper with the right signature
- src = "lambda %(signature)s: _wrapper_(%(signature)s)" % infodict
- # import sys; print >> sys.stderr, src # for debugging purposes
- wrapper = eval(src, dict(_wrapper_=wrapper))
- try:
- wrapper.__name__ = infodict['name']
- except: # Python version < 2.4
- pass
- wrapper.__doc__ = infodict['doc']
- wrapper.__module__ = infodict['module']
- wrapper.__dict__.update(infodict['dict'])
- wrapper.func_defaults = infodict['defaults']
- return wrapper
-
-# the real meat is here
-def _decorator(caller, func):
- infodict = getinfo(func)
- argnames = infodict['argnames']
- assert not ('_call_' in argnames or '_func_' in argnames), \
- 'You cannot use _call_ or _func_ as argument names!'
- src = "lambda %(signature)s: _call_(_func_, %(signature)s)" % infodict
- dec_func = eval(src, dict(_func_=func, _call_=caller))
- return update_wrapper(dec_func, func)
-
-def decorator(caller, func=None):
- """
- General purpose decorator factory: takes a caller function as
- input and returns a decorator with the same attributes.
- A caller function is any function like this::
-
- def caller(func, *args, **kw):
- # do something
- return func(*args, **kw)
-
- Here is an example of usage:
-
- >>> @decorator
- ... def chatty(f, *args, **kw):
- ... print "Calling %r" % f.__name__
- ... return f(*args, **kw)
-
- >>> chatty.__name__
- 'chatty'
-
- >>> @chatty
- ... def f(): pass
- ...
- >>> f()
- Calling 'f'
-
- For sake of convenience, the decorator factory can also be called with
- two arguments. In this casem ``decorator(caller, func)`` is just a
- shortcut for ``decorator(caller)(func)``.
- """
- if func is None: # return a decorator function
- return update_wrapper(lambda f : _decorator(caller, f), caller)
- else: # return a decorated function
- return _decorator(caller, func)
-
-if __name__ == "__main__":
- import doctest; doctest.testmod()
diff --git a/py/mock/trace_decorator.py b/py/mock/trace_decorator.py
index 3db2360..5529628 100755
--- a/py/mock/trace_decorator.py
+++ b/py/mock/trace_decorator.py
@@ -6,8 +6,7 @@
import logging
import os
import sys
-
-from decorator import decorator
+from peak.util.decorators import rewrap
moduleLog = logging.getLogger("mock.trace_decorator")
@@ -19,42 +18,42 @@ def doLog(logger, level, *args, **kargs):
if logger.isEnabledFor(level):
logger.handle(logger.makeRecord(logger.name, level, *args, **kargs))
-def traceLog(logger = moduleLog):
- log = logger
- @decorator
- def trace(f, *args, **kw):
- # default to logger that was passed by module, but
- # can override by passing logger=foo as function parameter.
- # make sure this doesnt conflict with one of the parameters
- # you are expecting
-
- filename = os.path.normcase(f.func_code.co_filename)
- func_name = f.func_code.co_name
- lineno = f.func_code.co_firstlineno
-
- l2 = kw.get('logger', log)
- message = "ENTER %s(" % f.func_name
- for arg in args:
- message = message + repr(arg) + ", "
- for k,v in kw.items():
- message = message + "%s=%s" % (k,repr(v))
- message = message + ")"
-
- frame = sys._getframe(2)
- doLog(l2, logging.DEBUG, os.path.normcase(frame.f_code.co_filename), frame.f_lineno, message, args=[], exc_info=None, func=frame.f_code.co_name)
- try:
- result = "Bad exception raised: Exception was not a derived class of 'Exception'"
+def traceLog(log = moduleLog):
+ def decorator(func):
+ def trace(*args, **kw):
+ # default to logger that was passed by module, but
+ # can override by passing logger=foo as function parameter.
+ # make sure this doesnt conflict with one of the parameters
+ # you are expecting
+
+ filename = os.path.normcase(func.func_code.co_filename)
+ func_name = func.func_code.co_name
+ lineno = func.func_code.co_firstlineno
+
+ l2 = kw.get('logger', log)
+ message = "ENTER %s(" % func_name
+ for arg in args:
+ message = message + repr(arg) + ", "
+ for k,v in kw.items():
+ message = message + "%s=%s" % (k,repr(v))
+ message = message + ")"
+
+ frame = sys._getframe(2)
+ doLog(l2, logging.DEBUG, os.path.normcase(frame.f_code.co_filename), frame.f_lineno, message, args=[], exc_info=None, func=frame.f_code.co_name)
try:
- result = f(*args, **kw)
- except (KeyboardInterrupt, Exception), e:
- result = "EXCEPTION RAISED"
- doLog(l2, logging.DEBUG, filename, lineno, "EXCEPTION: %s\n" % e, args=[], exc_info=sys.exc_info(), func=func_name)
- raise
- finally:
- doLog(l2, logging.DEBUG, filename, lineno, "LEAVE %s --> %s\n" % (f.func_name, result), args=[], exc_info=None, func=func_name)
-
- return result
- return trace
+ result = "Bad exception raised: Exception was not a derived class of 'Exception'"
+ try:
+ result = func(*args, **kw)
+ except (KeyboardInterrupt, Exception), e:
+ result = "EXCEPTION RAISED"
+ doLog(l2, logging.DEBUG, filename, lineno, "EXCEPTION: %s\n" % e, args=[], exc_info=sys.exc_info(), func=func_name)
+ raise
+ finally:
+ doLog(l2, logging.DEBUG, filename, lineno, "LEAVE %s --> %s\n" % (func_name, result), args=[], exc_info=None, func=func_name)
+
+ return result
+ return rewrap(func, trace)
+ return decorator
# unit tests...
if __name__ == "__main__":