summaryrefslogtreecommitdiff
path: root/testing/support.py
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2015-11-18 12:28:44 +0100
committerArmin Rigo <arigo@tunes.org>2015-11-18 12:28:44 +0100
commitd995bf5eda3cd8dae5c86206ee44f4ccd77d70bb (patch)
tree14a0060a9d11803d4e629f4aa86bd668bd94faba /testing/support.py
parent1b266852f4dc07efdca37f2fe495cc42b60c1a31 (diff)
downloadcffi-d995bf5eda3cd8dae5c86206ee44f4ccd77d70bb.tar.gz
Write one error message directly to stderr instead of sys.stderr. This
lets us avoid taking the GIL, which might crash in case the Python interpreter is not initialized at all.
Diffstat (limited to 'testing/support.py')
-rw-r--r--testing/support.py37
1 files changed, 37 insertions, 0 deletions
diff --git a/testing/support.py b/testing/support.py
index 17c56cd..17ee621 100644
--- a/testing/support.py
+++ b/testing/support.py
@@ -17,3 +17,40 @@ else:
u = ""
unicode = str
long = int
+
+
+class StdErrCapture(object):
+ """Capture writes to sys.stderr (not to the underlying file descriptor)."""
+ def __enter__(self):
+ import StringIO
+ self.old_stderr = sys.stderr
+ sys.stderr = f = StringIO.StringIO()
+ return f
+ def __exit__(self, *args):
+ sys.stderr = self.old_stderr
+
+
+class FdWriteCapture(object):
+ """xxx limited to capture at most 512 bytes of output, according
+ to the Posix manual."""
+
+ def __init__(self, capture_fd=2): # stderr by default
+ self.capture_fd = capture_fd
+
+ def __enter__(self):
+ import os
+ self.read_fd, self.write_fd = os.pipe()
+ self.copy_fd = os.dup(self.capture_fd)
+ os.dup2(self.write_fd, self.capture_fd)
+ return self
+
+ def __exit__(self, *args):
+ import os
+ os.dup2(self.copy_fd, self.capture_fd)
+ os.close(self.copy_fd)
+ os.close(self.write_fd)
+ self._value = os.read(self.read_fd, 512)
+ os.close(self.read_fd)
+
+ def getvalue(self):
+ return self._value