1. Pypy
  2. Untitled project
  3. pypy

Commits

Carl Friedrich Bolz  committed 3d242f8

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.

  • Participants
  • Parent commits def044a
  • Branches default

Comments (0)

Files changed (4)

File rpython/annotator/description.py

View file
  • Ignore whitespace
             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:

File rpython/annotator/signature.py

View file
  • Ignore whitespace
         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)
 
     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))

File rpython/rlib/test/test_signature.py

View file
  • Ignore whitespace
     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)

File rpython/rlib/types.py

View file
  • Ignore whitespace
 
 def self():
     return SelfTypeMarker()
+
+
+class AnyTypeMarker(object):
+    pass
+
+def any():
+    return AnyTypeMarker()