示例#1
0
def hax(target: T) -> T:

    if isinstance(target, CodeType):
        return cast(T, _hax(target))

    if isinstance(target, FunctionType):

        new = FunctionType(
            _hax(target.__code__),
            target.__globals__,
            target.__name__,
            target.__defaults__,
            target.__closure__,
        )

        if target.__annotations__:
            new.__annotations__ = target.__annotations__.copy()

        if target.__kwdefaults__ is not None:
            new.__kwdefaults__ = target.__kwdefaults__.copy()

        if target.__dict__:
            new.__dict__ = target.__dict__.copy()

        return cast(T, new)

    raise TypeError(f"HAX doesn't support this! Got type {type(target)!r}.")
示例#2
0
文件: pickle.py 项目: simon-ca/pymor
def loads_function(s):
    '''Restores a function serialized with :func:`dumps_function`.'''
    if PY2:
        name, code, globals_, defaults, closure, func_dict, doc = loads(s)
    else:
        name, code, globals_, defaults, closure, func_dict, doc, qualname, kwdefaults, annotations = loads(
            s)
    code = marshal.loads(code)
    for k, v in globals_.items():
        if isinstance(v, Module):
            globals_[k] = v.mod
    if closure is not None:
        import ctypes
        ctypes.pythonapi.PyCell_New.restype = ctypes.py_object
        ctypes.pythonapi.PyCell_New.argtypes = [ctypes.py_object]
        closure = tuple(ctypes.pythonapi.PyCell_New(c) for c in closure)
    globals_['__builtins__'] = __builtins__
    r = FunctionType(code, globals_, name, defaults, closure)
    r.__dict__ = func_dict
    r.__doc__ = doc
    if not PY2:
        r.__qualname__ = qualname
        r.__kwdefaults__ = kwdefaults
        r.__annotations__ = annotations
    return r
示例#3
0
def copy_func(func: FunctionType, deep: bool = False) -> FunctionType:
    """Copy a function as a different object.

    Args:
        func: Function object to be copied.
        deep: If ``True``, mutable attributes of ``func`` are deep-copied.

    Returns:
        Function as a different object from the original one.

    """
    copied = FunctionType(
        func.__code__,
        func.__globals__,
        func.__name__,
        func.__defaults__,
        func.__closure__,
    )

    # mutable attributes are copied by the given method
    copier = deepcopy if deep else copy
    copied.__annotations__ = copier(func.__annotations__)
    copied.__dict__ = copier(func.__dict__)
    copied.__kwdefaults__ = copier(func.__kwdefaults__)

    # immutable attributes are not copied (just assigned)
    copied.__doc__ = func.__doc__
    copied.__module__ = func.__module__
    copied.__name__ = func.__name__
    copied.__qualname__ = func.__qualname__

    return copied
示例#4
0
def buildFunction(baseFunc, code=None, glbls=None,
                  name=None, defaults=None,
                  kwdefaults=None, closure=None,
                  annotations=None, doc=None, dct=None):

    resf = None

    def _f():
        pass

    if hasattr(_f, 'func_code'):
        # Python 2.x
        resf = FunctionType(code or baseFunc.func_code,
                            glbls or baseFunc.func_globals,
                            name or baseFunc.func_name,
                            defaults or baseFunc.func_defaults,
                            closure or baseFunc.func_closure)
        resf.func_dict = dct or baseFunc.func_dict
        resf.func_doc = doc or baseFunc.func_doc

    else:
        # Python 3.x
        resf = FunctionType(code or baseFunc.__code__,
                            glbls or baseFunc.__globals__,
                            name or baseFunc.__name__,
                            defaults or baseFunc.__defaults__,
                            closure or baseFunc.__closure__)
        resf.__kwdefaults__ = kwdefaults or baseFunc.__kwdefaults__
        resf.__annotations__ = annotations or baseFunc.__annotations__
        resf.__dict__ = dct or baseFunc.__dict__
        resf.__doc__ = doc or baseFunc.__doc__

    return resf
