Skip to content

Commit

Permalink
Create a soft_def shim to combine move_to and Getattr (#473)
Browse files Browse the repository at this point in the history
* Create a soft_def shim to combine move_to and Getattr

* Rename `soft_def` to `register_shim`
  • Loading branch information
anivegesana committed Jun 9, 2022
1 parent 4462409 commit a6bf9a2
Showing 1 changed file with 35 additions and 9 deletions.
44 changes: 35 additions & 9 deletions dill/_shims.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,43 @@ def decorator(func):
return func
return decorator

def register_shim(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 = register_shim('_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__[name] = 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 = register_shim('_CELL_EMPTY', None)

if _dill.OLD37:
if _dill.HAS_CTYPES and hasattr(_dill.ctypes, 'pythonapi') and hasattr(_dill.ctypes.pythonapi, 'PyCell_Set'):
Expand All @@ -163,15 +195,13 @@ 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)
_PyCell_Set(object, 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)
Expand All @@ -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':
Expand All @@ -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
Expand All @@ -221,7 +249,6 @@ def cell_deleter():
# Copyright (c) 2012, Regents of the University of California.
# Copyright (c) 2009 `PiCloud, Inc. <http://www.picloud.com>`_.
# 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(
Expand Down Expand Up @@ -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 = register_shim('_setattr', setattr)
_delattr = register_shim('_delattr', delattr)

0 comments on commit a6bf9a2

Please sign in to comment.