Suppressor   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 30
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
wmc 4
c 4
b 1
f 0
dl 0
loc 30
ccs 12
cts 12
cp 1
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 3 1
A __exit__() 0 6 1
A __enter__() 0 4 1
1
#! /usr/bin/env python
2
#
3
# Copyright (C) 2015-2016 Rich Lewis <[email protected]>
4
# License: 3-clause BSD
5
6 1
"""
7
skchem.utils.suppress
8
9
Class for suppressing C extensions output.
10
"""
11
12 1
import os
13
14
##
15
# Adapted from:
16
# http://stackoverflow.com/questions/11130156/suppress-stdout-stderr-print-from-python-functions
17
##
18
19 1
class Suppressor(object):
20
    """ A context manager for doing a "deep suppression" of stdout and stderr.
21
22
    It will suppress all print, even if the print originates in a compiled
23
    C/Fortran sub-function.
24
25
    This will not suppress raised exceptions, since exceptions are printed
26
    to stderr just before a script exits, and after the context manager has
27
    exited (at least, I think that is why it lets exceptions through).
28
    """
29
30
    # always have these on the class, so we can have multiple Suppressors with
31
    # out running out of file descriptors
32 1
    null_fds = [os.open(os.devnull, os.O_RDWR) for _ in range(2)]
33
34 1
    def __init__(self):
35
        # Save the actual stdout (1) and stderr (2) file descriptors.
36 1
        self.save_fds = (os.dup(1), os.dup(2))
37
38 1
    def __enter__(self):
39
        # Assign the null pointers to stdout and stderr.
40 1
        os.dup2(Suppressor.null_fds[0], 1)
41 1
        os.dup2(Suppressor.null_fds[1], 2)
42
43 1
    def __exit__(self, *_):
44
        # Re-assign the real stdout/stderr back to (1) and (2)
45 1
        os.dup2(self.save_fds[0], 1)
46 1
        os.dup2(self.save_fds[1], 2)
47 1
        os.close(self.save_fds[0])
48 1
        os.close(self.save_fds[1])
49
50