This file is indexed.

/usr/lib/python2.7/dist-packages/cpl/result.py is in python-cpl 0.7.2-1build2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
import collections
import os
import signal
import logging

try: # pragma: no cover
    from astropy.io import fits
except ImportError:
    import pyfits as fits

class Result(object):
    def __init__(self, directory, res, input_len = 0, logger = None, 
                 output_format = fits.HDUList):
        '''Build an object containing all result frames.

        Calling :meth:`cpl.Recipe.__call__` returns an object that contains
        all result ('production') frames in attributes. All results for one
        tag are summarized in one attribute of the same name. 

        If the argument `output_format` is :class:`astropy.io.fits.HDUList`
        (default), then the attribute content is either a
        :class:`astropy.io.fits.HDUList` or a class:`list` of HDU lists,
        depending on the recipe and the call: If the recipe produces one out
        put frame of a tag per input file, the attribute contains a list if
        the recipe was called with a list, and if the recipe was called with a
        single input frame, the result attribute will also contain a single
        input frame. If the recipe combines all input frames to one output
        frame, a single :class:`astropy.io.fits.HDUList` es returned,
        independent of the input parameters.

        Similarly, if the argument `output_format` is set to :class:`str`, the
        attribute content is either a :class:`str` or a class:`list` of
        :class:`str`, containing the paths of output files. In this case,
        removing the output files is suppressed.

        .. todo:: This behaviour is made on some heuristics based on the
           number and type of the input frames. The heuristics will go wrong
           if there is only one input frame, specified as a list, but the
           recipe tries to summarize the input. In this case, the attribute
           will contain a list where a single :class:`astropy.io.fits.HDUList`
           was expected. To solve this problem, the "MASTER" flag has to be
           forwarded from the (MUSE) recipe which means that it should be
           exported by the recipe -- this is a major change since it probably
           leads into a replacement of CPLs recipeconfig module by something
           more sophisticated. And this is not usable for non-MUSE recipes
           anyway. So, we will skip this to probably some distant future.
        '''
        self.dir = os.path.abspath(directory)
        logger.join()
        if res[2][0]:
            raise CplError(res[2][0], res[1], logger)
        self.tags = set()
        for tag, frame in res[0]:
            if (output_format == fits.HDUList): 
                # Move the file to the base dir to avoid NFS problems
                outframe = os.path.join(
                    os.path.dirname(self.dir), 
                    '%s.%s' % (os.path.basename(self.dir), frame))
                os.rename(os.path.join(self.dir, frame), outframe)
            else:
                outframe = os.path.join(self.dir, frame)
            if output_format == fits.HDUList:
                hdulist = fits.open(outframe, memmap = True, mode = 'update')
                hdulist.readall()
                os.remove(outframe)
                outframe = hdulist
            tag = tag
            if tag not in self.__dict__:
                self.__dict__[tag] = outframe if input_len != 1 \
                    else [ outframe ]
                self.tags.add(tag)
            elif isinstance(self.__dict__[tag], (fits.HDUList, str)):
                self.__dict__[tag] = [ self.__dict__[tag], outframe ]
            else:
                self.__dict__[tag].append(outframe)
        mtracefname = os.path.join(self.dir, 'recipe.mtrace')
        mtrace = None
        if os.path.exists(mtracefname):
            try:
                mtrace = os.popen("mtrace %s" % mtracefname).read();
            except:
                mtrace = None
        self.stat = Stat(res[2], mtrace)
        self.error = CplError(res[2][0], res[1], logger) if res[1] else None
        self.log = logger.entries if logger else None

    def __getitem__(self, key):
        if key in self.tags:
            return self.__dict__[key]
        else:
            raise KeyError(key)

    def __contains__(self, key):
        return key in self.tags

    def __len__(self):
        return len(self.tags)

    def __iter__(self):
        return iter((key, self.__dict__[key]) for key in self.tags)

