##// END OF EJS Templates
Merge pull request #6071 from minrk/serialize-nan...
Merge pull request #6071 from minrk/serialize-nan Fix NaN warnings and failures in test_serialize

File last commit:

r15286:4572b2ed
r17149:639fc3ac merge
Show More
_decorator.py
229 lines | 9.4 KiB | text/x-python | PythonLexer
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 ########################## LICENCE ###############################
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920
# 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.
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268
"""
Decorator module, see http://pypi.python.org/pypi/decorator
for the documentation.
Doug Blank
Added doc-string comment regarding reason for patch, and details on try/catch change.
r15285
NOTE: this is an IPython-patched version to work on IronPython. See
FIXED comment below.
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 """
Thomas Kluyver
Convert print statements to print function calls...
r13348 from __future__ import print_function
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 __version__ = '3.3.3'
__all__ = ["decorator", "FunctionMaker", "partial"]
import sys, re, inspect
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268
try:
from functools import partial
except ImportError: # for Python version < 2.5
class partial(object):
"A simple replacement of functools.partial"
def __init__(self, func, *args, **kw):
self.func = func
Bernardo B. Marques
remove all trailling spaces
r4872 self.args = args
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 self.keywords = kw
def __call__(self, *otherargs, **otherkw):
kw = self.keywords.copy()
kw.update(otherkw)
return self.func(*(self.args + otherargs), **kw)
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 if sys.version >= '3':
from inspect import getfullargspec
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
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 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):
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 self.shortsignature = signature
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 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
Bernardo B. Marques
remove all trailling spaces
r4872 self.name = '_lambda_'
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 self.doc = func.__doc__
self.module = func.__module__
if inspect.isfunction(func):
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 argspec = getfullargspec(func)
self.annotations = getattr(func, '__annotations__', {})
for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs',
'kwonlydefaults'):
setattr(self, a, getattr(argspec, a))
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 for i, arg in enumerate(self.args):
setattr(self, 'arg%d' % i, arg)
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 if sys.version < '3': # easy way
self.shortsignature = self.signature = \
inspect.formatargspec(
formatvalue=lambda val: "", *argspec)[1:-1]
else: # Python 3 way
self.signature = self.shortsignature = ', '.join(self.args)
if self.varargs:
self.signature += ', *' + self.varargs
self.shortsignature += ', *' + self.varargs
if self.kwonlyargs:
for a in self.kwonlyargs:
self.signature += ', %s=None' % a
self.shortsignature += ', %s=%s' % (a, a)
if self.varkw:
self.signature += ', **' + self.varkw
self.shortsignature += ', **' + self.varkw
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 self.dict = func.__dict__.copy()
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 # func=None happens when decorating a caller
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 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', {})
Thomas Kluyver
Update function attribute names...
r13362 func.__defaults__ = getattr(self, 'defaults', ())
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
func.__annotations__ = getattr(self, 'annotations', None)
Doug Blank
Typo in comment fixed
r15286 # FIXED: The following is try/excepted in IPython to work
Doug Blank
Added doc-string comment regarding reason for patch, and details on try/catch change.
r15285 # with IronPython.
Doug Blank
Summary of changes:...
r15208 try:
callermodule = sys._getframe(3).f_globals.get('__name__', '?')
except AttributeError: # IronPython _getframe only exists with FullFrames
callermodule = '?'
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 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
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 names = set([name] + [arg.strip(' *') for arg in
self.shortsignature.split(',')])
for n in names:
if n in ('_func_', '_call_'):
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 raise NameError('%s is overridden in\n%s' % (n, src))
if not src.endswith('\n'): # add a newline just for safety
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 src += '\n' # this is needed in old versions of Python
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 try:
code = compile(src, '<string>', 'single')
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 # print >> sys.stderr, 'Compiling %s' % src
Thomas Kluyver
Fix exec statements for Py 3...
r13350 exec(code, evaldict)
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 except:
Thomas Kluyver
Convert print statements to print function calls...
r13348 print('Error in generated code:', file=sys.stderr)
print(src, file=sys.stderr)
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 raise
func = evaldict[name]
if addsource:
attrs['__source__'] = src
self.update(func, **attrs)
return func
@classmethod
def create(cls, obj, body, evaldict, defaults=None,
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 doc=None, module=None, addsource=True, **attrs):
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 """
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)
Bernardo B. Marques
remove all trailling spaces
r4872 signature = rest[:-1] #strip a right parens
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 func = None
else: # a function
name = None
signature = None
func = obj
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 self = cls(func, name, signature, defaults, doc, module)
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 ibody = '\n'.join(' ' + line for line in body.splitlines())
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 return self.make('def %(name)s(%(signature)s):\n' + ibody,
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 evaldict, addsource, **attrs)
Bernardo B. Marques
remove all trailling spaces
r4872
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 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
Thomas Kluyver
Update function attribute names...
r13362 evaldict = func.__globals__.copy()
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 evaldict['_call_'] = caller
evaldict['_func_'] = func
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 return FunctionMaker.create(
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 func, "return _call_(_func_, %(shortsignature)s)",
evaldict, undecorated=func, __wrapped__=func)
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 else: # returns a decorator
if isinstance(caller, partial):
return partial(decorator, caller)
# otherwise assume caller is a function
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 first = inspect.getargspec(caller)[0][0] # first arg
Thomas Kluyver
Update function attribute names...
r13362 evaldict = caller.__globals__.copy()
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 evaldict['_call_'] = caller
evaldict['decorator'] = decorator
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 return FunctionMaker.create(
Fernando Perez
Update decorator module in externals to version 3.3.3 (upstream).
r6920 '%s(%s)' % (caller.__name__, first),
'return decorator(_call_, %s)' % first,
evaldict, undecorated=caller, __wrapped__=caller,
Brian Granger
Updated Michele Simionato's decorator.py module to 3.1.2....
r2268 doc=caller.__doc__, module=caller.__module__)