test_serialization.py 5.8 KB

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