From 228cde7079922ead6676d118e78492875c3ebbbb Mon Sep 17 00:00:00 2001 From: anivegesana Date: Mon, 9 May 2022 19:33:17 -0700 Subject: [PATCH] Create a soft_def shim to combine move_to and Getattr --- dill/_shims.py | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/dill/_shims.py b/dill/_shims.py index 6bda5136..0a7814b2 100644 --- a/dill/_shims.py +++ b/dill/_shims.py @@ -150,11 +150,43 @@ def decorator(func): return func return decorator +def soft_def(name, default): + """ + A easier to understand and more compact way of "softly" defining a function. + These two pieces of code are equivalent: + + if _dill.OLD3X: + def _create_class(): + ... + _create_class = soft_def('_create_class', types.new_class) + + if _dill.OLD3X: + @move_to(_dill) + def _create_class(): + ... + _create_class = Getattr(_dill, '_create_class', types.new_class) + + Intuitively, it creates a function or object in the versions of dill/python + that require special reimplementations, and use a core library or default + implementation if that function or object does not exist. + """ + func = globals().get(name) + if func is not None: + _dill.__dict__[fname] = func + func.__module__ = _dill.__name__ + + if default is Getattr.NO_DEFAULT: + reduction = (getattr, (_dill, name)) + else: + reduction = (getattr, (_dill, name, default)) + + return Reduce(*reduction, is_callable=callable(default)) + ###################### ## Compatibility Shims are defined below ###################### -_CELL_EMPTY = Getattr(_dill, '_CELL_EMPTY', None) +_CELL_EMPTY = soft_def('_CELL_EMPTY', None) if _dill.OLD37: if _dill.HAS_CTYPES and hasattr(_dill.ctypes, 'pythonapi') and hasattr(_dill.ctypes.pythonapi, 'PyCell_Set'): @@ -163,7 +195,6 @@ def decorator(func): _PyCell_Set = ctypes.pythonapi.PyCell_Set - @move_to(_dill) def _setattr(object, name, value): if type(object) is _dill.CellType and name == 'cell_contents': _PyCell_Set.argtypes = (ctypes.py_object, ctypes.py_object) @@ -171,7 +202,6 @@ def _setattr(object, name, value): else: setattr(object, name, value) - @move_to(_dill) def _delattr(object, name): if type(object) is _dill.CellType and name == 'cell_contents': _PyCell_Set.argtypes = (ctypes.py_object, ctypes.c_void_p) @@ -195,7 +225,6 @@ def cell_setter(value): func(value) else: setattr(cell, name, value)''' % __nonlocal) - move_to(_dill)(_setattr) exec('''def _delattr(cell, name): if type(cell) is _dill.CellType and name == 'cell_contents': @@ -210,7 +239,6 @@ def cell_deleter(): func() else: delattr(cell, name)''' % __nonlocal) - move_to(_dill)(_delattr) else: # Likely PyPy 2.7. Simulate the nonlocal keyword with bytecode @@ -221,7 +249,6 @@ def cell_deleter(): # Copyright (c) 2012, Regents of the University of California. # Copyright (c) 2009 `PiCloud, Inc. `_. # License: https://github.com/cloudpipe/cloudpickle/blob/master/LICENSE - @move_to(_dill) def _setattr(cell, name, value): if type(cell) is _dill.CellType and name == 'cell_contents': _cell_set = _dill.FunctionType( @@ -255,12 +282,11 @@ def _cell_set_factory(value): del co - @move_to(_dill) def _delattr(cell, name): if type(cell) is _dill.CellType and name == 'cell_contents': pass else: delattr(cell, name) -_setattr = Getattr(_dill, '_setattr', setattr) -_delattr = Getattr(_dill, '_delattr', delattr) +_setattr = soft_def('_setattr', setattr) +_delattr = soft_def('_delattr', delattr)