Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement reduce for objects derived from abstract decorators #369

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ jobs:
python -m pip install -r dev-requirements.txt
python ci/install_coverage_subprocess_pth.py
export
- name: Install optional typing_extensions in Python 3.6
- name: Install optional typing_extensions in Python 3.5 and 3.6
shell: bash
run: python -m pip install typing-extensions
if: matrix.python_version == '3.6'
run: python -m pip install typing-extensions dataclasses
if: matrix.python_version == '3.5' || matrix.python_version == '3.6'
- name: Display Python version
shell: bash
run: python -c "import sys; print(sys.version)"
Expand Down
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