• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / RestrictedPython / 11230727746

08 Oct 2024 07:33AM UTC coverage: 98.197% (-0.7%) from 98.863%
11230727746

Pull #289

github

dataflake
- fix outdated Python version for tox coverage test
Pull Request #289: Support Python 3.13

380 of 409 branches covered (92.91%)

2505 of 2551 relevant lines covered (98.2%)

0.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.49
/tests/test_compile_restricted_function.py
1
from types import FunctionType
1✔
2

3
from RestrictedPython import PrintCollector
1✔
4
from RestrictedPython import compile_restricted_function
1✔
5
from RestrictedPython import safe_builtins
1✔
6
from RestrictedPython._compat import IS_PY38_OR_GREATER
1✔
7
from RestrictedPython._compat import IS_PY310_OR_GREATER
1✔
8

9

10
def test_compile_restricted_function():
1✔
11
    p = ''
1✔
12
    body = """
1✔
13
print("Hello World!")
14
return printed
15
"""
16
    name = "hello_world"
1✔
17
    global_symbols = []
1✔
18

19
    result = compile_restricted_function(
1✔
20
        p,  # parameters
21
        body,
22
        name,
23
        filename='<string>',
24
        globalize=global_symbols
25
    )
26

27
    assert result.code is not None
1✔
28
    assert result.errors == ()
1✔
29

30
    safe_globals = {
1✔
31
        '__name__': 'script',
32
        '_getattr_': getattr,
33
        '_print_': PrintCollector,
34
        '__builtins__': safe_builtins,
35
    }
36
    safe_locals = {}
1✔
37
    exec(result.code, safe_globals, safe_locals)
1✔
38
    hello_world = safe_locals['hello_world']
1✔
39
    assert type(hello_world) is FunctionType
1✔
40
    assert hello_world() == 'Hello World!\n'
1✔
41

42

43
def test_compile_restricted_function_func_wrapped():
1✔
44
    p = ''
1✔
45
    body = """
1✔
46
print("Hello World!")
47
return printed
48
"""
49
    name = "hello_world"
1✔
50
    global_symbols = []
1✔
51

52
    result = compile_restricted_function(
1✔
53
        p,  # parameters
54
        body,
55
        name,
56
        filename='<string>',
57
        globalize=global_symbols
58
    )
59

60
    assert result.code is not None
1✔
61
    assert result.errors == ()
1✔
62
    safe_globals = {
1✔
63
        '__name__': 'script',
64
        '_getattr_': getattr,
65
        '_print_': PrintCollector,
66
        '__builtins__': safe_builtins,
67
    }
68

69
    func = FunctionType(result.code, safe_globals)
1✔
70
    func()
1✔
71
    assert 'hello_world' in safe_globals
1✔
72
    hello_world = safe_globals['hello_world']
1✔
73
    assert hello_world() == 'Hello World!\n'
1✔
74

75

76
def test_compile_restricted_function_with_arguments():
1✔
77
    p = 'input1, input2'
1✔
78
    body = """
1✔
79
print(input1 + input2)
80
return printed
81
"""
82
    name = "hello_world"
1✔
83
    global_symbols = []
1✔
84

85
    result = compile_restricted_function(
1✔
86
        p,  # parameters
87
        body,
88
        name,
89
        filename='<string>',
90
        globalize=global_symbols
91
    )
92

93
    assert result.code is not None
1✔
94
    assert result.errors == ()
1✔
95

96
    safe_globals = {
1✔
97
        '__name__': 'script',
98
        '_getattr_': getattr,
99
        '_print_': PrintCollector,
100
        '__builtins__': safe_builtins,
101
    }
102
    safe_locals = {}
1✔
103
    exec(result.code, safe_globals, safe_locals)
1✔
104
    hello_world = safe_locals['hello_world']
1✔
105
    assert type(hello_world) is FunctionType
1✔
106
    assert hello_world('Hello ', 'World!') == 'Hello World!\n'
1✔
107

108

109
def test_compile_restricted_function_can_access_global_variables():
1✔
110
    p = ''
1✔
111
    body = """
1✔
112
print(input)
113
return printed
114
"""
115
    name = "hello_world"
1✔
116
    global_symbols = ['input']
1✔
117

118
    result = compile_restricted_function(
1✔
119
        p,  # parameters
120
        body,
121
        name,
122
        filename='<string>',
123
        globalize=global_symbols
124
    )
125

126
    assert result.code is not None
