[pypy-commit] pypy signatures: Check actual arguments against signature

Greg Price noreply at buildbot.pypy.org
Tue Dec 4 01:21:00 CET 2012


Author: Greg Price <price at mit.edu>
Branch: signatures
Changeset: r59308:7ad4dbce9497
Date: 2012-12-02 15:20 -0800
http://bitbucket.org/pypy/pypy/changeset/7ad4dbce9497/

Log:	Check actual arguments against signature

diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py
--- a/pypy/annotation/signature.py
+++ b/pypy/annotation/signature.py
@@ -133,7 +133,15 @@
 
 
 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
diff --git a/pypy/rlib/test/test_objectmodel.py b/pypy/rlib/test/test_objectmodel.py
--- a/pypy/rlib/test/test_objectmodel.py
+++ b/pypy/rlib/test/test_objectmodel.py
@@ -511,6 +511,24 @@
         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


More information about the pypy-commit mailing list