class Stat(object):
    def __init__(self, stat, mtrace):
        self.return_code = stat[0]
        self.user_time = stat[1]
        self.sys_time = stat[2]
        self.memory_is_empty = { -1:None, 0:False, 1:True }[stat[3]]
        self.mtrace = mtrace;

class CplError(Exception):
    '''Error message from the recipe.

    If the CPL recipe invocation returns an error, it is converted into a
    :class:`cpl.CplError` exception and no frames are returned. Also, the
    error is notified in the log file.

    The exception is raised on recipe invocation, or when accessing the result
    frames if the recipe was started in background
    (:attr:`cpl.Recipe.threaded` set to :obj:`True`).

    Attributes:

    .. attribute:: code

       The CPL error code returned from the recipe.

    .. attribute:: msg

       The supplied error message. 
    
    .. attribute:: filename

       The source file name where the error occurred.

    .. attribute:: line

       The line number where the error occurred.

    .. attribute:: log

       Log lines of the recipe that lead to this exception.

       .. seealso:: :class:`cpl.logger.LogList`

    .. attribute:: next_error
     
       Next error, or :obj:`None`.

    '''
    def __init__(self, retval, res, logger = None):
        self.retval = retval
        self.log = logger.entries if logger else None
        self.next_error = None
        if not res:
            self.code, self.msg, self.file, self.line, self.function = (
                None, None, None, None, None)
        else:
            self.code, self.msg, self.file, self.line, self.function = res[0]
            o = self
            for r in res[1:]:
                o.next_error = CplError(retval, [ r ], logger)
                o = o.next_error
    
    def __iter__(self):
        class Iter(object):
            current = self
            def __next__(self):
                if Iter.current is None:
                    raise StopIteration
                s = Iter.current
                Iter.current = Iter.current.next_error
                return s
            def next(self):
                return self.__next__()
        return Iter()

    def __str__(self):
        if self.code is None:
            s = 'Unspecified'
        else:
            s = "%s (%i) in %s() (%s:%i)" % (self.msg, self.code, 
                                             self.function, self.file, 
                                             self.line) 
        if self.next_error:
            for e in self.next_error:
                s += "\n    %s (%i) in %s() (%s:%i)" % (e.msg, e.code, 
                                                        e.function, e.file, 
                                                        e.line) 
        return s

