test_nested.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env python
  2. #
  3. # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
  4. # Copyright (c) 2008-2016 California Institute of Technology.
  5. # Copyright (c) 2016-2024 The Uncertainty Quantification Foundation.
  6. # License: 3-clause BSD. The full license text is available at:
  7. # - https://github.com/uqfoundation/dill/blob/master/LICENSE
  8. """
  9. test dill's ability to handle nested functions
  10. """
  11. import os
  12. import math
  13. import dill as pickle
  14. pickle.settings['recurse'] = True
  15. # the nested function: pickle should fail here, but dill is ok.
  16. def adder(augend):
  17. zero = [0]
  18. def inner(addend):
  19. return addend + augend + zero[0]
  20. return inner
  21. # rewrite the nested function using a class: standard pickle should work here.
  22. class cadder(object):
  23. def __init__(self, augend):
  24. self.augend = augend
  25. self.zero = [0]
  26. def __call__(self, addend):
  27. return addend + self.augend + self.zero[0]
  28. # rewrite again, but as an old-style class
  29. class c2adder:
  30. def __init__(self, augend):
  31. self.augend = augend
  32. self.zero = [0]
  33. def __call__(self, addend):
  34. return addend + self.augend + self.zero[0]
  35. # some basic class stuff
  36. class basic(object):
  37. pass
  38. class basic2:
  39. pass
  40. x = 5
  41. y = 1
  42. def test_basic():
  43. a = [0, 1, 2]
  44. pa = pickle.dumps(a)
  45. pmath = pickle.dumps(math) #XXX: FAILS in pickle
  46. pmap = pickle.dumps(map)
  47. # ...
  48. la = pickle.loads(pa)
  49. lmath = pickle.loads(pmath)
  50. lmap = pickle.loads(pmap)
  51. assert list(map(math.sin, a)) == list(lmap(lmath.sin, la))
  52. def test_basic_class():
  53. pbasic2 = pickle.dumps(basic2)
  54. _pbasic2 = pickle.loads(pbasic2)()
  55. pbasic = pickle.dumps(basic)
  56. _pbasic = pickle.loads(pbasic)()
  57. def test_c2adder():
  58. pc2adder = pickle.dumps(c2adder)
  59. pc2add5 = pickle.loads(pc2adder)(x)
  60. assert pc2add5(y) == x+y
  61. def test_pickled_cadder():
  62. pcadder = pickle.dumps(cadder)
  63. pcadd5 = pickle.loads(pcadder)(x)
  64. assert pcadd5(y) == x+y
  65. def test_raw_adder_and_inner():
  66. add5 = adder(x)
  67. assert add5(y) == x+y
  68. def test_pickled_adder():
  69. padder = pickle.dumps(adder)
  70. padd5 = pickle.loads(padder)(x)
  71. assert padd5(y) == x+y
  72. def test_pickled_inner():
  73. add5 = adder(x)
  74. pinner = pickle.dumps(add5) #XXX: FAILS in pickle
  75. p5add = pickle.loads(pinner)
  76. assert p5add(y) == x+y
  77. def test_moduledict_where_not_main():
  78. try:
  79. from . import test_moduledict
  80. except ImportError:
  81. import test_moduledict
  82. name = 'test_moduledict.py'
  83. if os.path.exists(name) and os.path.exists(name+'c'):
  84. os.remove(name+'c')
  85. if os.path.exists(name) and hasattr(test_moduledict, "__cached__") \
  86. and os.path.exists(test_moduledict.__cached__):
  87. os.remove(getattr(test_moduledict, "__cached__"))
  88. if os.path.exists("__pycache__") and not os.listdir("__pycache__"):
  89. os.removedirs("__pycache__")
  90. if __name__ == '__main__':
  91. test_basic()
  92. test_basic_class()
  93. test_c2adder()
  94. test_pickled_cadder()
  95. test_raw_adder_and_inner()
  96. test_pickled_adder()
  97. test_pickled_inner()
  98. test_moduledict_where_not_main()