Skip to content

Commit

Permalink
Implement reduce for objects derived from abstract decorators (cloudp…
Browse files Browse the repository at this point in the history
  • Loading branch information
KristianHolsheimer committed May 14, 2020
1 parent 70dc1df commit 414217f
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
6 changes: 5 additions & 1 deletion cloudpickle/cloudpickle_fast.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ def _root_logger_reduce(obj):


def _property_reduce(obj):
return property, (obj.fget, obj.fset, obj.fdel, obj.__doc__)
return type(obj), (obj.fget, obj.fset, obj.fdel, obj.__doc__)


def _weakset_reduce(obj):
Expand Down Expand Up @@ -424,6 +424,10 @@ class CloudPickler(Pickler):
dispatch[types.MappingProxyType] = _mappingproxy_reduce
dispatch[weakref.WeakSet] = _weakset_reduce
dispatch[typing.TypeVar] = _typevar_reduce
dispatch[abc.abstractmethod] = _classmethod_reduce
dispatch[abc.abstractclassmethod] = _classmethod_reduce
dispatch[abc.abstractstaticmethod] = _classmethod_reduce
dispatch[abc.abstractproperty] = _property_reduce

def __init__(self, file, protocol=None, buffer_callback=None):
if protocol is None:
Expand Down
55 changes: 53 additions & 2 deletions tests/cloudpickle_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1278,8 +1278,6 @@ def read_write_value(self):
def read_write_value(self, value):
self._read_write_value = value



my_object = MyObject()

assert my_object.read_only_value == 1
Expand All @@ -1303,6 +1301,59 @@ def read_write_value(self, value):
assert depickled_obj.read_write_value == 3
type(depickled_obj).read_only_value.__doc__ == "A read-only attribute"

def test_abstracts(self):
class Base(abc.ABC):
_value = 'initial_value'

@abc.abstractmethod
def my_method(self):
pass

@abc.abstractclassmethod
def my_classmethod(cls):
pass

@abc.abstractstaticmethod
def my_staticmethod():
pass

@abc.abstractproperty
def my_property(self):
pass

class Derived(Base):
def my_method(self):
return 'my_method'

@classmethod
def my_classmethod(cls):
return 'my_classmethod'

@staticmethod
def my_staticmethod():
return 'my_staticmethod'

@property
def my_property(self):
return self._value

@my_property.setter
def my_property(self, new_value):
self._value = new_value

my_object = Derived()

assert my_object.my_property == 'initial_value'
my_object.my_property = 'new_value'
assert my_object.my_property == 'new_value'
assert Derived._value == 'initial_value'
assert Base._value == 'initial_value'

depickled_obj = pickle_depickle(my_object)

assert depickled_obj.my_property == 'new_value'
assert type(depickled_obj) is Derived
assert isinstance(depickled_obj, Base)

def test_namedtuple(self):
MyTuple = collections.namedtuple('MyTuple', ['a', 'b', 'c'])
Expand Down

0 comments on commit 414217f

Please sign in to comment.