#!/usr/bin/env python
#
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
# Copyright (c) 2008-2016 California Institute of Technology.
# Copyright (c) 2016-2023 The Uncertainty Quantification Foundation.
# License: 3-clause BSD. The full license text is available at:
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
import dill
from enum import EnumMeta
import sys
dill.settings['recurse'] = True
# test classdefs
class _class:
def _method(self):
pass
def ok(self):
return True
class _class2:
def __call__(self):
pass
def ok(self):
return True
class _newclass(object):
def _method(self):
pass
def ok(self):
return True
class _newclass2(object):
def __call__(self):
pass
def ok(self):
return True
class _meta(type):
pass
def __call__(self):
pass
def ok(self):
return True
_mclass = _meta("_mclass", (object,), {"__call__": __call__, "ok": ok})
del __call__
del ok
o = _class()
oc = _class2()
n = _newclass()
nc = _newclass2()
m = _mclass()
if sys.hexversion < 0x03090000:
import typing
class customIntList(typing.List[int]):
pass
else:
class customIntList(list[int]):
pass
# test pickles for class instances
def test_class_instances():
assert dill.pickles(o)
assert dill.pickles(oc)
assert dill.pickles(n)
assert dill.pickles(nc)
assert dill.pickles(m)
def test_class_objects():
clslist = [_class,_class2,_newclass,_newclass2,_mclass]
objlist = [o,oc,n,nc,m]
_clslist = [dill.dumps(obj) for obj in clslist]
_objlist = [dill.dumps(obj) for obj in objlist]
for obj in clslist:
globals().pop(obj.__name__)
del clslist
for obj in ['o','oc','n','nc']:
globals().pop(obj)
del objlist
del obj
for obj,cls in zip(_objlist,_clslist):
_cls = dill.loads(cls)
_obj = dill.loads(obj)
assert _obj.ok()
assert _cls.ok(_cls())
if _cls.__name__ == "_mclass":
assert type(_cls).__name__ == "_meta"
# test NoneType
def test_specialtypes():
assert dill.pickles(type(None))
assert dill.pickles(type(NotImplemented))
assert dill.pickles(type(Ellipsis))
assert dill.pickles(type(EnumMeta))
from collections import namedtuple
Z = namedtuple("Z", ['a','b'])
Zi = Z(0,1)
X = namedtuple("Y", ['a','b'])
X.__name__ = "X"
X.__qualname__ = "X" #XXX: name must 'match' or fails to pickle
Xi = X(0,1)
Bad = namedtuple("FakeName", ['a','b'])
Badi = Bad(0,1)
Defaults = namedtuple('Defaults', ['x', 'y'], defaults=[1])
Defaultsi = Defaults(2)
# test namedtuple
def test_namedtuple():
assert Z is dill.loads(dill.dumps(Z))
assert Zi == dill.loads(dill.dumps(Zi))
assert X is dill.loads(dill.dumps(X))
assert Xi == dill.loads(dill.dumps(Xi))
assert Defaults is dill.loads(dill.dumps(Defaults))
assert Defaultsi == dill.loads(dill.dumps(Defaultsi))
assert Bad is not dill.loads(dill.dumps(Bad))
assert Bad._fields == dill.loads(dill.dumps(Bad))._fields
assert tuple(Badi) == tuple(dill.loads(dill.dumps(Badi)))
class A:
class B(namedtuple("C", ["one", "two"])):
'''docstring'''
B.__module__ = 'testing'
a = A()
assert dill.copy(a)
assert dill.copy(A.B).__name__ == 'B'
assert dill.copy(A.B).__qualname__.endswith('.