Skip to content

Commit

Permalink
Use bare FunctionType instead of _create_function()
Browse files Browse the repository at this point in the history
  • Loading branch information
leogama committed May 16, 2022
1 parent d2f916c commit 1476818
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 18 deletions.
21 changes: 3 additions & 18 deletions dill/_dill.py
Original file line number Diff line number Diff line change
Expand Up @@ -756,22 +756,6 @@ def _load_type(name):
def _create_type(typeobj, *args):
return typeobj(*args)

def _create_function(fcode, fglobals, fname=None, fdefaults=None,
fclosure=None, fdict=None, fkwdefaults=None):
# same as FunctionType, but enable passing __dict__ to new function,
# __dict__ is the storehouse for attributes added after function creation
func = FunctionType(fcode, fglobals or dict(), fname, fdefaults, fclosure)
if fdict is not None:
func.__dict__.update(fdict) #XXX: better copy? option to copy?
if fkwdefaults is not None:
func.__kwdefaults__ = fkwdefaults
# 'recurse' only stores referenced modules/objects in fglobals,
# thus we need to make sure that we have __builtins__ as well
if "__builtins__" not in func.__globals__:
func.__globals__["__builtins__"] = globals()["__builtins__"]
# assert id(fglobals) == id(func.__globals__)
return func

def _create_code(*args):
if PY3 and hasattr(args[-3], 'encode'): #FIXME: from PY2 fails (optcode)
args = list(args)
Expand Down Expand Up @@ -1905,6 +1889,7 @@ def save_function(pickler, obj):
# recurse to get all globals referred to by obj
from .detect import globalvars
globs_copy = globalvars(obj, recurse=True, builtin=True)
globs_copy.setdefault('__builtins__', globals()['__builtins__'])

# Add the name of the module to the globs dictionary to prevent
# the duplication of the dictionary. Pickle the unpopulated
Expand Down Expand Up @@ -1960,7 +1945,7 @@ def save_function(pickler, obj):
if state_dict:
state = state, state_dict

_save_with_postproc(pickler, (_create_function, (
_save_with_postproc(pickler, (FunctionType, (
obj.__code__, globs, obj.__name__, obj.__defaults__,
closure
), state), obj=obj, postproc_list=postproc_list)
Expand All @@ -1973,7 +1958,7 @@ def save_function(pickler, obj):
if obj.__dict__:
postproc_list.append((setattr, (obj, '__dict__', obj.__dict__)))

_save_with_postproc(pickler, (_create_function, (
_save_with_postproc(pickler, (FunctionType, (
obj.func_code, globs, obj.func_name, obj.func_defaults,
closure
)), obj=obj, postproc_list=postproc_list)
Expand Down
19 changes: 19 additions & 0 deletions dill/_shims.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,22 @@ def _delattr(cell, name):

_setattr = Getattr(_dill, '_setattr', setattr)
_delattr = Getattr(_dill, '_delattr', delattr)


# Kept for backward compatibility, substituted by bare FunctionType.
@move_to(_dill)
def _create_function(fcode, fglobals, fname=None, fdefaults=None,
fclosure=None, fdict=None, fkwdefaults=None):
# 'recurse' only stores referenced modules/objects in fglobals,
# thus we need to make sure that we have __builtins__ as well
if fglobals is None:
fglobals = {}
fglobals.setdefault('__builtins__', globals()['__builtins__'])
# same as FunctionType, but enable passing __dict__ to new function,
# __dict__ is the storehouse for attributes added after function creation
func = _dill.FunctionType(fcode, fglobals, fname, fdefaults, fclosure)
if fdict:
func.__dict__.update(fdict) #XXX: better copy? option to copy?
if fkwdefaults is not None:
func.__kwdefaults__ = fkwdefaults
return func

0 comments on commit 1476818

Please sign in to comment.