[pypy-svn] r31945 - in pypy/dist/pypy/annotation: . test

arigo at codespeak.net arigo at codespeak.net
Sat Sep 2 15:24:48 CEST 2006


Author: arigo
Date: Sat Sep  2 15:24:46 2006
New Revision: 31945

Modified:
   pypy/dist/pypy/annotation/description.py
   pypy/dist/pypy/annotation/policy.py
   pypy/dist/pypy/annotation/test/test_annrpython.py
Log:
(arigo, pedronis) - coding
(pedronis, arigo) - test

A way to enforce general enough signatures during the annotation of
functions.  To be used mostly for low-level helpers, to get rid of
problems mostly caused by non-neg integers that become possibly-negative
later.



Modified: pypy/dist/pypy/annotation/description.py
==============================================================================
--- pypy/dist/pypy/annotation/description.py	(original)
+++ pypy/dist/pypy/annotation/description.py	Sat Sep  2 15:24:46 2006
@@ -250,6 +250,9 @@
             tag = getattr(self.pyobj, '_annspecialcase_', None)
             policy = self.bookkeeper.annotator.policy
             self.specializer = policy.get_specializer(tag)
+        enforceargs = getattr(self.pyobj, '_annenforceargs_', None)
+        if enforceargs:
+            enforceargs(self, inputcells) # can modify inputcells in-place
         return self.specializer(self, inputcells)
 
     def pycall(self, schedule, args, s_previous_result):

Modified: pypy/dist/pypy/annotation/policy.py
==============================================================================
--- pypy/dist/pypy/annotation/policy.py	(original)
+++ pypy/dist/pypy/annotation/policy.py	Sat Sep  2 15:24:46 2006
@@ -90,3 +90,30 @@
     def override__ignore(pol, *args):
         bk = getbookkeeper()
         return bk.immutablevalue(None)
+
+# ____________________________________________________________
+
+class Sig(object):
+
+    def __init__(self, *argtypes):
+        self.argtypes = argtypes
+        
+    def __call__(self, funcdesc, inputcells):
+        args_s = []
+        for argtype in self.argtypes:
+            if isinstance(argtype, annmodel.SomeObject):
+                args_s.append(argtype)
+            else:
+                args_s.append(funcdesc.bookkeeper.valueoftype(argtype))
+        if len(inputcells) != len(args_s):
+            raise Exception("%r: expected %d args, got %d" % (funcdesc,
+                                                              len(args_s),
+                                                              len(inputcells)))
+        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

Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py	(original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py	Sat Sep  2 15:24:46 2006
@@ -2308,6 +2308,18 @@
         assert isinstance(s, annmodel.SomeInteger)
         assert s.nonneg
 
+    def test_sig(self):
+        def fun(x, y):
+            return x+y
+        s_nonneg = annmodel.SomeInteger(nonneg=True)
+        fun._annenforceargs_ = policy.Sig(int, s_nonneg)
+
+        a = self.RPythonAnnotator()
+        s = a.build_types(fun, [s_nonneg, s_nonneg])
+        assert isinstance(s, annmodel.SomeInteger)
+        assert not s.nonneg
+        py.test.raises(Exception, a.build_types, fun, [int, int])
+
 def g(n):
     return [0,1,2,n]
 



More information about the Pypy-commit mailing list