/
test_compile.py
107 lines (89 loc) · 3.54 KB
/
test_compile.py
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
from . import compile
from RestrictedPython import compile_restricted
from RestrictedPython import CompileResult
from RestrictedPython._compat import IS_PY2
import pytest
import RestrictedPython.compile
def test_compile__compile_restricted_invalid_code_input():
with pytest.raises(TypeError):
compile_restricted(object(), '<string>', 'eval')
@pytest.mark.parametrize(*compile)
def test_compile__compile_restricted_exec__1(compile):
"""It returns a CompileResult on success."""
result = compile('a = 42')
assert result.__class__ == CompileResult
assert result.errors == ()
assert result.warnings == []
assert result.used_names == {}
glob = {}
exec(result.code, glob)
assert glob['a'] == 42
@pytest.mark.parametrize(*compile)
def test_compile__compile_restricted_exec__2(compile):
"""It compiles without restrictions if there is no policy."""
if compile is RestrictedPython.compile.compile_restricted_exec:
# The old version does not support a custom policy
result = compile('_a = 42', policy=None)
assert result.errors == ()
assert result.warnings == []
assert result.used_names == {}
glob = {}
exec(result.code, glob)
assert glob['_a'] == 42
@pytest.mark.parametrize(*compile)
def test_compile__compile_restricted_exec__3(compile):
"""It returns a tuple of errors if the code is not allowed.
There is no code in this case.
"""
result = compile('_a = 42\n_b = 43')
errors = (
'Line 1: "_a" is an invalid variable name because it starts with "_"',
'Line 2: "_b" is an invalid variable name because it starts with "_"')
if compile is RestrictedPython.compile.compile_restricted_exec:
assert result.errors == errors
else:
# The old version did only return the first error message.
assert result.errors == (errors[0],)
assert result.warnings == []
assert result.used_names == {}
assert result.code is None
@pytest.mark.parametrize(*compile)
def test_compile__compile_restricted_exec__4(compile):
"""It does not return code on a SyntaxError."""
result = compile('asdf|')
assert result.code is None
assert result.warnings == []
assert result.used_names == {}
if compile is RestrictedPython.compile.compile_restricted_exec:
assert result.errors == (
'Line 1: SyntaxError: invalid syntax in on statement: asdf|',)
else:
# The old version had a less nice error message:
assert result.errors == ('invalid syntax (<string>, line 1)',)
@pytest.mark.parametrize(*compile)
def test_compile__compile_restricted_exec__5(compile):
"""It does not return code if the code contains a NULL byte."""
result = compile('a = 5\x00')
assert result.code is None
assert result.warnings == []
assert result.used_names == {}
if IS_PY2:
assert result.errors == (
'compile() expected string without null bytes',)
else:
assert result.errors == (
'source code string cannot contain null bytes',)
EXEC_STATEMENT = """\
def no_exec():
exec 'q = 1'
"""
@pytest.mark.skipif(
IS_PY2,
reason="exec statement in Python 2 is handled by RestrictedPython ")
@pytest.mark.parametrize(*compile)
def test_compile__compile_restricted_exec__10(compile):
"""It is a SyntaxError to use the `exec` statement. (Python 3 only)"""
result = compile(EXEC_STATEMENT)
assert (
"Line 2: SyntaxError: Missing parentheses in call to 'exec' in on "
"statement: exec 'q = 1'",) == result.errors