Completed
Push — master ( 2bc047...202252 )
by Rich
01:16
created

Suppressor.__exit__()   A

Complexity

Conditions 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 1
dl 0
loc 7
rs 9.4285
1
#! /usr/bin/env python
2
#
3
# Copyright (C) 2007-2009 Rich Lewis <[email protected]>
4
# License: 3-clause BSD
5
6
"""
7
skchem.utils.suppress
8
9
Class for suppressing C extensions output
10
"""
11
import os
12
13
##
14
# Taken from:
15
# http://stackoverflow.com/questions/11130156/suppress-stdout-stderr-print-from-python-functions
16
##
17
18
class Suppressor(object):
19
    """
20
    A context manager for doing a "deep suppression" of stdout and stderr in
21
    Python, i.e. will suppress all print, even if the print originates in a
22
    compiled C/Fortran sub-function.
23
       This will not suppress raised exceptions, since exceptions are printed
24
    to stderr just before a script exits, and after the context manager has
25
    exited (at least, I think that is why it lets exceptions through).
26
    """
27
28
    def __init__(self):
29
        # Open a pair of null files
30
        self.null_fds = [os.open(os.devnull, os.O_RDWR) for _ in range(2)]
31
        # Save the actual stdout (1) and stderr (2) file descriptors.
32
        self.save_fds = (os.dup(1), os.dup(2))
33
34
    def __enter__(self):
35
        # Assign the null pointers to stdout and stderr.
36
        os.dup2(self.null_fds[0], 1)
37
        os.dup2(self.null_fds[1], 2)
38
39
    def __exit__(self, *_):
40
        # Re-assign the real stdout/stderr back to (1) and (2)
41
        os.dup2(self.save_fds[0], 1)
42
        os.dup2(self.save_fds[1], 2)
43
        # Close the null files
44
        os.close(self.null_fds[0])
45
        os.close(self.null_fds[1])
46