Author: Greg Price <pr...@mit.edu> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit