From b02f7a254c3679dfac57a824e08dd02ced850636 Mon Sep 17 00:00:00 2001 From: Lorry Tar Creator Date: Thu, 18 Oct 2012 08:53:16 +0000 Subject: Imported from /home/lorry/working-area/delta_python-packages_python-decorator/decorator-3.4.0.tar.gz. --- src/decorator.egg-info/PKG-INFO | 100 +++++++++++ src/decorator.egg-info/SOURCES.txt | 11 ++ src/decorator.egg-info/dependency_links.txt | 1 + src/decorator.egg-info/not-zip-safe | 1 + src/decorator.egg-info/top_level.txt | 1 + src/decorator.py | 251 ++++++++++++++++++++++++++++ 6 files changed, 365 insertions(+) create mode 100644 src/decorator.egg-info/PKG-INFO create mode 100644 src/decorator.egg-info/SOURCES.txt create mode 100644 src/decorator.egg-info/dependency_links.txt create mode 100644 src/decorator.egg-info/not-zip-safe create mode 100644 src/decorator.egg-info/top_level.txt create mode 100644 src/decorator.py (limited to 'src') diff --git a/src/decorator.egg-info/PKG-INFO b/src/decorator.egg-info/PKG-INFO new file mode 100644 index 0000000..8491af5 --- /dev/null +++ b/src/decorator.egg-info/PKG-INFO @@ -0,0 +1,100 @@ +Metadata-Version: 1.1 +Name: decorator +Version: 3.4.0 +Summary: Better living through Python with decorators +Home-page: http://pypi.python.org/pypi/decorator +Author: Michele Simionato +Author-email: michele.simionato@gmail.com +License: BSD License +Description: Decorator module + ================= + + + :Author: Michele Simionato + :E-mail: michele.simionato@gmail.com + :Requires: Python 2.4+ + :Download page: http://pypi.python.org/pypi/decorator + :Installation: ``easy_install decorator`` + :License: BSD license + + Installation + ------------- + + If you are lazy, just perform + + $ easy_install decorator + + which will install just the module on your system. Notice that + Python 3 requires the easy_install version of the distribute_ project. + + If you prefer to install the full distribution from source, including + the documentation, download the tarball_, unpack it and run + + $ python setup.py install + + in the main directory, possibly as superuser. + + .. _tarball: http://pypi.python.org/pypi/decorator + .. _distribute: http://packages.python.org/distribute/ + + Testing + -------- + + For Python 2.5, 2.6, 2.7 run + + $ python documentation.py + + for Python 3.X run + + $ python documentation3.py + + You will see a few innocuous errors with Python 2.5, because some + inner details such as the introduction of the ArgSpec namedtuple and + Thread.__repr__ changed. You may safely ignore them. + + You cannot run the tests in Python 2.4, since there is a test using + the with statement, but the decorator module is expected to work + anyway (it has been used in production with Python 2.4 for years). My + plan is to keep supporting all Python versions >= 2.4 in the core + module, but I will keep the documentation and the tests updated only + for the latest Python versions in both the 2.X and 3.X branches. + + Finally, notice that you may run into trouble if in your system there + is an older version of the decorator module; in such a case remove the + old version. + + Documentation + -------------- + + There are various versions of the documentation: + + - `HTML version (Python 2)`_ + - `PDF version (Python 2)`_ + + - `HTML version (Python 3)`_ + - `PDF version (Python 3)`_ + + .. _HTML version (Python 2): http://micheles.googlecode.com/hg/decorator/documentation.html + .. _PDF version (Python 2): http://micheles.googlecode.com/hg/decorator/documentation.pdf + .. _HTML version (Python 3): http://micheles.googlecode.com/hg/decorator/documentation3.html + .. _PDF version (Python 3): http://micheles.googlecode.com/hg/decorator/documentation3.pdf + + Repository + --------------- + + The project is hosted on GoogleCode as a Mercurial repository. You + can look at the source here: + + http://code.google.com/p/micheles/source/browse/#hg%2Fdecorator + +Keywords: decorators generic utility +Platform: All +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: BSD License +Classifier: Natural Language :: English +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 3 +Classifier: Topic :: Software Development :: Libraries +Classifier: Topic :: Utilities diff --git a/src/decorator.egg-info/SOURCES.txt b/src/decorator.egg-info/SOURCES.txt new file mode 100644 index 0000000..4b7a116 --- /dev/null +++ b/src/decorator.egg-info/SOURCES.txt @@ -0,0 +1,11 @@ +MANIFEST.in +README.txt +documentation.py +documentation3.py +setup.py +src/decorator.py +src/decorator.egg-info/PKG-INFO +src/decorator.egg-info/SOURCES.txt +src/decorator.egg-info/dependency_links.txt +src/decorator.egg-info/not-zip-safe +src/decorator.egg-info/top_level.txt \ No newline at end of file diff --git a/src/decorator.egg-info/dependency_links.txt b/src/decorator.egg-info/dependency_links.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/decorator.egg-info/dependency_links.txt @@ -0,0 +1 @@ + diff --git a/src/decorator.egg-info/not-zip-safe b/src/decorator.egg-info/not-zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/src/decorator.egg-info/not-zip-safe @@ -0,0 +1 @@ + diff --git a/src/decorator.egg-info/top_level.txt b/src/decorator.egg-info/top_level.txt new file mode 100644 index 0000000..3fe18a4 --- /dev/null +++ b/src/decorator.egg-info/top_level.txt @@ -0,0 +1 @@ +decorator diff --git a/src/decorator.py b/src/decorator.py new file mode 100644 index 0000000..e003914 --- /dev/null +++ b/src/decorator.py @@ -0,0 +1,251 @@ +########################## LICENCE ############################### + +# Copyright (c) 2005-2012, Michele Simionato +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: + +# Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# Redistributions in bytecode form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. + +""" +Decorator module, see http://pypi.python.org/pypi/decorator +for the documentation. +""" + +__version__ = '3.4.0' + +__all__ = ["decorator", "FunctionMaker", "contextmanager"] + +import sys, re, inspect +if sys.version >= '3': + from inspect import getfullargspec + def get_init(cls): + return cls.__init__ +else: + class getfullargspec(object): + "A quick and dirty replacement for getfullargspec for Python 2.X" + def __init__(self, f): + self.args, self.varargs, self.varkw, self.defaults = \ + inspect.getargspec(f) + self.kwonlyargs = [] + self.kwonlydefaults = None + def __iter__(self): + yield self.args + yield self.varargs + yield self.varkw + yield self.defaults + def get_init(cls): + return cls.__init__.im_func + +DEF = re.compile('\s*def\s*([_\w][_\w\d]*)\s*\(') + +# basic functionality +class FunctionMaker(object): + """ + An object with the ability to create functions with a given signature. + It has attributes name, doc, module, signature, defaults, dict and + methods update and make. + """ + def __init__(self, func=None, name=None, signature=None, + defaults=None, doc=None, module=None, funcdict=None): + self.shortsignature = signature + if func: + # func can be a class or a callable, but not an instance method + self.name = func.__name__ + if self.name == '': # small hack for lambda functions + self.name = '_lambda_' + self.doc = func.__doc__ + self.module = func.__module__ + if inspect.isfunction(func): + argspec = getfullargspec(func) + self.annotations = getattr(func, '__annotations__', {}) + for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs', + 'kwonlydefaults'): + setattr(self, a, getattr(argspec, a)) + for i, arg in enumerate(self.args): + setattr(self, 'arg%d' % i, arg) + if sys.version < '3': # easy way + self.shortsignature = self.signature = \ + inspect.formatargspec( + formatvalue=lambda val: "", *argspec)[1:-1] + else: # Python 3 way + allargs = list(self.args) + allshortargs = list(self.args) + if self.varargs: + allargs.append('*' + self.varargs) + allshortargs.append('*' + self.varargs) + elif self.kwonlyargs: + allargs.append('*') # single star syntax + for a in self.kwonlyargs: + allargs.append('%s=None' % a) + allshortargs.append('%s=%s' % (a, a)) + if self.varkw: + allargs.append('**' + self.varkw) + allshortargs.append('**' + self.varkw) + self.signature = ', '.join(allargs) + self.shortsignature = ', '.join(allshortargs) + self.dict = func.__dict__.copy() + # func=None happens when decorating a caller + if name: + self.name = name + if signature is not None: + self.signature = signature + if defaults: + self.defaults = defaults + if doc: + self.doc = doc + if module: + self.module = module + if funcdict: + self.dict = funcdict + # check existence required attributes + 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" + func.__name__ = self.name + func.__doc__ = getattr(self, 'doc', None) + func.__dict__ = getattr(self, 'dict', {}) + func.func_defaults = getattr(self, 'defaults', ()) + func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None) + func.__annotations__ = getattr(self, 'annotations', None) + callermodule = sys._getframe(3).f_globals.get('__name__', '?') + func.__module__ = getattr(self, 'module', callermodule) + func.__dict__.update(kw) + + def make(self, src_templ, evaldict=None, addsource=False, **attrs): + "Make a new function from a given template and update the signature" + src = src_templ % vars(self) # expand name and signature + evaldict = evaldict or {} + mo = DEF.match(src) + if mo is None: + raise SyntaxError('not a valid function template\n%s' % src) + name = mo.group(1) # extract the function name + names = set([name] + [arg.strip(' *') for arg in + self.shortsignature.split(',')]) + for n in names: + if n in ('_func_', '_call_'): + raise NameError('%s is overridden in\n%s' % (n, src)) + if not src.endswith('\n'): # add a newline just for safety + src += '\n' # this is needed in old versions of Python + try: + code = compile(src, '', 'single') + # print >> sys.stderr, 'Compiling %s' % src + exec code in evaldict + except: + print >> sys.stderr, 'Error in generated code:' + print >> sys.stderr, src + raise + func = evaldict[name] + if addsource: + attrs['__source__'] = src + self.update(func, **attrs) + return func + + @classmethod + def create(cls, obj, body, evaldict, defaults=None, + doc=None, module=None, addsource=True, **attrs): + """ + Create a function from the strings name, signature and body. + evaldict is the evaluation dictionary. If addsource is true an attribute + __source__ is added to the result. The attributes attrs are added, + if any. + """ + if isinstance(obj, str): # "name(signature)" + name, rest = obj.strip().split('(', 1) + signature = rest[:-1] #strip a right parens + func = None + else: # a function + name = None + signature = None + func = obj + self = cls(func, name, signature, defaults, doc, module) + ibody = '\n'.join(' ' + line for line in body.splitlines()) + return self.make('def %(name)s(%(signature)s):\n' + ibody, + evaldict, addsource, **attrs) + +def decorator(caller, func=None): + """ + decorator(caller) converts a caller function into a decorator; + decorator(caller, func) decorates a function using a caller. + """ + if func is not None: # returns a decorated function + evaldict = func.func_globals.copy() + evaldict['_call_'] = caller + evaldict['_func_'] = func + return FunctionMaker.create( + func, "return _call_(_func_, %(shortsignature)s)", + evaldict, undecorated=func, __wrapped__=func) + else: # returns a decorator + if inspect.isclass(caller): + name = caller.__name__.lower() + callerfunc = get_init(caller) + doc = 'decorator(%s) converts functions/generators into ' \ + 'factories of %s objects' % (caller.__name__, caller.__name__) + fun = getfullargspec(callerfunc).args[1] # second arg + elif inspect.isfunction(caller): + name = '_lambda_' if caller.__name__ == '' \ + else caller.__name__ + callerfunc = caller + doc = caller.__doc__ + fun = getfullargspec(callerfunc).args[0] # first arg + else: # assume caller is an object with a __call__ method + name = caller.__class__.__name__.lower() + callerfunc = caller.__call__.im_func + doc = caller.__call__.__doc__ + fun = getfullargspec(callerfunc).args[1] # second arg + evaldict = callerfunc.func_globals.copy() + evaldict['_call_'] = caller + evaldict['decorator'] = decorator + return FunctionMaker.create( + '%s(%s)' % (name, fun), + 'return decorator(_call_, %s)' % fun, + evaldict, undecorated=caller, __wrapped__=caller, + doc=doc, module=caller.__module__) + +######################### contextmanager ######################## + +def __call__(self, func): + 'Context manager decorator' + return FunctionMaker.create( + func, "with _self_: return _func_(%(shortsignature)s)", + dict(_self_=self, _func_=func), __wrapped__=func) + +try: # Python >= 3.2 + + from contextlib import _GeneratorContextManager + ContextManager = type( + 'ContextManager', (_GeneratorContextManager,), dict(__call__=__call__)) + +except ImportError: # Python >= 2.5 + + from contextlib import GeneratorContextManager + def __init__(self, f, *a, **k): + return GeneratorContextManager.__init__(self, f(*a, **k)) + ContextManager = type( + 'ContextManager', (GeneratorContextManager,), + dict(__call__=__call__, __init__=__init__)) + +contextmanager = decorator(ContextManager) -- cgit v1.2.1