Документ взят из кэша поисковой машины. Адрес оригинального документа : http://kodomo.fbb.msu.ru/hg/allpy/file/c1091715f8a3/allpy/util.py
Дата изменения: Unknown
Дата индексирования: Sun Feb 3 20:41:20 2013
Кодировка:
allpy: c1091715f8a3 allpy/util.py

allpy

view allpy/util.py @ 1088:c1091715f8a3

Added allpy.util.Silence to faciliate running most code with as little noise as possible This class is intended for use around noisy chunks of code using `with`, e.g.:: with Silence(): structure = PDBParser().load_pdb(file) This will produce no output to stderr if no exceptions are raised in the code. Otherwise, all output will be printed as if the code was run without this wrapper. See docstrings for more documentation.
author Daniil Alexeyevsky <dendik@kodomo.fbb.msu.ru>
date Fri, 01 Jun 2012 13:43:02 +0400
parents a3e439d09322
children bc1a7595d9d1
line source
1 """Miscellanous utilities.
2 """
3 import sys
4 import warnings
5 import os
6 from tempfile import mkstemp
7 from StringIO import StringIO
9 def unzip(seq):
10 """The oppozite of zip() builtin."""
11 a, b = [], []
12 for x, y in seq:
13 a.append(x)
14 b.append(y)
15 return a, b
17 def open(filename, mode='r'):
18 """Open file. Return stdin/stdout for filename '-'."""
19 if filename == '-':
20 if 'w' in mode or 'a' in mode or '+' in mode:
21 return sys.stdout
22 if 'r' in mode:
23 return sys.stdin
24 raise AssertionError("Unknown file mode: %s" % mode)
25 else:
26 return file(filename, mode)
28 def remove_each(string, substrings):
29 """Remove each of substrings from string."""
30 for sub in substrings:
31 string = string.replace(sub, "")
32 return string
34 class UserDict(dict):
35 """Clone of dict that user may add attributes to."""
36 pass
38 class UserList(list):
39 """Clone of list that user may add attributes to."""
40 pass
42 class UserString(str):
43 """Clone of str that user may add attributes to."""
44 pass
46 def deprecated(message):
47 """Warn about function being deprecated."""
48 warnings.warn(message, DeprecationWarning, stacklevel=2)
50 class Silence(object):
51 """Context manager for use with `with`.
53 Run code in context without any message to the screen, but show all output
54 that was there if an error occured. E.g.::
56 with Silence():
57 structure = PDBParser().get_structure(name, file)
59 There are two mutually exclusive ways of silencing:
61 1. By replacing OS'es stdout/stderr with tempfile (called `dup`)
62 2. By replacing python's sys.stdout/sys.stderr with StringIO (`hide`)
64 For each of ways you may specify values: 'stdout', 'stderr' or 'both'.
65 E.g::
67 with Silence(dup="both"):
68 check_call(["mucle", alignment])
70 `Silence()` is equivalent to `Silence(hide='stderr')`
71 """
73 def __init__(self, hide=None, dup=None):
74 if dup is None and hide is None:
75 hide = "stderr"
76 assert not (dup is not None and hide is not None)
77 self.stderr = self.stdout = self.dup_stderr = self.dup_stdout = False
78 if dup == "stdout" or dup == "both":
79 self.dup_stdout = True
80 if dup == "stderr" or dup == "both":
81 self.dup_stderr = True
82 if hide == "stdout" or hide == "both":
83 self.stdout = True
84 if hide == "stderr" or hide == "both":
85 self.stderr = True
87 def __enter__(self):
88 assert not (self.stderr and self.dup_stderr)
89 assert not (self.stdout and self.dup_stdout)
90 if self.dup_stdout or self.dup_stderr:
91 fd, name = mkstemp(prefix="allpy-silent-")
92 self.captured_dup = os.fdopen(fd)
93 self.captured_dup_name = name
94 if self.dup_stdout:
95 self.dup_stdout = os.dup(sys.stdout.fileno())
96 os.dup2(self.captured_dup.fileno(), sys.stdout.fileno())
97 if self.dup_stderr:
98 self.dup_stderr = os.dup(sys.stderr.fileno())
99 os.dup2(self.captured_dup.fileno(), sys.stderr.fileno())
100 if self.stdout or self.stderr:
101 self.captured_output = StringIO()
102 if self.stdout:
103 self.stdout, sys.stdout = sys.stdout, self.captured_output
104 if self.stderr:
105 self.stderr, sys.stderr = sys.stderr, self.captured_output
107 def __exit__(self, exc_type, exc_value, traceback):
108 if self.stdout or self.stderr:
109 if self.stdout:
110 sys.stdout = self.stdout
111 if self.stderr:
112 sys.stderr = self.stderr
113 if exc_type is not None:
114 sys.stderr.write(self.captured_output.getvalue())
115 if self.dup_stdout or self.dup_stderr:
116 if self.dup_stdout:
117 os.dup2(self.dup_stdout, sys.stdout.fileno())
118 os.close(self.dup_stdout)
119 if self.dup_stderr:
120 os.dup2(self.dup_stderr, sys.stderr.fileno())
121 os.close(self.dup_stderr)
122 if exc_type is not None:
123 self.captured_dup.seek(0)
124 sys.stderr.write(self.captured_dup.read())
125 os.unlink(self.captured_dup_name)
127 # vim: set et ts=4 sts=4 sw=4: