1+ import inspect
12import platform
23
34from toolz .functoolz import (thread_first , thread_last , memoize , curry ,
45 compose , compose_left , pipe , complement , do , juxt ,
56 flip , excepts , apply )
7+ from toolz .compatibility import PY3
68from operator import add , mul , itemgetter
79from toolz .utils import raises
810from functools import partial
@@ -24,6 +26,26 @@ def double(x):
2426 return 2 * x
2527
2628
29+ class AlwaysEquals (object ):
30+ """useful to test correct __eq__ implementation of other objects"""
31+
32+ def __eq__ (self , other ):
33+ return True
34+
35+ def __ne__ (self , other ):
36+ return False
37+
38+
39+ class NeverEquals (object ):
40+ """useful to test correct __eq__ implementation of other objects"""
41+
42+ def __eq__ (self , other ):
43+ return False
44+
45+ def __ne__ (self , other ):
46+ return True
47+
48+
2749def test_apply ():
2850 assert apply (double , 5 ) == 10
2951 assert tuple (map (apply , [double , inc , double ], [10 , 500 , 8000 ])) == (20 , 501 , 16000 )
@@ -573,6 +595,74 @@ def g(a):
573595 assert composed .__name__ == 'Compose'
574596 assert composed .__doc__ == 'A composition of functions'
575597
598+ assert repr (composed ) == 'Compose({!r}, {!r})' .format (f , h )
599+
600+ assert composed == compose (f , h )
601+ assert composed == AlwaysEquals ()
602+ assert not composed == compose (h , f )
603+ assert not composed == object ()
604+ assert not composed == NeverEquals ()
605+
606+ assert composed != compose (h , f )
607+ assert composed != NeverEquals ()
608+ assert composed != object ()
609+ assert not composed != compose (f , h )
610+ assert not composed != AlwaysEquals ()
611+
612+ assert hash (composed ) == hash (compose (f , h ))
613+ assert hash (composed ) != hash (compose (h , f ))
614+
615+ bindable = compose (str , lambda x : x * 2 , lambda x , y = 0 : int (x ) + y )
616+
617+ class MyClass :
618+
619+ def __int__ (self ):
620+ return 8
621+
622+ my_method = bindable
623+ my_static_method = staticmethod (bindable )
624+
625+ assert MyClass .my_method (3 ) == '6'
626+ assert MyClass .my_method (3 , y = 2 ) == '10'
627+ assert MyClass .my_static_method (2 ) == '4'
628+ assert MyClass ().my_method () == '16'
629+ assert MyClass ().my_method (y = 3 ) == '22'
630+ assert MyClass ().my_static_method (0 ) == '0'
631+ assert MyClass ().my_static_method (0 , 1 ) == '2'
632+
633+ assert compose (f , h ).__wrapped__ is h
634+ assert compose (f , h ).__class__ .__wrapped__ is None
635+
636+ # __signature__ is python3 only
637+ if PY3 :
638+
639+ def myfunc (a , b , c , * d , ** e ):
640+ return 4
641+
642+ def otherfunc (f ):
643+ return 'result: {}' .format (f )
644+
645+ # set annotations compatibly with python2 syntax
646+ myfunc .__annotations__ = {
647+ 'a' : int ,
648+ 'b' : str ,
649+ 'c' : float ,
650+ 'd' : int ,
651+ 'e' : bool ,
652+ 'return' : int ,
653+ }
654+ otherfunc .__annotations__ = {'f' : int , 'return' : str }
655+
656+ composed = compose (otherfunc , myfunc )
657+ sig = inspect .signature (composed )
658+ assert sig .parameters == inspect .signature (myfunc ).parameters
659+ assert sig .return_annotation == str
660+
661+ class MyClass :
662+ method = composed
663+
664+ assert len (inspect .signature (MyClass ().method ).parameters ) == 4
665+
576666
577667def generate_compose_left_test_cases ():
578668 """
@@ -708,4 +798,3 @@ def raise_(a):
708798 excepting = excepts (object (), object (), object ())
709799 assert excepting .__name__ == 'excepting'
710800 assert excepting .__doc__ == excepts .__doc__
711-
0 commit comments