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', 'scikits.openopt', ('.openopt.__version__',)),
116 ('pywt', None, SV),
117 ('rpy', None, ('.rpy_version',)),
118 ('scipy', None, SV),
119 ('shogun', None, ('.Classifier.Version_get_version_release()',)),
120 ):
121 try:
122 if not externals.exists(e):
123 continue
124 else:
125 if mname is None:
126 mname = e
127 m = __import__(mname)
128 svers = [eval('m%s' % (f,)) for f in fs]
129 sver = ' '.join(svers)
130 except Exception, exc:
131 sver = 'failed to query due to "%s"' % str(exc)
132 out.write(' %-12s: %s\n' % (e, sver))
133
134 if externals.exists('matplotlib'):
135 import matplotlib
136 out.write(' Matplotlib backend: %s\n' % matplotlib.get_backend())
137
138 out.write("RUNTIME:\n")
139 out.write(" PyMVPA Environment Variables:\n")
140 out.write(' '.join([' %-20s: "%s"\n' % (str(k), str(v))
141 for k, v in os.environ.iteritems()
142 if (k.startswith('MVPA') or k.startswith('PYTHON'))]))
143
144 out.write(" PyMVPA Runtime Configuration:\n")
145 out.write(' ' + str(cfg).replace('\n', '\n ').rstrip() + '\n')
146
147 try:
148 procstat = open('/proc/%d/status' % os.getpid()).readlines()
149 out.write(' Process Information:\n')
150 out.write(' ' + ' '.join(procstat))
151 except:
152 pass
153
154 self._info = out.getvalue()
155
157 if self._info is None:
158 self._acquire()
159 return self._info
160
161 __str__ = __repr__
162
163
164 -def wtf(filename=None):
165 """Report summary about PyMVPA and the system
166
167 :Keywords:
168 filename : None or string
169 If provided, information will be stored in a file, not printed
170 to the screen
171 """
172
173 info = WTF()
174 if filename is not None:
175 out = file(filename, 'w').write(str(info))
176 else:
177 return info
178
179
180 if __name__ == '__main__':
181 print wtf()
182