Commits

Anonymous committed 7ad4dbc Draft

Check actual arguments against signature

Comments (0)

Files changed (2)

pypy/annotation/signature.py

 
 
 def enforce_signature_args(funcdesc, argtypes, inputcells):
+    assert len(argtypes) == len(inputcells)
     args_s = []
     for i, argtype in enumerate(argtypes):
         args_s.append(annotation(argtype, bookkeeper=funcdesc.bookkeeper))
+    for i, (s_arg, s_input) in enumerate(zip(args_s, inputcells)):
+        if not s_arg.contains(s_input):
+            raise Exception("%r argument %d:\n"
+                            "expected %s,\n"
+                            "     got %s" % (funcdesc, i+1,
+                                         s_arg,
+                                         s_input))
     inputcells[:] = args_s

pypy/rlib/test/test_objectmodel.py

         return a + len(b)
     assert getsig(f) == [model.SomeInteger(), model.SomeString(), model.SomeInteger()]
 
+def test_signature_errors():
+    @signature(types.int(), types.str(), returns=types.int())
+    def f(a, b):
+        return a + len(b)
+    def ok_for_body(): # would give no error without signature
+        f(2.0, 'b')
+    def bad_for_body(): # would give error inside 'f' body, instead errors at call
+        f('a', 'b')
+
+    def check_fails(caller):
+        t = TranslationContext()
+        a = t.buildannotator()
+        exc = py.test.raises(Exception, a.annotate_helper, caller, []).value
+        assert caller.func_name in repr(exc.args)
+
+    check_fails(ok_for_body)
+    check_fails(bad_for_body)
+
 
 def getgraph(f, argtypes):
     from pypy.translator.translator import TranslationContext, graphof