A closure binds to a free variable, not it's value. For a self-referencing closure, all Python needs to do is create a closure for the free fact
name first (not yet bound to anything), create the function object with the closure, and then bind fact
to that object.
As such, you need to combine creating a closure and a function into the same outer function, such that you create a closure to the name the function is going to be bound to:
def create_closure_and_function(*args):
func = None
def create_function_closure():
return func
closure = create_function_closure.__closure__
func = types.FunctionType(*args[:-1] + [closure])
return func
To make this work with unpickling you'd have to loop over the closure argument (args[-1]
) and detect where there is a recursion, and replace that one item with create_function_closure.__closure__[0]
, I suppose.