1✔
127
    assert result.errors == ()
1✔
128

129
    safe_globals = {
1✔
130
        '__name__': 'script',
131
        '_getattr_': getattr,
132
        'input': 'Hello World!',
133
        '_print_': PrintCollector,
134
        '__builtins__': safe_builtins,
135
    }
136
    safe_locals = {}
1✔
137
    exec(result.code, safe_globals, safe_locals)
1✔
138
    hello_world = safe_locals['hello_world']
1✔
139
    assert type(hello_world) is FunctionType
1✔
140
    assert hello_world() == 'Hello World!\n'
1✔
141

142

143
def test_compile_restricted_function_pretends_the_code_is_executed_in_a_global_scope():  # NOQA: E501
1✔
144
    p = ''
1✔
145
    body = """output = output + 'bar'"""
1✔
146
    name = "hello_world"
1✔
147
    global_symbols = ['output']
1✔
148

149
    result = compile_restricted_function(
1✔
150
        p,  # parameters
151
        body,
152
        name,
153
        filename='<string>',
154
        globalize=global_symbols
155
    )
156

157
    assert result.code is not None
1✔
158
    assert result.errors == ()
1✔
159

160
    safe_globals = {
1✔
161
        '__name__': 'script',
162
        'output': 'foo',
163
        '__builtins__': {},
164
    }
165
    safe_locals = {}
1✔
166
    exec(result.code, safe_globals, safe_locals)
1✔
167
    hello_world = safe_locals['hello_world']
1✔
168
    assert type(hello_world) is FunctionType
1✔
169
    hello_world()
1✔
170
    assert safe_globals['output'] == 'foobar'
1✔
171

172

173
def test_compile_restricted_function_allows_invalid_python_identifiers_as_function_name():  # NOQA: E501
1✔
174
    p = ''
1✔
175
    body = """output = output + 'bar'"""
1✔
176
    name = "<foo>.bar.__baz__"
1✔
177
    global_symbols = ['output']
1✔
178

179
    result = compile_restricted_function(
1✔
180
        p,  # parameters
181
        body,
182
        name,
183
        filename='<string>',
184
        globalize=global_symbols
185
    )
186

187
    assert result.code is not None
1✔
188
    assert result.errors == ()
1✔
189

190
    safe_globals = {
1✔
191
        '__name__': 'script',
192
        'output': 'foo',
193
        '__builtins__': {},
194
    }
195
    safe_locals = {}
1✔
196
    exec(result.code, safe_globals, safe_locals)
1✔
197
    generated_function = tuple(safe_locals.values())[0]
1✔
198
    assert type(generated_function) is FunctionType
1✔
199
    generated_function()
1✔
200
    assert safe_globals['output'] == 'foobar'
1✔
201

202

203
def test_compile_restricted_function_handle_SyntaxError():
1✔
204
    p = ''
1✔
205
    body = """a("""
1✔
206
    name = "broken"
1✔
207

208
    result = compile_restricted_function(
1✔
209
        p,  # parameters
210
        body,
211
        name,
212
    )
213

214
    assert result.code is None
1✔
215
    if IS_PY310_OR_GREATER:
1!
216
        assert result.errors == (
1✔
217
            "Line 1: SyntaxError: '(' was never closed at statement: 'a('",
218
        )
219
    else:
220
        assert result.errors == (
×
221
            "Line 1: SyntaxError: unexpected EOF while parsing at statement:"
222
            " 'a('",
223
        )
224

225

226
def test_compile_restricted_function_invalid_syntax():
1✔
227
    p = ''
1✔
228
    body = '1=1'
1✔
229
    name = 'broken'
1✔
230

231
    result = compile_restricted_function(
1✔
232
        p,  # parameters
233
        body,
234
        name,
235
    )
236

237
    assert result.code is None
1✔
238
    assert len(result.errors) == 1
1✔
239
    error_msg = result.errors[0]
1✔
240

241
    if IS_PY310_OR_GREATER:
1!
242
        assert error_msg.startswith(
1✔
243
            "Line 1: SyntaxError: cannot assign to literal here. Maybe "
244
        )
245
    elif IS_PY38_OR_GREATER:
×
246
        assert error_msg.startswith(
×
247
            "Line 1: SyntaxError: cannot assign to literal at statement:"
248
        )
249
    else:
250
        assert error_msg.startswith(
×
251
            "Line 1: SyntaxError: can't assign to literal at statement:"
252
        )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc