Author: Greg Price <[email protected]>
Branch: signatures
Changeset: r59317:69dc4f2048ca
Date: 2012-12-02 17:59 -0800
http://bitbucket.org/pypy/pypy/changeset/69dc4f2048ca/
Log: Move signature to its own module
diff --git a/pypy/rlib/objectmodel.py b/pypy/rlib/objectmodel.py
--- a/pypy/rlib/objectmodel.py
+++ b/pypy/rlib/objectmodel.py
@@ -193,25 +193,6 @@
return result
return decorator
-def signature(*paramtypes, **kwargs):
- """Decorate a function to specify its type signature.
-
- Usage:
- @signature(param1type, param2type, ..., returns=returntype)
- def foo(...)
-
- The arguments paramNtype and returntype should be instances
- of the classes in pypy.annotation.types.
- """
- returntype = kwargs.pop('returns', None)
- if returntype is None:
- raise TypeError, "signature: parameter 'returns' required"
-
- def decorator(f):
- f._signature_ = (paramtypes, returntype)
- return f
- return decorator
-
# ____________________________________________________________
diff --git a/pypy/rlib/signature.py b/pypy/rlib/signature.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/signature.py
@@ -0,0 +1,19 @@
+
+def signature(*paramtypes, **kwargs):
+ """Decorate a function to specify its type signature.
+
+ Usage:
+ @signature(param1type, param2type, ..., returns=returntype)
+ def foo(...)
+
+ The arguments paramNtype and returntype should be instances
+ of the classes in pypy.annotation.types.
+ """
+ returntype = kwargs.pop('returns', None)
+ if returntype is None:
+ raise TypeError, "signature: parameter 'returns' required"
+
+ def decorator(f):
+ f._signature_ = (paramtypes, returntype)
+ return f
+ return decorator
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
@@ -488,129 +488,6 @@
assert TYPES == [lltype.Signed, lltype.Float]
-def test_signature_bookkeeping():
- @signature('x', 'y', returns='z')
- def f(a, b):
- return a + len(b)
- f.foo = 'foo'
- assert f._signature_ == (('x', 'y'), 'z')
- assert f.func_name == 'f'
- assert f.foo == 'foo'
- assert f(1, 'hello') == 6
-
-def annotate_at(f):
- t = TranslationContext()
- a = t.buildannotator()
- a.annotate_helper(f, [model.s_ImpossibleValue]*f.func_code.co_argcount)
- return a
-
-def sigof(a, f):
- # returns [param1, param2, ..., ret]
- g = graphof(a.translator, f)
- return [a.bindings[v] for v in g.startblock.inputargs] +
[a.bindings[g.getreturnvar()]]
-
-def getsig(f):
- a = annotate_at(f)
- return sigof(a, f)
-
-def check_annotator_fails(caller):
- exc = py.test.raises(Exception, annotate_at, caller).value
- assert caller.func_name in repr(exc.args)
-
-def test_signature_basic():
- @signature(types.int(), types.str(), returns=types.char())
- def f(a, b):
- return b[a]
- assert getsig(f) == [model.SomeInteger(), model.SomeString(),
model.SomeChar()]
-
-def test_signature_arg_errors():
- @signature(types.int(), types.str(), returns=types.int())
- def f(a, b):
- return a + len(b)
- @check_annotator_fails
- def ok_for_body(): # would give no error without signature
- f(2.0, 'b')
- @check_annotator_fails
- def bad_for_body(): # would give error inside 'f' body, instead errors at
call
- f('a', 'b')
-
-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')
- a = annotate_at(g)
- assert sigof(a, f) == [model.SomeString(), model.SomeString()]
-
-def test_signature_return_errors():
- @check_annotator_fails
- @signature(returns=types.int())
- def int_not_char():
- return 'a'
- @check_annotator_fails
- @signature(types.str(), returns=types.int())
- def str_to_int(s):
- return s
-
-def test_signature_list():
- @signature(types.list(types.int()), returns=types.int())
- def f(a):
- return len(a)
- argtype = getsig(f)[0]
- assert isinstance(argtype, model.SomeList)
- item = argtype.listdef.listitem
- assert item.s_value == model.SomeInteger()
- assert item.resized == True
-
- @check_annotator_fails
- def ok_for_body():
- f(['a'])
- @check_annotator_fails
- def bad_for_body():
- f('a')
-
- @signature(returns=types.list(types.char()))
- def ff():
- return ['a']
- @check_annotator_fails
- def mutate_broader():
- ff()[0] = 'abc'
- @check_annotator_fails
- def mutate_unrelated():
- ff()[0] = 1
- @check_annotator_fails
- @signature(types.list(types.char()), returns=types.int())
- def mutate_in_body(l):
- l[0] = 'abc'
- return len(l)
-
- def can_append():
- l = ff()
- l.append('b')
- getsig(can_append)
-
-def test_signature_array():
- @signature(returns=types.array(types.int()))
- def f():
- return [1]
- rettype = getsig(f)[0]
- assert isinstance(rettype, model.SomeList)
- item = rettype.listdef.listitem
- assert item.s_value == model.SomeInteger()
- assert item.resized == False
-
- def try_append():
- l = f()
- l.append(2)
- check_annotator_fails(try_append)
-
-
def getgraph(f, argtypes):
from pypy.translator.translator import TranslationContext, graphof
from pypy.translator.backendopt.all import backend_optimizations
diff --git a/pypy/rlib/test/test_signature.py b/pypy/rlib/test/test_signature.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/test/test_signature.py
@@ -0,0 +1,127 @@
+import py
+from pypy.rlib.signature import signature
+from pypy.annotation import types, model
+from pypy.translator.translator import TranslationContext, graphof
+
+
+def test_signature_bookkeeping():
+ @signature('x', 'y', returns='z')
+ def f(a, b):
+ return a + len(b)
+ f.foo = 'foo'
+ assert f._signature_ == (('x', 'y'), 'z')
+ assert f.func_name == 'f'
+ assert f.foo == 'foo'
+ assert f(1, 'hello') == 6
+
+def annotate_at(f):
+ t = TranslationContext()
+ a = t.buildannotator()
+ a.annotate_helper(f, [model.s_ImpossibleValue]*f.func_code.co_argcount)
+ return a
+
+def sigof(a, f):
+ # returns [param1, param2, ..., ret]
+ g = graphof(a.translator, f)
+ return [a.bindings[v] for v in g.startblock.inputargs] +
[a.bindings[g.getreturnvar()]]
+
+def getsig(f):
+ a = annotate_at(f)
+ return sigof(a, f)
+
+def check_annotator_fails(caller):
+ exc = py.test.raises(Exception, annotate_at, caller).value
+ assert caller.func_name in repr(exc.args)
+
+def test_signature_basic():
+ @signature(types.int(), types.str(), returns=types.char())
+ def f(a, b):
+ return b[a]
+ assert getsig(f) == [model.SomeInteger(), model.SomeString(),
model.SomeChar()]
+
+def test_signature_arg_errors():
+ @signature(types.int(), types.str(), returns=types.int())
+ def f(a, b):
+ return a + len(b)
+ @check_annotator_fails
+ def ok_for_body(): # would give no error without signature
+ f(2.0, 'b')
+ @check_annotator_fails
+ def bad_for_body(): # would give error inside 'f' body, instead errors at
call
+ f('a', 'b')
+
+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')
+ a = annotate_at(g)
+ assert sigof(a, f) == [model.SomeString(), model.SomeString()]
+
+def test_signature_return_errors():
+ @check_annotator_fails
+ @signature(returns=types.int())
+ def int_not_char():
+ return 'a'
+ @check_annotator_fails
+ @signature(types.str(), returns=types.int())
+ def str_to_int(s):
+ return s
+
+def test_signature_list():
+ @signature(types.list(types.int()), returns=types.int())
+ def f(a):
+ return len(a)
+ argtype = getsig(f)[0]
+ assert isinstance(argtype, model.SomeList)
+ item = argtype.listdef.listitem
+ assert item.s_value == model.SomeInteger()
+ assert item.resized == True
+
+ @check_annotator_fails
+ def ok_for_body():
+ f(['a'])
+ @check_annotator_fails
+ def bad_for_body():
+ f('a')
+
+ @signature(returns=types.list(types.char()))
+ def ff():
+ return ['a']
+ @check_annotator_fails
+ def mutate_broader():
+ ff()[0] = 'abc'
+ @check_annotator_fails
+ def mutate_unrelated():
+ ff()[0] = 1
+ @check_annotator_fails
+ @signature(types.list(types.char()), returns=types.int())
+ def mutate_in_body(l):
+ l[0] = 'abc'
+ return len(l)
+
+ def can_append():
+ l = ff()
+ l.append('b')
+ getsig(can_append)
+
+def test_signature_array():
+ @signature(returns=types.array(types.int()))
+ def f():
+ return [1]
+ rettype = getsig(f)[0]
+ assert isinstance(rettype, model.SomeList)
+ item = rettype.listdef.listitem
+ assert item.s_value == model.SomeInteger()
+ assert item.resized == False
+
+ def try_append():
+ l = f()
+ l.append(2)
+ check_annotator_fails(try_append)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit