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

Cannot pickle classes derived from ABC with abc.abstract* decorators #367

Closed
KristianHolsheimer opened this issue May 14, 2020 · 4 comments · Fixed by #450
Closed

Cannot pickle classes derived from ABC with abc.abstract* decorators #367

KristianHolsheimer opened this issue May 14, 2020 · 4 comments · Fixed by #450

Comments

@KristianHolsheimer
Copy link

This may be an issue specific to Python 3.8, but I'm unable to cloudpickle objects whose class is derived from an abc.ABC derived base class with either one of these decorators:

  • abc.abstractproperty
  • abc.abstractclassmethod
  • abc.abstractstaticmethod

Note: abc.abstractmethod appears to be fine.

Here's a simple test case (that currently fails):

def test_abstracts():
    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()
    depickled_obj = pickle_depickle(my_object)  # TypeError: cannot pickle ... object

See also joblib/joblib#989

@ssanderson
Copy link

They're probably widely used enough that it'd be nice for cloudpickle to support them, but FYI, abstractproperty, abstractclassmethod, and abstractstaticmethod have been deprecated since Python 3.3. The preferred usage, according to the Python docs, is:

@classmethod
@abc.abstractmethod
def the_method(cls, ...):
    ...

(and similarly for property and staticmethod).

@KristianHolsheimer
Copy link
Author

You're right, they are. Perhaps it might be better to send some PRs upstream to use the preferred usage.

I tried putting together a quick PR, but it seemed to break things for python versions < 3.8.

@ogrisel
Copy link
Contributor

ogrisel commented May 20, 2020

They're probably widely used enough that it'd be nice for cloudpickle to support them, but FYI, abstractproperty, abstractclassmethod, and abstractstaticmethod have been deprecated since Python 3.3.

Indeed, thanks for the notice. I would consider reviewing a PR that add support for them but no time to work on it myself.

@ogrisel
Copy link
Contributor

ogrisel commented May 20, 2020

I have improved the tests in #371 to check that the pattern described by @ssanderson works as expected with cloudpickle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants