1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
import py
from rpython.rtyper.extfunc import ExtFuncEntry, register_external,\
is_external, lazy_register
from rpython.annotator import model as annmodel
from rpython.annotator.annrpython import RPythonAnnotator
from rpython.annotator.policy import AnnotatorPolicy
from rpython.rtyper.test.test_llinterp import interpret
class TestExtFuncEntry:
def test_basic(self):
"""
A ExtFuncEntry provides an annotation for a function, no need to flow
its graph.
"""
def b(x):
"NOT_RPYTHON"
return eval("x+40")
class BTestFuncEntry(ExtFuncEntry):
_about_ = b
name = 'b'
signature_args = [annmodel.SomeInteger()]
signature_result = annmodel.SomeInteger()
def f():
return b(2)
policy = AnnotatorPolicy()
a = RPythonAnnotator(policy=policy)
s = a.build_types(f, [])
assert isinstance(s, annmodel.SomeInteger)
res = interpret(f, [])
assert res == 42
def test_lltypeimpl(self):
"""
interpret() calls lltypeimpl instead of of the function/
"""
def c(y, x):
yyy
class CTestFuncEntry(ExtFuncEntry):
_about_ = c
name = 'ccc'
signature_args = [annmodel.SomeInteger()] * 2
signature_result = annmodel.SomeInteger()
def lltypeimpl(y, x):
return y + x
lltypeimpl = staticmethod(lltypeimpl)
def f():
return c(3, 4)
res = interpret(f, [])
assert res == 7
def test_register_external_signature(self):
"""
Test the standard interface for external functions.
"""
def dd():
pass
register_external(dd, [int], int)
def f():
return dd(3)
policy = AnnotatorPolicy()
a = RPythonAnnotator(policy=policy)
s = a.build_types(f, [])
assert isinstance(s, annmodel.SomeInteger)
def test_register_external_tuple_args(self):
"""
Verify the annotation of a registered external function which takes a
tuple argument.
"""
def function_with_tuple_arg():
"""
Dummy function which is declared via register_external to take a
tuple as an argument so that register_external's behavior for
tuple-taking functions can be verified.
"""
register_external(function_with_tuple_arg, [(int,)], int)
def f():
return function_with_tuple_arg((1,))
policy = AnnotatorPolicy()
a = RPythonAnnotator(policy=policy)
s = a.build_types(f, [])
# Not a very good assertion, but at least it means _something_ happened.
assert isinstance(s, annmodel.SomeInteger)
def test_register_external_return_goes_back(self):
"""
Check whether it works to pass the same list from one external
fun to another
[bookkeeper and list joining issues]
"""
def function_with_list():
pass
register_external(function_with_list, [[int]], int)
def function_returning_list():
pass
register_external(function_returning_list, [], [int])
def f():
return function_with_list(function_returning_list())
policy = AnnotatorPolicy()
a = RPythonAnnotator(policy=policy)
s = a.build_types(f, [])
assert isinstance(s, annmodel.SomeInteger)
def test_register_external_specialcase(self):
"""
When args=None, the external function accepts any arguments unmodified.
"""
def function_withspecialcase(arg):
return repr(arg)
register_external(function_withspecialcase, args=None, result=str)
def f():
x = function_withspecialcase
return x(33) + x("aaa") + x([]) + "\n"
policy = AnnotatorPolicy()
a = RPythonAnnotator(policy=policy)
s = a.build_types(f, [])
assert isinstance(s, annmodel.SomeString)
def test_str0(self):
str0 = annmodel.SomeString(no_nul=True)
def os_open(s):
pass
register_external(os_open, [str0], None)
def f(s):
return os_open(s)
policy = AnnotatorPolicy()
a = RPythonAnnotator(policy=policy)
a.build_types(f, [str]) # Does not raise
assert a.translator.config.translation.check_str_without_nul == False
# Now enable the str0 check, and try again with a similar function
a.translator.config.translation.check_str_without_nul=True
def g(s):
return os_open(s)
py.test.raises(Exception, a.build_types, g, [str])
a.build_types(g, [str0]) # Does not raise
def test_list_of_str0(self):
str0 = annmodel.SomeString(no_nul=True)
def os_execve(l):
pass
register_external(os_execve, [[str0]], None)
def f(l):
return os_execve(l)
policy = AnnotatorPolicy()
a = RPythonAnnotator(policy=policy)
a.build_types(f, [[str]]) # Does not raise
assert a.translator.config.translation.check_str_without_nul == False
# Now enable the str0 check, and try again with a similar function
a.translator.config.translation.check_str_without_nul=True
def g(l):
return os_execve(l)
py.test.raises(Exception, a.build_types, g, [[str]])
a.build_types(g, [[str0]]) # Does not raise
|