diff --git a/tests/test_check.py b/tests/test_check.py index e357dbc7..4b3bad73 100644 --- a/tests/test_check.py +++ b/tests/test_check.py @@ -8,14 +8,14 @@ from __future__ import with_statement from dill import check +import sys + from dill.temp import capture from dill.dill import PY3 -import sys -f = lambda x:x**2 #FIXME: this doesn't catch output... it's from the internal call -def test(func, **kwds): +def raise_check(func, **kwds): try: with capture('stdout') as out: check(func, **kwds) @@ -28,19 +28,40 @@ def test(func, **kwds): out.close() -if __name__ == '__main__': - test(f) - test(f, recurse=True) - test(f, byref=True) - test(f, protocol=0) - #TODO: test incompatible versions - # SyntaxError: invalid syntax +f = lambda x:x**2 + + +def test_simple(): + raise_check(f) + + +def test_recurse(): + raise_check(f, recurse=True) + + +def test_byref(): + raise_check(f, byref=True) + + +def test_protocol(): + raise_check(f, protocol=True) + + +def test_python(): if PY3: - test(f, python='python3.4') + raise_check(f, python='python3.4') else: - test(f, python='python2.7') - #TODO: test dump failure - #TODO: test load failure + raise_check(f, python='python2.7') + +#TODO: test incompatible versions +#TODO: test dump failure +#TODO: test load failure -# EOF + +if __name__ == '__main__': + test_simple() + test_recurse() + test_byref() + test_protocol() + test_python() diff --git a/tests/test_extendpickle.py b/tests/test_extendpickle.py index 553b6653..59d84400 100644 --- a/tests/test_extendpickle.py +++ b/tests/test_extendpickle.py @@ -12,20 +12,27 @@ except ImportError: from io import BytesIO as StringIO + def my_fn(x): return x * 17 -obj = lambda : my_fn(34) -assert obj() == 578 -obj_io = StringIO() -pickler = pickle.Pickler(obj_io) -pickler.dump(obj) +def test_extend(): + obj = lambda : my_fn(34) + assert obj() == 578 + + obj_io = StringIO() + pickler = pickle.Pickler(obj_io) + pickler.dump(obj) + + obj_str = obj_io.getvalue() + + obj2_io = StringIO(obj_str) + unpickler = pickle.Unpickler(obj2_io) + obj2 = unpickler.load() -obj_str = obj_io.getvalue() + assert obj2() == 578 -obj2_io = StringIO(obj_str) -unpickler = pickle.Unpickler(obj2_io) -obj2 = unpickler.load() -assert obj2() == 578 +if __name__ == '__main__': + test_extend() diff --git a/tests/test_file.py b/tests/test_file.py index f18879c2..64fc9fac 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -6,11 +6,14 @@ # License: 3-clause BSD. The full license text is available at: # - http://trac.mystic.cacr.caltech.edu/project/pathos/browser/dill/LICENSE -import dill -import random import os import sys import string +import random + +import dill + + dill.settings['recurse'] = True fname = "_test_file.txt" @@ -21,6 +24,7 @@ buffer_error = ValueError("invalid buffer size") dne_error = FileNotFoundError("[Errno 2] No such file or directory: '%s'" % fname) + def write_randomness(number=200): f = open(fname, "w") for i in range(number): @@ -45,7 +49,17 @@ def throws(op, args, exc): return False -def test(strictio, fmode): +def teardown_module(): + if os.path.exists(fname): + os.remove(fname) + + +def bench(strictio, fmode, skippypy): + import platform + if skippypy and platform.python_implementation() == 'PyPy': + # Skip for PyPy... + return + # file exists, with same contents # read @@ -462,18 +476,27 @@ def test(strictio, fmode): f2.close() -if __name__ == '__main__': +def test_nostrictio_handlefmode(): + bench(False, dill.HANDLE_FMODE, False) + teardown_module() - test(strictio=False, fmode=dill.HANDLE_FMODE) - test(strictio=False, fmode=dill.FILE_FMODE) - if not dill.dill.IS_PYPY: #FIXME: fails due to pypy/issues/1233 - test(strictio=False, fmode=dill.CONTENTS_FMODE) - #test(strictio=True, fmode=dill.HANDLE_FMODE) - #test(strictio=True, fmode=dill.FILE_FMODE) - #test(strictio=True, fmode=dill.CONTENTS_FMODE) +def test_nostrictio_filefmode(): + bench(False, dill.FILE_FMODE, False) + teardown_module() -if os.path.exists(fname): - os.remove(fname) -# EOF +def test_nostrictio_contentsfmode(): + bench(False, dill.CONTENTS_FMODE, True) + teardown_module() + + +#bench(True, dill.HANDLE_FMODE, False) +#bench(True, dill.FILE_FMODE, False) +#bench(True, dill.CONTENTS_FMODE, True) + + +if __name__ == '__main__': + test_nostrictio_handlefmode() + test_nostrictio_filefmode() + test_nostrictio_contentsfmode() diff --git a/tests/test_functors.py b/tests/test_functors.py index 1d408294..5d70f756 100644 --- a/tests/test_functors.py +++ b/tests/test_functors.py @@ -10,21 +10,30 @@ import dill dill.settings['recurse'] = True + def f(a, b, c): # without keywords pass + def g(a, b, c=2): # with keywords pass + def h(a=1, b=2, c=3): # without args pass -fp = functools.partial(f, 1, 2) -gp = functools.partial(g, 1, c=2) -hp = functools.partial(h, 1, c=2) -bp = functools.partial(int, base=2) -assert dill.pickles(fp, safe=True) -assert dill.pickles(gp, safe=True) -assert dill.pickles(hp, safe=True) -assert dill.pickles(bp, safe=True) +def test_functools(): + fp = functools.partial(f, 1, 2) + gp = functools.partial(g, 1, c=2) + hp = functools.partial(h, 1, c=2) + bp = functools.partial(int, base=2) + + assert dill.pickles(fp, safe=True) + assert dill.pickles(gp, safe=True) + assert dill.pickles(hp, safe=True) + assert dill.pickles(bp, safe=True) + + +if __name__ == '__main__': + test_functools() diff --git a/tests/test_mixins.py b/tests/test_mixins.py index 8313410d..65afc2fb 100644 --- a/tests/test_mixins.py +++ b/tests/test_mixins.py @@ -9,6 +9,7 @@ import dill dill.settings['recurse'] = True + def wtf(x,y,z): def zzz(): return x @@ -18,6 +19,7 @@ def xxx(): return z return zzz,yyy + def quad(a=1, b=1, c=0): inverted = [False] def invert(): @@ -38,8 +40,10 @@ def func(*args, **kwds): def double_add(*args): return sum(args) + fx = sum([1,2,3]) + ### to make it interesting... def quad_factory(a=1,b=1,c=0): def dec(f): @@ -49,25 +53,28 @@ def func(*args,**kwds): return func return dec + @quad_factory(a=0,b=4,c=0) def quadish(x): return x+1 + quadratic = quad_factory() + def doubler(f): def inner(*args, **kwds): fx = f(*args, **kwds) return 2*fx return inner + @doubler def quadruple(x): return 2*x -if __name__ == '__main__': - +def test_mixins(): # test mixins assert double_add(1,2,3) == 2*fx double_add.invert() @@ -110,4 +117,5 @@ def quadruple(x): #***** -# EOF +if __name__ == '__main__': + test_mixins() diff --git a/tests/test_nested.py b/tests/test_nested.py index bce97af9..bb49ebe1 100644 --- a/tests/test_nested.py +++ b/tests/test_nested.py @@ -9,10 +9,12 @@ test dill's ability to handle nested functions """ +import os +import math + import dill as pickle pickle.settings['recurse'] = True -import math -#import pickle + # the nested function: pickle should fail here, but dill is ok. def adder(augend): @@ -22,6 +24,7 @@ def inner(addend): return addend + augend + zero[0] return inner + # rewrite the nested function using a class: standard pickle should work here. class cadder(object): def __init__(self, augend): @@ -31,6 +34,7 @@ def __init__(self, augend): def __call__(self, addend): return addend + self.augend + self.zero[0] + # rewrite again, but as an old-style class class c2adder: def __init__(self, augend): @@ -40,22 +44,22 @@ def __init__(self, augend): def __call__(self, addend): return addend + self.augend + self.zero[0] -# some basic stuff -a = [0, 1, 2] # some basic class stuff class basic(object): pass + class basic2: pass -if __name__ == '__main__': - x = 5 - y = 1 +x = 5 +y = 1 + - # pickled basic stuff +def test_basic(): + a = [0, 1, 2] pa = pickle.dumps(a) pmath = pickle.dumps(math) #XXX: FAILS in pickle pmap = pickle.dumps(map) @@ -65,46 +69,49 @@ class basic2: lmap = pickle.loads(pmap) assert list(map(math.sin, a)) == list(lmap(lmath.sin, la)) - # pickled basic class stuff + +def test_basic_class(): pbasic2 = pickle.dumps(basic2) _pbasic2 = pickle.loads(pbasic2)() pbasic = pickle.dumps(basic) _pbasic = pickle.loads(pbasic)() - # pickled c2adder + +def test_c2adder(): pc2adder = pickle.dumps(c2adder) pc2add5 = pickle.loads(pc2adder)(x) assert pc2add5(y) == x+y - # pickled cadder + +def test_pickled_cadder(): pcadder = pickle.dumps(cadder) pcadd5 = pickle.loads(pcadder)(x) assert pcadd5(y) == x+y - # raw adder and inner + +def test_raw_adder_and_inner(): add5 = adder(x) assert add5(y) == x+y - # pickled adder + +def test_pickled_adder(): padder = pickle.dumps(adder) padd5 = pickle.loads(padder)(x) assert padd5(y) == x+y - # pickled inner + +def test_pickled_inner(): + add5 = adder(x) pinner = pickle.dumps(add5) #XXX: FAILS in pickle p5add = pickle.loads(pinner) assert p5add(y) == x+y - # testing moduledict where not __main__ + +def test_moduledict_where_not_main(): try: - import test_moduledict - error = None + from . import test_moduledict except: - import sys - error = sys.exc_info()[1] - assert error is None - # clean up - import os + import test_moduledict name = 'test_moduledict.py' if os.path.exists(name) and os.path.exists(name+'c'): os.remove(name+'c') @@ -117,4 +124,12 @@ class basic2: os.removedirs("__pycache__") -# EOF +if __name__ == '__main__': + test_basic() + test_basic_class() + test_c2adder() + test_pickled_cadder() + test_raw_adder_and_inner() + test_pickled_adder() + test_pickled_inner() + test_moduledict_where_not_main() diff --git a/tests/test_objects.py b/tests/test_objects.py index 989cc35d..72b9e1e3 100644 --- a/tests/test_objects.py +++ b/tests/test_objects.py @@ -27,7 +27,7 @@ class _class: def _method(self): pass - + # objects that *fail* if imported special = {} special['LambdaType'] = _lambda = lambda x: lambda y: x @@ -50,14 +50,13 @@ def pickles(name, exact=False): assert type(obj) == type(pik) except Exception: print ("fails: %s %s" % (name, type(obj))) - return - -if __name__ == '__main__': +def test_objects(): for member in objects.keys(): #pickles(member, exact=True) pickles(member, exact=False) -# EOF +if __name__ == '__main__': + test_objects() diff --git a/tests/test_properties.py b/tests/test_properties.py index 093428e7..1428d32b 100644 --- a/tests/test_properties.py +++ b/tests/test_properties.py @@ -6,9 +6,10 @@ # License: 3-clause BSD. The full license text is available at: # - http://trac.mystic.cacr.caltech.edu/project/pathos/browser/dill/LICENSE +import sys + import dill dill.settings['recurse'] = True -import sys class Foo(object): @@ -24,26 +25,38 @@ def _set_data(self, x): data = property(_get_data, _set_data) -FooS = dill.copy(Foo) - -assert FooS.data.fget is not None -assert FooS.data.fset is not None -assert FooS.data.fdel is None - -try: - res = FooS().data -except Exception: - e = sys.exc_info()[1] - raise AssertionError(str(e)) -else: - assert res == 1 - -try: - f = FooS() - f.data = 1024 - res = f.data -except Exception: - e = sys.exc_info()[1] - raise AssertionError(str(e)) -else: - assert res == 1024 +def test_data_not_none(): + FooS = dill.copy(Foo) + assert FooS.data.fget is not None + assert FooS.data.fset is not None + assert FooS.data.fdel is None + + +def test_data_unchanged(): + FooS = dill.copy(Foo) + try: + res = FooS().data + except Exception: + e = sys.exc_info()[1] + raise AssertionError(str(e)) + else: + assert res == 1 + + +def test_data_changed(): + FooS = dill.copy(Foo) + try: + f = FooS() + f.data = 1024 + res = f.data + except Exception: + e = sys.exc_info()[1] + raise AssertionError(str(e)) + else: + assert res == 1024 + + +if __name__ == '__main__': + test_data_not_none() + test_data_unchanged() + test_data_changed() diff --git a/tests/test_weakref.py b/tests/test_weakref.py index 3ac4e7f6..082e5cce 100644 --- a/tests/test_weakref.py +++ b/tests/test_weakref.py @@ -29,43 +29,49 @@ def __call__(self): def _function(): pass -o = _class() -oc = _class2() -n = _newclass() -nc = _newclass2() -f = _function -z = _class -x = _newclass -r = weakref.ref(o) -dr = weakref.ref(_class()) -p = weakref.proxy(o) -dp = weakref.proxy(_class()) -c = weakref.proxy(oc) -dc = weakref.proxy(_class2()) +def test_weakref(): + o = _class() + oc = _class2() + n = _newclass() + nc = _newclass2() + f = _function + z = _class + x = _newclass -m = weakref.ref(n) -dm = weakref.ref(_newclass()) -t = weakref.proxy(n) -dt = weakref.proxy(_newclass()) -d = weakref.proxy(nc) -dd = weakref.proxy(_newclass2()) + r = weakref.ref(o) + dr = weakref.ref(_class()) + p = weakref.proxy(o) + dp = weakref.proxy(_class()) + c = weakref.proxy(oc) + dc = weakref.proxy(_class2()) -fr = weakref.ref(f) -fp = weakref.proxy(f) -#zr = weakref.ref(z) #XXX: weakrefs not allowed for classobj objects -#zp = weakref.proxy(z) #XXX: weakrefs not allowed for classobj objects -xr = weakref.ref(x) -xp = weakref.proxy(x) + m = weakref.ref(n) + dm = weakref.ref(_newclass()) + t = weakref.proxy(n) + dt = weakref.proxy(_newclass()) + d = weakref.proxy(nc) + dd = weakref.proxy(_newclass2()) -objlist = [r,dr,m,dm,fr,xr, p,dp,t,dt, c,dc,d,dd, fp,xp] + fr = weakref.ref(f) + fp = weakref.proxy(f) + #zr = weakref.ref(z) #XXX: weakrefs not allowed for classobj objects + #zp = weakref.proxy(z) #XXX: weakrefs not allowed for classobj objects + xr = weakref.ref(x) + xp = weakref.proxy(x) -#dill.detect.trace(True) -for obj in objlist: - res = dill.detect.errors(obj) - if res: - print ("%s" % res) - #print ("%s:\n %s" % (obj, res)) -# else: -# print ("PASS: %s" % obj) - assert not res + objlist = [r,dr,m,dm,fr,xr, p,dp,t,dt, c,dc,d,dd, fp,xp] + #dill.detect.trace(True) + + for obj in objlist: + res = dill.detect.errors(obj) + if res: + print ("%s" % res) + #print ("%s:\n %s" % (obj, res)) + # else: + # print ("PASS: %s" % obj) + assert not res + + +if __name__ == '__main__': + test_weakref()