1
2
3
4
5
6
7
8
9 """Provide system and PyMVPA information useful while reporting bugs
10 """
11
12 __docformat__ = 'restructuredtext'
13
14 import time, sys, os, subprocess
15 import platform as pl
16 from tempfile import mkstemp
17 from StringIO import StringIO
18
19 import mvpa
20 from mvpa.base import externals, cfg
21
23 res = []
24 for e in t:
25 if isinstance(e, tuple):
26 es = _t2s(e)
27 if es != '':
28 res += ['(%s)' % es]
29 elif e != '':
30 res += [e]
31 return '/'.join(res)
32
33 __all__ = ['wtf']
34
36 """Convenience class to contain information about PyMVPA and OS
37
38 TODO: refactor to actually not contain just string representation
39 but rather a dictionary (of dictionaries)
40 """
41
45
47 """
48 TODO: refactor and redo ;)
49 """
50 out = StringIO()
51
52 out.write("Current date: %s\n" % time.strftime("%Y-%m-%d %H:%M"))
53
54 out.write("PyMVPA:\n")
55 out.write(" Version: %s\n" % mvpa.__version__)
56 out.write(" Path: %s\n" % mvpa.__file__)
57
58
59 out.write(" Version control (GIT):\n")
60 try:
61 gitpath = os.path.join(os.path.dirname(mvpa.__file__), os.path.pardir)
62 gitpathgit = os.path.join(gitpath, '.git')
63 if os.path.exists(gitpathgit):
64 for scmd, cmd in [
65 ('Status', ['status']),
66 ('Reference', 'show-ref -h HEAD'.split(' ')),
67 ('Difference from last release %s' % mvpa.__version__,
68 ['diff', '--shortstat', 'upstream/%s...' % mvpa.__version__])]:
69 try:
70 (tmpd, tmpn) = mkstemp('mvpa', 'git')
71 retcode = subprocess.call(['git',
72 '--git-dir=%s' % gitpathgit,
73 '--work-tree=%s' % gitpath] + cmd,
74 stdout=tmpd,
75 stderr=subprocess.STDOUT)
76 finally:
77 outlines = open(tmpn, 'r').readlines()
78 if len(outlines):
79 out.write(' %s:\n %s' % (scmd, ' '.join(outlines)))
80 os.remove(tmpn)
81
82
83 else:
84 raise RuntimeError, "%s is not under GIT" % gitpath
85 except Exception, e:
86 out.write(' GIT information could not be obtained due "%s"\n' % e)
87
88 out.write('SYSTEM:\n')
89 out.write(' OS: %s\n' %
90 ' '.join([os.name,
91 pl.system(),
92 pl.release(),
93 pl.version()]).rstrip())
94 out.write(' Distribution: %s\n' %
95 ' '.join([_t2s(pl.dist()),
96 _t2s(pl.mac_ver()),
97 _t2s(pl.win32_ver())]).rstrip())
98
99
100 sdeps = {True: [], False: []}
101 for dep in sorted(externals._KNOWN):
102 sdeps[externals.exists(dep, force=False)] += [dep]
103 out.write('EXTERNALS:\n')
104 out.write(' Present: %s\n' % ', '.join(sdeps[True]))
105 out.write(' Absent: %s\n' % ', '.join(sdeps[False]))
106
107 SV = ('.__version__', )
108 out.write(' Versions of critical externals:\n')
109 for e, mname, fs in (
110 ('ctypes', None, SV),
111 ('matplotlib', None, SV),
112 ('lxml', None, ('.etree.__version__',)),
113 ('nifti', None, SV),
114 ('numpy', None, SV),
115 ('openopt', 'openopt', SV),
116 ('openopt', 'scikits.openopt', ('.openopt.__version__',)),
117 ('pywt', None, SV),
118 ('rpy', None, ('.rpy_version',)),
119 ('scipy', None, SV),
120 ('shogun', None, ('.Classifier.Version_get_version_release()',)),
121 ):
122 try:
123 if not externals.exists(e):
124 continue
125 else:
126 if mname is None:
127 mname = e
128 m = __import__(mname)
129 svers = [eval('m%s' % (f,)) for f in fs]
130 sver = ' '.join(svers)
131 except Exception, exc:
132 sver = 'failed to query due to "%s"' % str(exc)
133 out.write(' %-12s: %s\n' % (e, sver))
134
135 if externals.exists('matplotlib'):
136 import matplotlib
137 out.write(' Matplotlib backend: %s\n' % matplotlib.get_backend())
138
139 out.write("RUNTIME:\n")
140 out.write(" PyMVPA Environment Variables:\n")
141 out.write(' '.join([' %-20s: "%s"\n' % (str(k), str(v))
142 for k, v in os.environ.iteritems()
143 if (k.startswith('MVPA') or k.startswith('PYTHON'))]))
144
145 out.write(" PyMVPA Runtime Configuration:\n")
146 out.write(' ' + str(cfg).replace('\n', '\n ').rstrip() + '\n')
147
148 try:
149 procstat = open('/proc/%d/status' % os.getpid()).readlines()
150 out.write(' Process Information:\n')
151 out.write(' ' + ' '.join(procstat))
152 except:
153 pass
154
155 self._info = out.getvalue()
156
158 if self._info is None:
159 self._acquire()
160 return self._info
161
162 __str__ = __repr__
163
164
165 -def wtf(filename=None):
166 """Report summary about PyMVPA and the system
167
168 :Keywords:
169 filename : None or string
170 If provided, information will be stored in a file, not printed
171 to the screen
172 """
173
174 info = WTF()
175 if filename is not None:
176 out = file(filename, 'w').write(str(info))
177 else:
178 return info
179
180
181 if __name__ == '__main__':
182 print wtf()
183