示例#5
0
 def handle_deffun(self, func, fdict, fdoc, remote_globals):
   func = self.unpack(func)
   g = globals()
   glbls = {k:g[k] for k in remote_globals if k in g} if remote_globals is not None else g.copy()
   glbls.update(func[1])
   func[1].update(glbls)
   f = FunctionType(*func)
   f.__dict__ = self.unpack(fdict)
   f.__doc__ = self.unpack(fdoc)
   return self.pack(f)
示例#6
0
def _function_constructor(code, fglobals, name, argdefs, closure, kwdefaults, fdict, annotations, qualname,
                          doc,
                          module):
    func = FunctionType(code, fglobals, name, argdefs, closure)
    func.__kwdefaults__ = kwdefaults
    func.__dict__ = fdict
    func.__annotations__ = annotations
    func.__qualname__ = qualname
    func.__doc__ = doc
    func.__module__ = module
    return func
示例#7
0
 def handle_deffun(self, func, fdict, fdoc, remote_globals):
     func = self.unpack(func)
     g = globals()
     glbls = {k: g[k]
              for k in remote_globals
              if k in g} if remote_globals is not None else g.copy()
     glbls.update(func[1])
     func[1].update(glbls)
     f = FunctionType(*func)
     f.__dict__ = self.unpack(fdict)
     f.__doc__ = self.unpack(fdoc)
     return self.pack(f)
示例#8
0
def rebindFunction(f, rebindDir=None, **rebinds):
    '''return *f* with some globals rebound.'''
    d = {}
    if rebindDir: d.update(rebindDir)
    if rebinds: d.update(rebinds)
    if not d: return f
    f = getattr(f, 'im_func', f)
    fd = f.func_globals.copy()
    fd.update(d)
    nf = FunctionType(f.func_code, fd, f.func_name, f.func_defaults or ())
    nf.__doc__ = f.__doc__
    if f.__dict__ is not None: nf.__dict__ = f.__dict__.copy()
    return nf
示例#9
0
def loads_function(s):
    '''Restores a function serialized with :func:`dumps_function`.'''
    name, code, globals_, defaults, closure, func_dict, doc, qualname, kwdefaults, annotations = loads(s)
    code = marshal.loads(code)
    for k, v in globals_.items():
        if isinstance(v, Module):
            globals_[k] = v.mod
    if closure is not None:
        import ctypes
        ctypes.pythonapi.PyCell_New.restype = ctypes.py_object
        ctypes.pythonapi.PyCell_New.argtypes = [ctypes.py_object]
        closure = tuple(ctypes.pythonapi.PyCell_New(c) for c in closure)
    globals_['__builtins__'] = __builtins__
    r = FunctionType(code, globals_, name, defaults, closure)
    r.__dict__ = func_dict
    r.__doc__ = doc
    r.__qualname__ = qualname
    r.__kwdefaults__ = kwdefaults
    r.__annotations__ = annotations
    return r
示例#10
0
def buildFunction(baseFunc,
                  code=None,
                  glbls=None,
                  name=None,
                  defaults=None,
                  kwdefaults=None,
                  closure=None,
                  annotations=None,
                  doc=None,
                  dct=None):

    resf = None

    def _f():
        pass

    if hasattr(_f, 'func_code'):
        # Python 2.x
        resf = FunctionType(code or baseFunc.func_code, glbls
                            or baseFunc.func_globals, name
                            or baseFunc.func_name, defaults
                            or baseFunc.func_defaults, closure
                            or baseFunc.func_closure)
        resf.func_dict = dct or baseFunc.func_dict
        resf.func_doc = doc or baseFunc.func_doc

    else:
        # Python 3.x
        resf = FunctionType(code or baseFunc.__code__, glbls
                            or baseFunc.__globals__, name or baseFunc.__name__,
                            defaults or baseFunc.__defaults__, closure
                            or baseFunc.__closure__)
        resf.__kwdefaults__ = kwdefaults or baseFunc.__kwdefaults__
        resf.__annotations__ = annotations or baseFunc.__annotations__
        resf.__dict__ = dct or baseFunc.__dict__
        resf.__doc__ = doc or baseFunc.__doc__

    return resf
