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
|
"""develop tests
"""
import os
import types
import pytest
import pkg_resources
import setuptools.sandbox
from setuptools.sandbox import DirectorySandbox
class TestSandbox:
def test_devnull(self, tmpdir):
sandbox = DirectorySandbox(str(tmpdir))
sandbox.run(self._file_writer(os.devnull))
@staticmethod
def _file_writer(path):
def do_write():
with open(path, 'w') as f:
f.write('xxx')
return do_write
def test_win32com(self, tmpdir):
"""
win32com should not be prevented from caching COM interfaces
in gen_py.
"""
win32com = pytest.importorskip('win32com')
gen_py = win32com.__gen_path__
target = os.path.join(gen_py, 'test_write')
sandbox = DirectorySandbox(str(tmpdir))
try:
# attempt to create gen_py file
sandbox.run(self._file_writer(target))
finally:
if os.path.exists(target):
os.remove(target)
def test_setup_py_with_BOM(self):
"""
It should be possible to execute a setup.py with a Byte Order Mark
"""
target = pkg_resources.resource_filename(__name__,
'script-with-bom.py')
namespace = types.ModuleType('namespace')
setuptools.sandbox._execfile(target, vars(namespace))
assert namespace.result == 'passed'
def test_setup_py_with_CRLF(self, tmpdir):
setup_py = tmpdir / 'setup.py'
with setup_py.open('wb') as stream:
stream.write(b'"degenerate script"\r\n')
setuptools.sandbox._execfile(str(setup_py), globals())
class TestExceptionSaver:
def test_exception_trapped(self):
with setuptools.sandbox.ExceptionSaver():
raise ValueError("details")
def test_exception_resumed(self):
with setuptools.sandbox.ExceptionSaver() as saved_exc:
raise ValueError("details")
with pytest.raises(ValueError) as caught:
saved_exc.resume()
assert isinstance(caught.value, ValueError)
assert str(caught.value) == 'details'
def test_exception_reconstructed(self):
orig_exc = ValueError("details")
with setuptools.sandbox.ExceptionSaver() as saved_exc:
raise orig_exc
with pytest.raises(ValueError) as caught:
saved_exc.resume()
assert isinstance(caught.value, ValueError)
assert caught.value is not orig_exc
def test_no_exception_passes_quietly(self):
with setuptools.sandbox.ExceptionSaver() as saved_exc:
pass
saved_exc.resume()
def test_unpickleable_exception(self):
class CantPickleThis(Exception):
"This Exception is unpickleable because it's not in globals"
with setuptools.sandbox.ExceptionSaver() as saved_exc:
raise CantPickleThis('detail')
with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
saved_exc.resume()
assert str(caught.value) == "CantPickleThis('detail',)"
def test_unpickleable_exception_when_hiding_setuptools(self):
"""
As revealed in #440, an infinite recursion can occur if an unpickleable
exception while setuptools is hidden. Ensure this doesn't happen.
"""
class ExceptionUnderTest(Exception):
"""
An unpickleable exception (not in globals).
"""
with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
with setuptools.sandbox.save_modules():
setuptools.sandbox.hide_setuptools()
raise ExceptionUnderTest()
msg, = caught.value.args
assert msg == 'ExceptionUnderTest()'
def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir):
"""
When in a sandbox with setuptools hidden, a SandboxViolation
should reflect a proper exception and not be wrapped in
an UnpickleableException.
"""
def write_file():
"Trigger a SandboxViolation by writing outside the sandbox"
with open('/etc/foo', 'w'):
pass
sandbox = DirectorySandbox(str(tmpdir))
with pytest.raises(setuptools.sandbox.SandboxViolation) as caught:
with setuptools.sandbox.save_modules():
setuptools.sandbox.hide_setuptools()
sandbox.run(write_file)
cmd, args, kwargs = caught.value.args
assert cmd == 'open'
assert args == ('/etc/foo', 'w')
assert kwargs == {}
|