1import unittest 2 3from Cython.Compiler import PyrexTypes as pt 4from Cython.Compiler.ExprNodes import NameNode 5from Cython.Compiler.PyrexTypes import CFuncTypeArg 6 7def cfunctype(*arg_types): 8 return pt.CFuncType(pt.c_int_type, 9 [ CFuncTypeArg("name", arg_type, None) for arg_type in arg_types ]) 10 11def cppclasstype(name, base_classes): 12 return pt.CppClassType(name, None, 'CPP_'+name, base_classes) 13 14class SignatureMatcherTest(unittest.TestCase): 15 """ 16 Test the signature matching algorithm for overloaded signatures. 17 """ 18 def assertMatches(self, expected_type, arg_types, functions): 19 args = [ NameNode(None, type=arg_type) for arg_type in arg_types ] 20 match = pt.best_match(args, functions) 21 if expected_type is not None: 22 self.assertNotEqual(None, match) 23 self.assertEqual(expected_type, match.type) 24 25 def test_cpp_reference_single_arg(self): 26 function_types = [ 27 cfunctype(pt.CReferenceType(pt.c_int_type)), 28 cfunctype(pt.CReferenceType(pt.c_long_type)), 29 cfunctype(pt.CReferenceType(pt.c_double_type)), 30 ] 31 32 functions = [ NameNode(None, type=t) for t in function_types ] 33 self.assertMatches(function_types[0], [pt.c_int_type], functions) 34 self.assertMatches(function_types[1], [pt.c_long_type], functions) 35 self.assertMatches(function_types[2], [pt.c_double_type], functions) 36 37 def test_cpp_reference_two_args(self): 38 function_types = [ 39 cfunctype( 40 pt.CReferenceType(pt.c_int_type), pt.CReferenceType(pt.c_long_type)), 41 cfunctype( 42 pt.CReferenceType(pt.c_long_type), pt.CReferenceType(pt.c_long_type)), 43 ] 44 45 functions = [ NameNode(None, type=t) for t in function_types ] 46 self.assertMatches(function_types[0], [pt.c_int_type, pt.c_long_type], functions) 47 self.assertMatches(function_types[1], [pt.c_long_type, pt.c_long_type], functions) 48 self.assertMatches(function_types[1], [pt.c_long_type, pt.c_int_type], functions) 49 50 def test_cpp_reference_cpp_class(self): 51 classes = [ cppclasstype("Test%d"%i, []) for i in range(2) ] 52 function_types = [ 53 cfunctype(pt.CReferenceType(classes[0])), 54 cfunctype(pt.CReferenceType(classes[1])), 55 ] 56 57 functions = [ NameNode(None, type=t) for t in function_types ] 58 self.assertMatches(function_types[0], [classes[0]], functions) 59 self.assertMatches(function_types[1], [classes[1]], functions) 60 61 def test_cpp_reference_cpp_class_and_int(self): 62 classes = [ cppclasstype("Test%d"%i, []) for i in range(2) ] 63 function_types = [ 64 cfunctype(pt.CReferenceType(classes[0]), pt.c_int_type), 65 cfunctype(pt.CReferenceType(classes[0]), pt.c_long_type), 66 cfunctype(pt.CReferenceType(classes[1]), pt.c_int_type), 67 cfunctype(pt.CReferenceType(classes[1]), pt.c_long_type), 68 ] 69 70 functions = [ NameNode(None, type=t) for t in function_types ] 71 self.assertMatches(function_types[0], [classes[0], pt.c_int_type], functions) 72 self.assertMatches(function_types[1], [classes[0], pt.c_long_type], functions) 73 self.assertMatches(function_types[2], [classes[1], pt.c_int_type], functions) 74 self.assertMatches(function_types[3], [classes[1], pt.c_long_type], functions) 75