NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

decorator.py (5796B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\ccpProfile\decorator.py
      2 from __future__ import print_function
      3 __version__ = '3.3.2'
      4 __all__ = ['decorator', 'FunctionMaker', 'partial']
      5 import sys, re, inspect
      6 try:
      7     from functools import partial
      8 except ImportError:
      9 
     10     class partial(object):
     11 
     12         def __init__(self, func, *args, **kw):
     13             self.func = func
     14             self.args = args
     15             self.keywords = kw
     16 
     17         def __call__(self, *otherargs, **otherkw):
     18             kw = self.keywords.copy()
     19             kw.update(otherkw)
     20             return self.func(*(self.args + otherargs), **kw)
     21 
     22 
     23 if sys.version >= '3':
     24     from inspect import getfullargspec
     25 else:
     26 
     27     class getfullargspec(object):
     28 
     29         def __init__(self, f):
     30             self.args, self.varargs, self.varkw, self.defaults = inspect.getargspec(f)
     31             self.kwonlyargs = []
     32             self.kwonlydefaults = None
     33             self.annotations = getattr(f, '__annotations__', {})
     34 
     35         def __iter__(self):
     36             yield self.args
     37             yield self.varargs
     38             yield self.varkw
     39             yield self.defaults
     40 
     41 
     42 DEF = re.compile('\\s*def\\s*([_\\w][_\\w\\d]*)\\s*\\(')
     43 
     44 class FunctionMaker(object):
     45 
     46     def __init__(self, func = None, name = None, signature = None, defaults = None, doc = None, module = None, funcdict = None):
     47         self.shortsignature = signature
     48         if func:
     49             self.name = func.__name__
     50             if self.name == '<lambda>':
     51                 self.name = '_lambda_'
     52             self.doc = func.__doc__
     53             self.module = func.__module__
     54             if inspect.isfunction(func):
     55                 argspec = getfullargspec(func)
     56                 for a in ('args', 'varargs', 'varkw', 'defaults', 'kwonlyargs', 'kwonlydefaults', 'annotations'):
     57                     setattr(self, a, getattr(argspec, a))
     58 
     59                 for i, arg in enumerate(self.args):
     60                     setattr(self, 'arg%d' % i, arg)
     61 
     62                 self.signature = inspect.formatargspec(formatvalue=(lambda val: ''), *argspec)[1:-1]
     63                 allargs = list(self.args)
     64                 if self.varargs:
     65                     allargs.append('*' + self.varargs)
     66                 if self.varkw:
     67                     allargs.append('**' + self.varkw)
     68                 try:
     69                     self.shortsignature = ', '.join(allargs)
     70                 except TypeError:
     71                     self.shortsignature = self.signature
     72 
     73                 self.dict = func.__dict__.copy()
     74         if name:
     75             self.name = name
     76         if signature is not None:
     77             self.signature = signature
     78         if defaults:
     79             self.defaults = defaults
     80         if doc:
     81             self.doc = doc
     82         if module:
     83             self.module = module
     84         if funcdict:
     85             self.dict = funcdict
     86         if not hasattr(self, 'signature'):
     87             raise TypeError('You are decorating a non function: %s' % func)
     88 
     89     def update(self, func, **kw):
     90         func.__name__ = self.name
     91         func.__doc__ = getattr(self, 'doc', None)
     92         func.__dict__ = getattr(self, 'dict', {})
     93         func.__defaults__ = getattr(self, 'defaults', ())
     94         func.__kwdefaults__ = getattr(self, 'kwonlydefaults', None)
     95         callermodule = sys._getframe(3).f_globals.get('__name__', '?')
     96         func.__module__ = getattr(self, 'module', callermodule)
     97         func.__dict__.update(kw)
     98 
     99     def make(self, src_templ, evaldict = None, addsource = False, **attrs):
    100         src = src_templ % vars(self)
    101         evaldict = evaldict or {}
    102         mo = DEF.match(src)
    103         if mo is None:
    104             raise SyntaxError('not a valid function template\n%s' % src)
    105         name = mo.group(1)
    106         names = set([name] + [ arg.strip(' *') for arg in self.shortsignature.split(',') ])
    107         for n in names:
    108             if n in ('_func_', '_call_'):
    109                 raise NameError('%s is overridden in\n%s' % (n, src))
    110 
    111         if not src.endswith('\n'):
    112             src += '\n'
    113         try:
    114             code = compile(src, '<string>', 'single')
    115             exec code in evaldict
    116         except:
    117             print('Error in generated code:', file=sys.stderr)
    118             print(src, file=sys.stderr)
    119             raise
    120 
    121         func = evaldict[name]
    122         if addsource:
    123             attrs['__source__'] = src
    124         self.update(func, **attrs)
    125         return func
    126 
    127     @classmethod
    128     def create(cls, obj, body, evaldict, defaults = None, doc = None, module = None, addsource = True, **attrs):
    129         if isinstance(obj, str):
    130             name, rest = obj.strip().split('(', 1)
    131             signature = rest[:-1]
    132             func = None
    133         else:
    134             name = None
    135             signature = None
    136             func = obj
    137         self = cls(func, name, signature, defaults, doc, module)
    138         ibody = '\n'.join(('    ' + line for line in body.splitlines()))
    139         return self.make(('def %(name)s(%(signature)s):\n' + ibody), evaldict, addsource, **attrs)
    140 
    141 
    142 def decorator(caller, func = None):
    143     if func is not None:
    144         evaldict = func.__globals__.copy()
    145         evaldict['_call_'] = caller
    146         evaldict['_func_'] = func
    147         return FunctionMaker.create(func, 'return _call_(_func_, %(shortsignature)s)', evaldict, undecorated=func, __wrapped__=func)
    148     elif isinstance(caller, partial):
    149         return partial(decorator, caller)
    150     else:
    151         first = inspect.getargspec(caller)[0][0]
    152         evaldict = caller.__globals__.copy()
    153         evaldict['_call_'] = caller
    154         evaldict['decorator'] = decorator
    155         return FunctionMaker.create('%s(%s)' % (caller.__name__, first), 'return decorator(_call_, %s)' % first, evaldict, undecorated=caller, __wrapped__=caller, doc=caller.__doc__, module=caller.__module__)