From e9063081529ecd0722143476997fe4952ed697fc Mon Sep 17 00:00:00 2001 From: Valentyn Tymofieiev Date: Fri, 24 Mar 2023 20:54:38 -0700 Subject: [PATCH] Patch to serialize _abc_data. --- dill/_dill.py | 2 ++ dill/tests/test_classdef.py | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/dill/_dill.py b/dill/_dill.py index a03a78b2..c36ec360 100644 --- a/dill/_dill.py +++ b/dill/_dill.py @@ -1768,6 +1768,8 @@ def save_type(pickler, obj, postproc_list=None): for name in slots: _dict.pop(name, None) + if isinstance(obj, abc.ABCMeta) and '_abc_impl' in _dict: + del _dict['_abc_impl'] qualname = getattr(obj, '__qualname__', None) if attrs is not None: diff --git a/dill/tests/test_classdef.py b/dill/tests/test_classdef.py index 8ad17cb7..35e658a3 100644 --- a/dill/tests/test_classdef.py +++ b/dill/tests/test_classdef.py @@ -6,6 +6,7 @@ # License: 3-clause BSD. The full license text is available at: # - https://github.com/uqfoundation/dill/blob/master/LICENSE +import abc import dill from enum import EnumMeta import sys @@ -276,6 +277,24 @@ def test_enummeta(): assert dill.copy(HTTPStatus.OK) is HTTPStatus.OK assert dill.copy(enum.EnumMeta) is enum.EnumMeta +def test_abc_data(): + class MyMeta(metaclass=abc.ABCMeta): + _not_abc_impl = 1 + # Make sure dill tries to serialise the class, not just pickle it by name. + # It needs to be in __main__ for dill to serialise it. + MyMeta.__module__ = '__main__' + class MyImpl: + pass + MyMeta.register(MyImpl) + + assert isinstance (MyImpl(), MyMeta) + cls = dill.loads(dill.dumps(MyMeta)) + # Dill doesn't serialise the ABC registry, although it's not clear if + # that's on purpose or not. + assert not isinstance (MyImpl(), cls) + cls.register(MyImpl) + assert isinstance (MyImpl(), cls) + if __name__ == '__main__': test_class_instances() test_class_objects() @@ -289,3 +308,4 @@ def test_enummeta(): test_origbases() test_metaclass() test_enummeta() + test_abc_data()