Commit 047a1d83 authored by Stefan Behnel's avatar Stefan Behnel

move file descriptor redirecting to Cython.Utils package and use it as context...

move file descriptor redirecting to Cython.Utils package and use it as context manager in test runner
parent bde66547
......@@ -8,6 +8,7 @@ import sys
import re
import io
import codecs
from contextlib import contextmanager
modification_time = os.path.getmtime
......@@ -344,3 +345,38 @@ def get_cython_cache_dir():
# last fallback: ~/.cython
return os.path.expanduser(os.path.join('~', '.cython'))
@contextmanager
def captured_fd(stream=2):
pipe_in = t = None
orig_stream = os.dup(stream) # keep copy of original stream
try:
pipe_in, pipe_out = os.pipe()
os.dup2(pipe_out, stream) # replace stream by copy of pipe
try:
os.close(pipe_out) # close original pipe-out stream
data = []
def copy():
try:
while True:
d = os.read(pipe_in, 1000)
if d:
data.append(d)
else:
break
finally:
os.close(pipe_in)
from threading import Thread
t = Thread(target=copy)
t.daemon = True # just in case
t.start()
yield data
finally:
os.dup2(orig_stream, stream) # restore original stream
if t is not None:
t.join()
finally:
os.close(orig_stream)
......@@ -867,33 +867,24 @@ class CythonCompileTestCase(unittest.TestCase):
so_path = None
if not self.cython_only:
c_compiler_output = None
orig_stderr = os.dup(2) # remember original stderr
from Cython.Utils import captured_fd
c_compiler_stderr = None
try:
with tempfile.TemporaryFile() as temp_stderr:
os.dup2(temp_stderr.fileno(), 2) # replace stderr by temp file
try:
try:
so_path = self.run_distutils(test_directory, module, workdir, incdir)
finally:
temp_stderr.seek(0)
c_compiler_output = temp_stderr.read().strip()
except Exception:
if expected_errors == '_FAIL_C_COMPILE':
assert c_compiler_output
else:
raise
else:
if c_compiler_output:
print("\n=== C/C++ compiler output: ===")
print(c_compiler_output)
if expected_errors == '_FAIL_C_COMPILE':
# must raise this outside the try block
raise RuntimeError('should have failed C compile')
finally:
os.dup2(orig_stderr, 2) # restore stderr
finally:
os.close(orig_stderr)
with captured_fd(2) as c_compiler_stderr:
so_path = self.run_distutils(test_directory, module, workdir, incdir)
except Exception:
if expected_errors == '_FAIL_C_COMPILE':
assert c_compiler_stderr
else:
raise
else:
c_compiler_stderr = ''.join(c_compiler_stderr).strip()
if c_compiler_stderr:
print("\n=== C/C++ compiler output: ===")
print(c_compiler_stderr)
if expected_errors == '_FAIL_C_COMPILE':
# must raise this outside the try block
raise RuntimeError('should have failed C compile')
return so_path
class CythonRunTestCase(CythonCompileTestCase):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment