Author: Carl Friedrich Bolz <[email protected]>
Branch:
Changeset: r62395:3d242f84ac48
Date: 2013-03-17 22:00 +0100
http://bitbucket.org/pypy/pypy/changeset/3d242f84ac48/
Log: add an "any" type to rlib.types. It's kind of necessary for a lot of
practical uses, e.g. when a PBC (like the object space) is involved.
diff --git a/rpython/annotator/description.py b/rpython/annotator/description.py
--- a/rpython/annotator/description.py
+++ b/rpython/annotator/description.py
@@ -306,8 +306,10 @@
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])
+ sigresult = enforce_signature_return(self, signature[1],
result)
+ if sigresult is not None:
+ self.bookkeeper.annotator.addpendingblock(graph,
graph.returnblock, [sigresult])
+ result = sigresult
# 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/rpython/annotator/signature.py b/rpython/annotator/signature.py
--- a/rpython/annotator/signature.py
+++ b/rpython/annotator/signature.py
@@ -132,11 +132,13 @@
inputcells[:] = args_s
def finish_type(paramtype, bookkeeper, func):
- from rpython.rlib.types import SelfTypeMarker
+ from rpython.rlib.types import SelfTypeMarker, AnyTypeMarker
if isinstance(paramtype, SomeObject):
return paramtype
elif isinstance(paramtype, SelfTypeMarker):
raise Exception("%r argument declared as annotation.types.self();
class needs decorator rlib.signature.finishsigs()" % (func,))
+ elif isinstance(paramtype, AnyTypeMarker):
+ return None
else:
return paramtype(bookkeeper)
@@ -144,15 +146,20 @@
assert len(paramtypes) == len(actualtypes)
params_s = [finish_type(paramtype, funcdesc.bookkeeper, funcdesc.pyobj)
for paramtype in paramtypes]
for i, (s_param, s_actual) in enumerate(zip(params_s, actualtypes)):
+ if s_param is None: # can be anything
+ continue
if not s_param.contains(s_actual):
raise Exception("%r argument %d:\n"
"expected %s,\n"
" got %s" % (funcdesc, i+1, s_param, s_actual))
- actualtypes[:] = params_s
+ for i, s_param in enumerate(params_s):
+ if s_param is None:
+ continue
+ actualtypes[i] = s_param
def enforce_signature_return(funcdesc, sigtype, inferredtype):
s_sigret = finish_type(sigtype, funcdesc.bookkeeper, funcdesc.pyobj)
- if not s_sigret.contains(inferredtype):
+ if s_sigret is not None and not s_sigret.contains(inferredtype):
raise Exception("%r return value:\n"
"expected %s,\n"
" got %s" % (funcdesc, s_sigret, inferredtype))
diff --git a/rpython/rlib/test/test_signature.py
b/rpython/rlib/test/test_signature.py
--- a/rpython/rlib/test/test_signature.py
+++ b/rpython/rlib/test/test_signature.py
@@ -248,3 +248,39 @@
exc = py.test.raises(Exception, annotate_at, C.incomplete_sig_meth).value
assert 'incomplete_sig_meth' in repr(exc.args)
assert 'finishsigs' in repr(exc.args)
+
+def test_any_as_argument():
+ @signature(types.any(), types.int(), returns=types.float())
+ def f(x, y):
+ return x + y
+ @signature(types.int(), returns=types.float())
+ def g(x):
+ return f(x, x)
+ sig = getsig(g)
+ assert sig == [model.SomeInteger(), model.SomeFloat()]
+
+ @signature(types.float(), returns=types.float())
+ def g(x):
+ return f(x, 4)
+ sig = getsig(g)
+ assert sig == [model.SomeFloat(), model.SomeFloat()]
+
+ @signature(types.str(), returns=types.int())
+ def cannot_add_string(x):
+ return f(x, 2)
+ exc = py.test.raises(Exception, annotate_at, cannot_add_string).value
+ assert 'Blocked block' in repr(exc.args)
+
+def test_return_any():
+ @signature(types.int(), returns=types.any())
+ def f(x):
+ return x
+ sig = getsig(f)
+ assert sig == [model.SomeInteger(), model.SomeInteger()]
+
+ @signature(types.str(), returns=types.any())
+ def cannot_add_string(x):
+ return f(3) + x
+ exc = py.test.raises(Exception, annotate_at, cannot_add_string).value
+ assert 'Blocked block' in repr(exc.args)
+ assert 'cannot_add_string' in repr(exc.args)
diff --git a/rpython/rlib/types.py b/rpython/rlib/types.py
--- a/rpython/rlib/types.py
+++ b/rpython/rlib/types.py
@@ -63,3 +63,10 @@
def self():
return SelfTypeMarker()
+
+
+class AnyTypeMarker(object):
+ pass
+
+def any():
+ return AnyTypeMarker()
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit