summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichele Simionato <michele.simionato@gmail.com>2015-03-16 11:13:06 +0100
committerMichele Simionato <michele.simionato@gmail.com>2015-03-16 11:13:06 +0100
commit5d0a05302b850386b2b71ff281c58db333ac7e78 (patch)
treee8ccc92a2336ee1a5bed53a503776888a3929e91 /src
parent3e2bd43069fa1837d77f8ab2079044a44aaedd66 (diff)
downloadpython-decorator-git-5d0a05302b850386b2b71ff281c58db333ac7e78.tar.gz
Initial changes for decorator 3.4.1
Diffstat (limited to 'src')
-rw-r--r--src/decorator.py88
1 files changed, 49 insertions, 39 deletions
diff --git a/src/decorator.py b/src/decorator.py
index e1187bd..07d99cb 100644
--- a/src/decorator.py
+++ b/src/decorator.py
@@ -1,4 +1,4 @@
-########################## LICENCE ###############################
+# ######################### LICENCE ############################ #
# Copyright (c) 2005-2012, Michele Simionato
# All rights reserved.
@@ -7,12 +7,12 @@
# modification, are permitted provided that the following conditions are
# met:
-# Redistributions of source code must retain the above copyright
+# 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.
+# distribution.
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -36,9 +36,13 @@ __version__ = '3.4.1'
__all__ = ["decorator", "FunctionMaker", "contextmanager"]
-import sys, re, inspect
+import re
+import sys
+import inspect
+
if sys.version >= '3':
from inspect import getfullargspec
+
def get_init(cls):
return cls.__init__
else:
@@ -49,16 +53,19 @@ else:
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):
"""
@@ -72,8 +79,8 @@ class FunctionMaker(object):
if func:
# func can 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_'
+ if self.name == '<lambda>': # small hack for lambda functions
+ self.name = '_lambda_'
self.doc = func.__doc__
self.module = func.__module__
if inspect.isfunction(func):
@@ -84,18 +91,18 @@ class FunctionMaker(object):
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 = \
+ if sys.version < '3': # easy way
+ self.shortsignature = self.signature = (
inspect.formatargspec(
- formatvalue=lambda val: "", *argspec)[1:-1]
- else: # Python 3 way
+ 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
+ allargs.append('*') # single star syntax
for a in self.kwonlyargs:
allargs.append('%s=None' % a)
allshortargs.append('%s=%s' % (a, a))
@@ -137,19 +144,19 @@ class FunctionMaker(object):
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
+ 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(',')])
+ 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
+ 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, '<string>', 'single')
# print >> sys.stderr, 'Compiling %s' % src
@@ -169,42 +176,43 @@ class FunctionMaker(object):
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.
+ 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)"
+ if isinstance(obj, str): # "name(signature)"
name, rest = obj.strip().split('(', 1)
- signature = rest[:-1] #strip a right parens
+ signature = rest[:-1] # strip a right parens
func = None
- else: # a function
+ 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)
-
+ 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
+ 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, __wrapped__=func)
- else: # returns a decorator
+ 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
+ fun = getfullargspec(callerfunc).args[1] # second arg
elif inspect.isfunction(caller):
if caller.__name__ == '<lambda>':
name = '_lambda_'
@@ -212,21 +220,22 @@ def decorator(caller, func=None):
name = caller.__name__
callerfunc = caller
doc = caller.__doc__
- fun = getfullargspec(callerfunc).args[0] # first arg
- else: # assume caller is an object with a __call__ method
+ 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
+ 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),
+ '%s(%s)' % (name, fun),
'return decorator(_call_, %s)' % fun,
evaldict, call=caller, doc=doc, module=caller.__module__)
-######################### contextmanager ########################
+
+# ####################### contextmanager ####################### #
def __call__(self, func):
'Context manager decorator'
@@ -234,17 +243,18 @@ def __call__(self, func):
func, "with _self_: return _func_(%(shortsignature)s)",
dict(_self_=self, _func_=func), __wrapped__=func)
-try: # Python >= 3.2
+try: # Python >= 3.2
+
+ from contextlib import _GeneratorContextManager
- from contextlib import _GeneratorContextManager
class ContextManager(_GeneratorContextManager):
- __call__=__call__
+ __call__ = __call__
-except ImportError: # Python >= 2.5
+except ImportError: # Python >= 2.5
try:
from contextlib import GeneratorContextManager
- except ImportError: # Python 2.4
+ except ImportError: # Python 2.4
class ContextManager(object):
def __init__(self, g, *a, **k):
raise RuntimeError(