test_serialization.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. from toolz import *
  2. import toolz
  3. import toolz.curried
  4. import pickle
  5. from toolz.utils import raises
  6. def test_compose():
  7. f = compose(str, sum)
  8. g = pickle.loads(pickle.dumps(f))
  9. assert f((1, 2)) == g((1, 2))
  10. def test_curry():
  11. f = curry(map)(str)
  12. g = pickle.loads(pickle.dumps(f))
  13. assert list(f((1, 2, 3))) == list(g((1, 2, 3)))
  14. def test_juxt():
  15. f = juxt(str, int, bool)
  16. g = pickle.loads(pickle.dumps(f))
  17. assert f(1) == g(1)
  18. assert f.funcs == g.funcs
  19. def test_complement():
  20. f = complement(bool)
  21. assert f(True) is False
  22. assert f(False) is True
  23. g = pickle.loads(pickle.dumps(f))
  24. assert f(True) == g(True)
  25. assert f(False) == g(False)
  26. def test_instanceproperty():
  27. p = toolz.functoolz.InstanceProperty(bool)
  28. assert p.__get__(None) is None
  29. assert p.__get__(0) is False
  30. assert p.__get__(1) is True
  31. p2 = pickle.loads(pickle.dumps(p))
  32. assert p2.__get__(None) is None
  33. assert p2.__get__(0) is False
  34. assert p2.__get__(1) is True
  35. def f(x, y):
  36. return x, y
  37. def test_flip():
  38. flip = pickle.loads(pickle.dumps(toolz.functoolz.flip))
  39. assert flip is toolz.functoolz.flip
  40. g1 = flip(f)
  41. g2 = pickle.loads(pickle.dumps(g1))
  42. assert g1(1, 2) == g2(1, 2) == f(2, 1)
  43. g1 = flip(f)(1)
  44. g2 = pickle.loads(pickle.dumps(g1))
  45. assert g1(2) == g2(2) == f(2, 1)
  46. def test_curried_exceptions():
  47. # This tests a global curried object that isn't defined in toolz.functoolz
  48. merge = pickle.loads(pickle.dumps(toolz.curried.merge))
  49. assert merge is toolz.curried.merge
  50. @toolz.curry
  51. class GlobalCurried(object):
  52. def __init__(self, x, y):
  53. self.x = x
  54. self.y = y
  55. @toolz.curry
  56. def f1(self, a, b):
  57. return self.x + self.y + a + b
  58. def g1(self):
  59. pass
  60. def __reduce__(self):
  61. """Allow us to serialize instances of GlobalCurried"""
  62. return GlobalCurried, (self.x, self.y)
  63. @toolz.curry
  64. class NestedCurried(object):
  65. def __init__(self, x, y):
  66. self.x = x
  67. self.y = y
  68. @toolz.curry
  69. def f2(self, a, b):
  70. return self.x + self.y + a + b
  71. def g2(self):
  72. pass
  73. def __reduce__(self):
  74. """Allow us to serialize instances of NestedCurried"""
  75. return GlobalCurried.NestedCurried, (self.x, self.y)
  76. class Nested(object):
  77. def __init__(self, x, y):
  78. self.x = x
  79. self.y = y
  80. @toolz.curry
  81. def f3(self, a, b):
  82. return self.x + self.y + a + b
  83. def g3(self):
  84. pass
  85. def test_curried_qualname():
  86. def preserves_identity(obj):
  87. return pickle.loads(pickle.dumps(obj)) is obj
  88. assert preserves_identity(GlobalCurried)
  89. assert preserves_identity(GlobalCurried.func.f1)
  90. assert preserves_identity(GlobalCurried.func.NestedCurried)
  91. assert preserves_identity(GlobalCurried.func.NestedCurried.func.f2)
  92. assert preserves_identity(GlobalCurried.func.Nested.f3)
  93. global_curried1 = GlobalCurried(1)
  94. global_curried2 = pickle.loads(pickle.dumps(global_curried1))
  95. assert global_curried1 is not global_curried2
  96. assert global_curried1(2).f1(3, 4) == global_curried2(2).f1(3, 4) == 10
  97. global_curried3 = global_curried1(2)
  98. global_curried4 = pickle.loads(pickle.dumps(global_curried3))
  99. assert global_curried3 is not global_curried4
  100. assert global_curried3.f1(3, 4) == global_curried4.f1(3, 4) == 10
  101. func1 = global_curried1(2).f1(3)
  102. func2 = pickle.loads(pickle.dumps(func1))
  103. assert func1 is not func2
  104. assert func1(4) == func2(4) == 10
  105. nested_curried1 = GlobalCurried.func.NestedCurried(1)
  106. nested_curried2 = pickle.loads(pickle.dumps(nested_curried1))
  107. assert nested_curried1 is not nested_curried2
  108. assert nested_curried1(2).f2(3, 4) == nested_curried2(2).f2(3, 4) == 10
  109. # If we add `curry.__getattr__` forwarding, the following tests will pass
  110. # if not PY34:
  111. # assert preserves_identity(GlobalCurried.func.g1)
  112. # assert preserves_identity(GlobalCurried.func.NestedCurried.func.g2)
  113. # assert preserves_identity(GlobalCurried.func.Nested)
  114. # assert preserves_identity(GlobalCurried.func.Nested.g3)
  115. #
  116. # # Rely on curry.__getattr__
  117. # assert preserves_identity(GlobalCurried.f1)
  118. # assert preserves_identity(GlobalCurried.NestedCurried)
  119. # assert preserves_identity(GlobalCurried.NestedCurried.f2)
  120. # assert preserves_identity(GlobalCurried.Nested.f3)
  121. # if not PY34:
  122. # assert preserves_identity(GlobalCurried.g1)
  123. # assert preserves_identity(GlobalCurried.NestedCurried.g2)
  124. # assert preserves_identity(GlobalCurried.Nested)
  125. # assert preserves_identity(GlobalCurried.Nested.g3)
  126. #
  127. # nested_curried3 = nested_curried1(2)
  128. # nested_curried4 = pickle.loads(pickle.dumps(nested_curried3))
  129. # assert nested_curried3 is not nested_curried4
  130. # assert nested_curried3.f2(3, 4) == nested_curried4.f2(3, 4) == 10
  131. #
  132. # func1 = nested_curried1(2).f2(3)
  133. # func2 = pickle.loads(pickle.dumps(func1))
  134. # assert func1 is not func2
  135. # assert func1(4) == func2(4) == 10
  136. #
  137. # if not PY34:
  138. # nested3 = GlobalCurried.func.Nested(1, 2)
  139. # nested4 = pickle.loads(pickle.dumps(nested3))
  140. # assert nested3 is not nested4
  141. # assert nested3.f3(3, 4) == nested4.f3(3, 4) == 10
  142. #
  143. # func1 = nested3.f3(3)
  144. # func2 = pickle.loads(pickle.dumps(func1))
  145. # assert func1 is not func2
  146. # assert func1(4) == func2(4) == 10
  147. def test_curried_bad_qualname():
  148. @toolz.curry
  149. class Bad(object):
  150. __qualname__ = 'toolz.functoolz.not.a.valid.path'
  151. assert raises(pickle.PicklingError, lambda: pickle.dumps(Bad))