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

skchem.utils.Suppressor   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 28
Duplicated Lines 0 %
Metric Value
dl 0
loc 28
rs 10
wmc 4

3 Methods

Rating   Name   Duplication   Size   Complexity  
A Suppressor.__init__() 0 5 2
A Suppressor.__exit__() 0 7 1
A Suppressor.__enter__() 0 4 1
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