"""develop tests """ import os import types import pytest import pkg_resources import setuptools.sandbox class TestSandbox: def test_devnull(self, tmpdir): with setuptools.sandbox.DirectorySandbox(str(tmpdir)): 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_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" def __repr__(self): return 'CantPickleThis%r' % (self.args,) 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 with pytest.raises(setuptools.sandbox.SandboxViolation) as caught: with setuptools.sandbox.save_modules(): setuptools.sandbox.hide_setuptools() with setuptools.sandbox.DirectorySandbox(str(tmpdir)): write_file() cmd, args, kwargs = caught.value.args assert cmd == 'open' assert args == ('/etc/foo', 'w') assert kwargs == {} msg = str(caught.value) assert 'open' in msg assert "('/etc/foo', 'w')" in msg