Commits

Greg Price  committed 2fcd49f Draft

Basic support for instance types in signatures

  • Participants
  • Parent commits dd3c75d
  • Branches signatures

Comments (0)

Files changed (3)

File pypy/annotation/signature.py

                                              s_input))
         inputcells[:] = args_s
 
+def apply_bookkeeper(paramtype, bookkeeper):
+    if isinstance(paramtype, SomeObject):
+        return paramtype
+    else:
+        return paramtype(bookkeeper)
 
 def enforce_signature_args(funcdesc, paramtypes, actualtypes):
     assert len(paramtypes) == len(actualtypes)
-    params_s = paramtypes
+    params_s = [apply_bookkeeper(paramtype, funcdesc.bookkeeper) for paramtype in paramtypes]
     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"
                             "     got %s" % (funcdesc, i+1, s_param, s_actual))
     actualtypes[:] = params_s
 
-
 def enforce_signature_return(funcdesc, sigtype, inferredtype):
-    return sigtype
+    return apply_bookkeeper(sigtype, funcdesc.bookkeeper)

File pypy/annotation/types.py

 def array(element):
     listdef = ListDef(None, element, mutated=True, resized=False)
     return model.SomeList(listdef)
+
+def instance(class_):
+    return lambda bookkeeper: model.SomeInstance(bookkeeper.getuniqueclassdef(class_))

File pypy/rlib/test/test_signature.py

         l = f()
         l.append(2)
     check_annotator_fails(try_append)
+
+def test_signature_instance():
+    class C1(object):
+        pass
+    class C2(C1):
+        pass
+    class C3(C2):
+        pass
+    @signature(types.instance(C3), returns=types.instance(C2))
+    def f(x):
+        assert isinstance(x, C2)
+        return x
+    argtype, rettype = getsig(f)
+    assert isinstance(argtype, model.SomeInstance)
+    assert argtype.classdef.classdesc.pyobj == C3
+    assert isinstance(rettype, model.SomeInstance)
+    assert rettype.classdef.classdesc.pyobj == C2
+
+    @check_annotator_fails
+    def ok_for_body():
+        f(C2())
+    @check_annotator_fails
+    def bad_for_body():
+        f(C1())