示例#11
0
def func2not_implemented(func):
    sig_str = func2clean_signature_str(func)
    if sig_str not in cache__sig_str2code:
        code = signature_str2not_implemented_func(sig_str).__code__
        cache__sig_str2code[sig_str] = code  # code really depends on sig_str
        #cache__not_implemented_codes.add(code)
        #print('cache__not_implemented_codes', len(cache__not_implemented_codes))
    else:
        code = cache__sig_str2code[sig_str]
    code_without_freevars = _replace_codestring(func.__code__, code)
    new = FunctionType(code_without_freevars, globals())
    new.__dict__.update(vars(func))

    new.__defaults__ = func.__defaults__
    new.__kwdefaults__ = func.__kwdefaults__
    new.__doc__ = func.__doc__
    new.__name__ = func.__name__
    new.__qualname__ = func.__qualname__
    new.__module__ = func.__module__
    new.__annotations__ = func.__annotations__
    new.__dict__ = dict(func.__dict__)
    return new
    set_func_not_implemented(func)
    return func
示例#12
0
def rebindFunction(f, rebindDir=None,
                   funcName=None, funcDoc=None,
                   argRebindDir=None, propRebindDir=None,
                   **rebinds):
  '''return a function derived from *f* with rebinds specified by *rebindDir* and/or *rebinds*.

  Use *funcName* as function name, instead of `f.func_name` as function
  name, if given.
  
  *argRebindDir* is a dictionary mapping function parameter names
  to defaults. You can use this to turn required parameters into optional
  ones (by providing a default value for them), to change their
  default values or to turn optional parameters into required ones.
  Note that Python requires that required arguments must preceed
  optional ones. A `ValueError` is raised when *argRebindDir* violates
  this restriction.
  Note: we only support simply named parameters (not constructor expressions).

  *propRebindDir* is a dictionary specifying rebinds for the
  functions properties.

  ATT: *f.func_globals* is copied at rebind time. Later modifications
  may affect *f* but not the rebind function.

  Note: we would like to rebind closure parts as well but Python currently
  does not allow to create `cell` instances. Thus, this would be difficult.
  '''
  # unwrap a method
  f = getattr(f, 'im_func', f)
  # handle global variable rebinds
  fg = f.func_globals.copy()
  if rebindDir: fg.update(rebindDir)
  if rebinds: fg.update(rebinds)
  # handle argument (default) rebinds
  if argRebindDir:
    args, _, _, defaults = getargspec(f)
    # ensure all arguments are known
    unknown = []
    for a in argRebindDir:
      if a not in args: unknown.append(a)
    if unknown:
      raise ValueError('unknown arguments in `argRebindDir`: %s'
                       % ', '.join(unknown)
                       )
    # determine new defaults
    defaults = defaults is not None and list(defaults) or []
    defaults = [REQUIRED] * (len(args) - len(defaults)) + defaults
    funcDefaults = []
    for (a,d) in zip(args, defaults):
      if isinstance(a, str) and a in argRebindDir: d = argRebindDir[a]
      if d is not REQUIRED: funcDefaults.append(d)
      elif funcDefaults: raise ValueError('required argument after optional one: %s' % a)
    funcDefaults = tuple(funcDefaults)
  else: funcDefaults = f.func_defaults or ()
  # construct the new function
  nf = FunctionType(
    f.func_code,
    fg, # func_globals
    funcName or f.func_name,
    funcDefaults,
    f.func_closure,
    )
  # handle the documentation
  if funcDoc is not None: nf.func_doc = funcDoc
  else: nf.func_doc = f.func_doc
  # handle is properties
  if f.__dict__ is not None: nf.__dict__ = f.__dict__.copy()
  if propRebindDir:
    if nf.__dict__ is None: nf.__dict__ = {}
    nf.__dict__.update(propRebindDir)
  return nf