def copy_function_with_closure(old_func, updated_module,
updated_wrapped_func):
"""Copies a function, updating it's globals to point to updated_module.
This works for singly-wrapped function (ie, closure has len 1).
"""
assert old_func.__closure__ and len(old_func.__closure__) == 1
cell = make_cell()
PyCell_Set = ctypes.pythonapi.PyCell_Set
# ctypes.pythonapi functions need to have argtypes and restype set manually
PyCell_Set.argtypes = (ctypes.py_object, ctypes.py_object)
# restype actually defaults to c_int here, but we might as well be explicit
PyCell_Set.restype = ctypes.c_int
PyCell_Set(cell, updated_wrapped_func)
new_closure = (cell,)
new_func = types.FunctionType(old_func.__code__, updated_module.__dict__,
name=old_func.__name__,
argdefs=old_func.__defaults__,
closure=new_closure)
new_func.__dict__.update(old_func.__dict__)
new_func.__module__ = updated_module.__name__
return new_func
评论列表
文章目录