diff --git a/python/subunit/__init__.py b/python/subunit/__init__.py index 9c4fa5d..2d5c118 100644 --- a/python/subunit/__init__.py +++ b/python/subunit/__init__.py @@ -913,7 +913,12 @@ def debug(self): def _run(self, result): protocol = TestProtocolServer(result) - process = subprocess.Popen(self.script, shell=True, stdout=subprocess.PIPE) + # Explicitly invoke Python to run the script instead of relying on + # execute permissions, which may not be preserved during installation + import shlex + + script_parts = shlex.split(self.script) + process = subprocess.Popen([sys.executable] + script_parts, stdout=subprocess.PIPE) make_stream_binary(process.stdout) output = process.communicate()[0] protocol.readFrom(BytesIO(output)) diff --git a/python/subunit/tests/test_test_protocol2.py b/python/subunit/tests/test_test_protocol2.py index 6d1e03b..2874e43 100644 --- a/python/subunit/tests/test_test_protocol2.py +++ b/python/subunit/tests/test_test_protocol2.py @@ -30,7 +30,12 @@ from testtools import TestCase from testtools.matchers import Contains, HasLength from testtools.testresult.doubles import StreamResult -from testtools.tests.test_testresult import TestStreamResultContract + +try: + from testtools.tests.test_testresult import TestStreamResultContract +except ImportError: + # testtools >= 2.8 no longer includes the tests submodule + TestStreamResultContract = None import subunit import iso8601 @@ -54,11 +59,13 @@ ] -class TestStreamResultToBytesContract(TestCase, TestStreamResultContract): - """Check that StreamResult behaves as testtools expects.""" +if TestStreamResultContract is not None: - def _make_result(self): - return subunit.StreamResultToBytes(BytesIO()) + class TestStreamResultToBytesContract(TestCase, TestStreamResultContract): + """Check that StreamResult behaves as testtools expects.""" + + def _make_result(self): + return subunit.StreamResultToBytes(BytesIO()) class TestStreamResultToBytes(TestCase):