import pickle from ipykernel.pickleutil import can, uncan, codeutil def interactive(f): f.__module__ = '__main__' return f def dumps(obj): return pickle.dumps(can(obj)) def loads(obj): return uncan(pickle.loads(obj)) def test_no_closure(): @interactive def foo(): a = 5 return a pfoo = dumps(foo) bar = loads(pfoo) assert foo() == bar() def test_generator_closure(): # this only creates a closure on Python 3 @interactive def foo(): i = 'i' r = [ i for j in (1,2) ] return r pfoo = dumps(foo) bar = loads(pfoo) assert foo() == bar() def test_nested_closure(): @interactive def foo(): i = 'i' def g(): return i return g() pfoo = dumps(foo) bar = loads(pfoo) assert foo() == bar() def test_closure(): i = 'i' @interactive def foo(): return i pfoo = dumps(foo) bar = loads(pfoo) assert foo() == bar() def test_uncan_bytes_buffer(): data = b'data' canned = can(data) canned.buffers = [memoryview(buf) for buf in canned.buffers] out = uncan(canned) assert out == data