From 770c5a0ed244901995148b906a5d234ad9c0ae40 Mon Sep 17 00:00:00 2001 From: David Stuebe Date: Sun, 29 Aug 2021 22:13:16 -0400 Subject: [PATCH] wip: working solution? --- dill/_dill.py | 7 ++++++- tests/test_objects.py | 30 +++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/dill/_dill.py b/dill/_dill.py index a5dbc9d8..84f9fc7a 100644 --- a/dill/_dill.py +++ b/dill/_dill.py @@ -31,6 +31,8 @@ def _trace(boolean): stack = dict() # record of 'recursion-sensitive' pickled objects +import abc + import os import sys diff = None @@ -1398,12 +1400,15 @@ def save_type(pickler, obj): elif obj.__module__ == '__main__': if issubclass(type(obj), type): # try: # used when pickling the class as code (or the interpreter) - if is_dill(pickler, child=True) and not pickler._byref: + if is_dill(pickler, child=True) and not pickler._byref and not issubclass(type(obj), abc.ABCMeta): # thanks to Tom Stepleton pointing out pickler._session unneeded _t = 'T2' log.info("%s: %s" % (_t, obj)) _dict = _dict_from_dictproxy(obj.__dict__) # except: # punt to StockPickler (pickle by class reference) + if issubclass(type(obj), abc.ABCMeta): + StockPickler.save_type(pickler, obj) + return else: log.info("T5: %s" % obj) name = getattr(obj, '__qualname__', getattr(obj, '__name__', None)) diff --git a/tests/test_objects.py b/tests/test_objects.py index b3888b2a..b0633689 100644 --- a/tests/test_objects.py +++ b/tests/test_objects.py @@ -23,6 +23,20 @@ #extend(False) #import cloudpickle as pickle +from abc import ABC, abstractmethod + + +class OneTwoThree(ABC): + + @abstractmethod + def foo(self): + pass + +class EasyAsAbc(OneTwoThree): + + def foo(self): + print('bar') + # helper objects class _class: def _method(self): @@ -33,13 +47,17 @@ def _method(self): special['LambdaType'] = _lambda = lambda x: lambda y: x special['MethodType'] = _method = _class()._method special['UnboundMethodType'] = _class._method +special['EasyAsABC'] = EasyAsAbc +special['easy_as_abc'] = EasyAsAbc() +special['OneTwoThree'] = OneTwoThree objects.update(special) def pickles(name, exact=False): """quick check if object pickles with dill""" obj = objects[name] try: - pik = pickle.loads(pickle.dumps(obj)) + res = pickle.dumps(obj) + pik = pickle.loads(res) if exact: try: assert pik == obj @@ -49,8 +67,13 @@ def pickles(name, exact=False): else: assert type(obj) == type(pik) except Exception: - print ("fails: %s %s" % (name, type(obj))) + print("fails: %s %s" % (name, type(obj))) + raise +def test_special(): + pickles("EasyAsABC", exact=False) + pickles("OneTwoThree", exact=False) + pickles("easy_as_abc", exact=False) def test_objects(): for member in objects.keys(): @@ -59,4 +82,5 @@ def test_objects(): if __name__ == '__main__': - test_objects() + # test_objects() + test_lambda()