class RecipeCrash(Exception):
    '''Recipe crash exception

    If the CPL recipe crashes with a SIGSEV or a SIGBUS, the C stack trace is
    tried to conserved in this exception. The stack trace is obtained with the
    GNU debugger gdb. If the debugger is not available, or if the debugger
    cannot be attached to the crashed recipe, the Exception remains empty.

    When converted to a string, the Exception will return a stack trace
    similar to the Python stack trace.

    The exception is raised on recipe invocation, or when accessing the result
    frames if the recipe was started in background
    (:attr:`cpl.Recipe.threaded` set to :obj:`True`).

    Attributes:

    .. attribute:: elements

       List of stack elements, with the most recent element (the one that
       caused the crash) at the end. Each stack element is a 
       :func:`collections.namedtuple` with the following attributes:

       .. attribute:: filename
 
          Source file name, including full path, if available.

       .. attribute:: line

          Line number, if available

       .. attribute:: func

          Function name, if available

       .. attribute:: params

          Dictionary parameters the function was called with.  The key here is
          the parameter name, the value is a string describing the value set.

       .. attribute:: localvars

          Dictionary of local variables of the function, if available.  The
          key here is the parameter name, the value is a string describing the
          value set.

    .. attribute:: signal

          Signal that caused the crash.
    '''

    StackElement = collections.namedtuple('StackElement', 
                                          'filename line func params localvars')
    signals = {signal.SIGSEGV:'SIGSEV: Segmentation Fault', 
               signal.SIGBUS:'SIGBUS: Bus Error',
               signal.SIGHUP:'SIGHUP: Hangup',
               signal.SIGABRT:'SIGABRT: Abnormal process termination',
               signal.SIGTERM:'SIGTERM: Terminated by user',
               signal.SIGQUIT:'SIGQUIT: Quit',
               signal.SIGFPE:'SIGFPE: Arithmetic Exception',
               signal.SIGINT:'SIGINT: Interrupt (Ctrl-C)',
               None:'Memory inconsistency detected'}
    def __init__(self, bt_file):
        self.elements = []
        current_element = None
        parse_functions = True
        parse_sourcelist = False
        sourcefiles = dict()
        self.signal = None
        self.lines = []
        for line in bt_file:
            self.lines.append(line)
            if line.startswith('Received signal:'):
                self.signal = int(line.split(':')[1])
            if line.startswith('Memory corruption'):
                self.signal = None
            elif line.find('signal handler called') >= 0:
                del self.elements[:]
            elif parse_functions:
                if line.startswith('#'):
                    try:
                        current_element = self._parse_function_line(line)
                    except StopIteration:
                        parse_functions = False
                elif current_element is not None:
                    self._add_variable(current_element.localvars, line)
            if line.startswith('Source files'):
                parse_sourcelist = True
                parse_functions = False
            elif parse_sourcelist:
                sourcefiles.update(dict((os.path.basename(s.strip()), s.strip())
                                        for s in line.split(',') 
                                        if s.rfind('/') > 0 ))
        self.elements = [ RecipeCrash.StackElement(sourcefiles.get(e.filename, 
                                                                   e.filename),
                                                   e.line, e.func, e.params, 
                                                   e.localvars) 
                          for e in self.elements ]
        Exception.__init__(self, str(self))

    def _add_variable(self, variables, line):
        s = line.strip().split('=', 1)
        if len(s) > 1:
            variables[s[0].strip()] = s[1].strip()

    def _parse_function_line(self, line):
        s = line.split()
        funcname = s[3] if s[1].startswith('0x') else s[1]
        if funcname.startswith('Py'):
            raise StopIteration()
        pars = {}
        for fp in line[line.find('(')+1:line.rfind(')')].split(','):
            self._add_variable(pars, fp)
        l = line[line.rfind(')')+1:].split()
        if not l:
            return None
        source = l[-1].split(':')
        filename = source[0]
        lineno = int(source[1]) if len(source) > 1 else None
        current_element = RecipeCrash.StackElement(filename, lineno, 
                                                   funcname, pars, {})
        self.elements.insert(0, current_element)
        return current_element
        
    def log(self, logger):
        '''Put the content of the crash into the log.
        '''
        log = logging.getLogger('%s' % logger.name)
        log.error('Recipe crashed. Traceback (most recent call last):')
        for e in self.elements:
            logc = logging.getLogger('%s.%s' % (logger.name, e.func))
            logc.error('  File "%s", %sin %s\n',e.filename, 
                       'line %i, ' % e.line if e.line else '', 
                       e.func)
            if os.path.exists(e.filename) and e.line:
                logc.error('    %s\n',
                           open(e.filename).readlines()[e.line-1].strip())
            if e.params:
                logc.error('  Parameters:')
                for p, v in e.params.items():
                    logc.error('    %s = %s', p, v)
            if e.localvars:
                logc.error('  Local variables:')
                for p, v in e.localvars.items():
                    logc.error('    %s = %s', p, v)
        log.error(RecipeCrash.signals.get(self.signal, 
                                          '%s: Unknown' % str(self.signal)))

    def __repr__(self):
        return 'RecipeCrash()'

    def __str__(self):
        s = 'Recipe Traceback (most recent call last):\n'
        for e in self.elements:
            s += '  File "%s", %sin %s\n' % ((e.filename), 
                                             'line %i, ' % e.line if e.line 
                                             else '', 
                                             e.func)
            if os.path.exists(e.filename) and e.line:
                s += '    %s\n' % open(e.filename).readlines()[e.line-1].strip()
        s += RecipeCrash.signals.get(self.signal, '%s: Unknown' % str(self.signal))
        return s