Author: Greg Price <[email protected]>
Branch: signatures
Changeset: r59309:71849b77d899
Date: 2012-12-02 16:10 -0800
http://bitbucket.org/pypy/pypy/changeset/71849b77d899/
Log: (price, arigato) Apply signature to return type
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -1,6 +1,6 @@
from __future__ import absolute_import
import types, py
-from pypy.annotation.signature import enforce_signature_args
+from pypy.annotation.signature import enforce_signature_args,
enforce_signature_return
from pypy.objspace.flow.model import Constant, FunctionGraph
from pypy.objspace.flow.bytecode import cpython_code_signature
from pypy.objspace.flow.argument import rawshape, ArgErr
@@ -304,6 +304,10 @@
new_args = args.unmatch_signature(self.signature, inputcells)
inputcells = self.parse_arguments(new_args, graph)
result = schedule(graph, inputcells)
+ signature = getattr(self.pyobj, '_signature_', None)
+ if signature:
+ result = enforce_signature_return(self, signature[1], result)
+ self.bookkeeper.annotator.addpendingblock(graph,
graph.returnblock, [result])
# Some specializations may break the invariant of returning
# annotations that are always more general than the previous time.
# We restore it here:
diff --git a/pypy/annotation/signature.py b/pypy/annotation/signature.py
--- a/pypy/annotation/signature.py
+++ b/pypy/annotation/signature.py
@@ -132,16 +132,19 @@
inputcells[:] = args_s
-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):
+def enforce_signature_args(funcdesc, paramtypes, actualtypes):
+ assert len(paramtypes) == len(actualtypes)
+ params_s = []
+ for i, paramtype in enumerate(paramtypes):
+ params_s.append(annotation(paramtype, bookkeeper=funcdesc.bookkeeper))
+ for i, (s_param, s_actual) in enumerate(zip(params_s, actualtypes)):
+ if not s_param.contains(s_actual):
raise Exception("%r argument %d:\n"
"expected %s,\n"
- " got %s" % (funcdesc, i+1,
- s_arg,
- s_input))
- inputcells[:] = args_s
+ " got %s" % (funcdesc, i+1, s_param, s_actual))
+ actualtypes[:] = params_s
+
+
+def enforce_signature_return(funcdesc, sigtype, inferredtype):
+ annsigtype = annotation(sigtype, bookkeeper=funcdesc.bookkeeper)
+ return annsigtype
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_return():
+ @signature(returns=types.str())
+ def f():
+ return 'a'
+ assert getsig(f) == [model.SomeString()]
+
+ @signature(types.str(), returns=types.str())
+ def f(x):
+ return x
+ def g():
+ return f('a')
+ t = TranslationContext()
+ a = t.buildannotator()
+ a.annotate_helper(g, [])
+ assert a.bindings[graphof(t, f).startblock.inputargs[0]] ==
model.SomeString()
+ assert a.bindings[graphof(t, f).getreturnvar()] == model.SomeString()
+
+
def test_signature_errors():
@signature(types.int(), types.str(), returns=types.int())
def f(a, b):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit