-
Notifications
You must be signed in to change notification settings - Fork 187
Closed
Description
using functools.wraps
functools.wraps(f)
def g():
passchanges a g's __module__ attribute to f.__module__, but not its __globals__. Because we retrieve globals from state['module'] at unpickling time, this will pollute a depickled version of g with the globals of f.__module__
As an illustration:
import functools
import pickle
import cloudpickle
@functools.wraps(pickle._dumps)
def f():
pass
depickled_f = pickle.loads(cloudpickle.dumps(f))
assert depickled_f.__globals__ is vars(pickle)passes.
This is tricky:
On one hand one can spot if a function is wrapping another by checking for a __wrapped__ attribute. On the other hand, once wraps is used, there is no way back, and f's attributes are lost forever.
The side effects are not life threatening, but this may be worth adding a warning at pickling time. I am thinking about (roughly):
if hasattr(func, '__wrapped__'):
msg = ("This function seems decorated by functools.wraps. This"
" may cause {}'s __globals__ to be populated with"
" unnecessary global variables at unpickling time."
" To fix it, change the assigned argument of"
" functools.wraps so that is does not include __module__ ")
raise UserWarning(msg.format(func.__code__.co_name))Inside extract_func_data.
Metadata
Metadata
Assignees
Labels
No labels