def flushWarnings(self, offendingFunctions=None): """ Remove stored warnings from the list of captured warnings and return them. @param offendingFunctions: If L{None}, all warnings issued during the currently running test will be flushed. Otherwise, only warnings which I{point} to a function included in this list will be flushed. All warnings include a filename and source line number; if these parts of a warning point to a source line which is part of a function, then the warning I{points} to that function. @type offendingFunctions: L{None} or L{list} of functions or methods. @raise ValueError: If C{offendingFunctions} is not L{None} and includes an object which is not a L{types.FunctionType} or L{types.MethodType} instance. @return: A C{list}, each element of which is a C{dict} giving information about one warning which was flushed by this call. The keys of each C{dict} are: - C{'message'}: The string which was passed as the I{message} parameter to L{warnings.warn}. - C{'category'}: The warning subclass which was passed as the I{category} parameter to L{warnings.warn}. - C{'filename'}: The name of the file containing the definition of the code object which was C{stacklevel} frames above the call to L{warnings.warn}, where C{stacklevel} is the value of the C{stacklevel} parameter passed to L{warnings.warn}. - C{'lineno'}: The source line associated with the active instruction of the code object object which was C{stacklevel} frames above the call to L{warnings.warn}, where C{stacklevel} is the value of the C{stacklevel} parameter passed to L{warnings.warn}. """ if offendingFunctions is None: toFlush = self._warnings[:] self._warnings[:] = [] else: toFlush = [] for aWarning in self._warnings: for aFunction in offendingFunctions: if not isinstance(aFunction, ( types.FunctionType, types.MethodType)): raise ValueError("%r is not a function or method" % ( aFunction,)) # inspect.getabsfile(aFunction) sometimes returns a # filename which disagrees with the filename the warning # system generates. This seems to be because a # function's code object doesn't deal with source files # being renamed. inspect.getabsfile(module) seems # better (or at least agrees with the warning system # more often), and does some normalization for us which # is desirable. inspect.getmodule() is attractive, but # somewhat broken in Python < 2.6. See Python bug 4845. aModule = sys.modules[aFunction.__module__] filename = inspect.getabsfile(aModule) if filename != os.path.normcase(aWarning.filename): continue lineStarts = list(_findlinestarts(aFunction.__code__)) first = lineStarts[0][1] last = lineStarts[-1][1] if not (first <= aWarning.lineno <= last): continue # The warning points to this function, flush it and move on # to the next warning. toFlush.append(aWarning) break # Remove everything which is being flushed. list(map(self._warnings.remove, toFlush)) return [ {'message': w.message, 'category': w.category, 'filename': w.filename, 'lineno': w.lineno} for w in toFlush]
def flushWarnings(self, offendingFunctions=None): """ Remove stored warnings from the list of captured warnings and return them. @param offendingFunctions: If C{None}, all warnings issued during the currently running test will be flushed. Otherwise, only warnings which I{point} to a function included in this list will be flushed. All warnings include a filename and source line number; if these parts of a warning point to a source line which is part of a function, then the warning I{points} to that function. @type offendingFunctions: C{NoneType} or L{list} of functions or methods. @raise ValueError: If C{offendingFunctions} is not C{None} and includes an object which is not a L{types.FunctionType} or L{types.MethodType} instance. @return: A C{list}, each element of which is a C{dict} giving information about one warning which was flushed by this call. The keys of each C{dict} are: - C{'message'}: The string which was passed as the I{message} parameter to L{warnings.warn}. - C{'category'}: The warning subclass which was passed as the I{category} parameter to L{warnings.warn}. - C{'filename'}: The name of the file containing the definition of the code object which was C{stacklevel} frames above the call to L{warnings.warn}, where C{stacklevel} is the value of the C{stacklevel} parameter passed to L{warnings.warn}. - C{'lineno'}: The source line associated with the active instruction of the code object object which was C{stacklevel} frames above the call to L{warnings.warn}, where C{stacklevel} is the value of the C{stacklevel} parameter passed to L{warnings.warn}. """ if offendingFunctions is None: toFlush = self._warnings[:] self._warnings[:] = [] else: toFlush = [] for aWarning in self._warnings: for aFunction in offendingFunctions: if not isinstance(aFunction, ( types.FunctionType, types.MethodType)): raise ValueError("%r is not a function or method" % ( aFunction,)) # inspect.getabsfile(aFunction) sometimes returns a # filename which disagrees with the filename the warning # system generates. This seems to be because a # function's code object doesn't deal with source files # being renamed. inspect.getabsfile(module) seems # better (or at least agrees with the warning system # more often), and does some normalization for us which # is desirable. inspect.getmodule() is attractive, but # somewhat broken in Python < 2.6. See Python bug 4845. aModule = sys.modules[aFunction.__module__] filename = inspect.getabsfile(aModule) if filename != os.path.normcase(aWarning.filename): continue lineStarts = list(_findlinestarts(aFunction.__code__)) first = lineStarts[0][1] last = lineStarts[-1][1] if not (first <= aWarning.lineno <= last): continue # The warning points to this function, flush it and move on # to the next warning. toFlush.append(aWarning) break # Remove everything which is being flushed. list(map(self._warnings.remove, toFlush)) return [ {'message': w.message, 'category': w.category, 'filename': w.filename, 'lineno': w.lineno} for w in toFlush]
def generate_disassembly(co, lasti=-1): report_template = ''' <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Disassembly</title> <style type="text/css"> body { font-family: "Courier New", Monospace, Monaco, Fixedsys, Courier; color: #ffffff; background-color: #001b33; } ul { list-style-type: none; } li.src_line { } li.src_line:hover { background-color: #003b70; } li[class^="op_line"] { } li[class^="op_line"]:hover { background-color: #003b70; } li.op_line_start { list-style-type: square; } li.op_line_jump { list-style-type: disc; } span { display: inline-block; } span.tab { display: none; } span.line_no { width: 40px; margin-left: 5px; margin-right: 5px; text-align: right; color: #0065bf; } span.src { width: 500px; color: #0088ff; } span.filename { width: 500px; color: #0088ff; } span.address { width: 40px; margin-left: 20px; margin-right: 5px; text-align: right; color: #0065bf; } span.op_ { width: 70px; margin-left: 5px; margin-right: 15px; color: #000d1a; } span.op { width: 70px; margin-left: 5px; margin-right: 15px; color: #666; } span.opname { width: 150px; margin-left: 5px; margin-right: 5px; } span.oparg { width: 50px; margin-left: 5px; margin-right: 5px; text-align: right; color: #ff0044; } span.decoration { width: 300px; margin-left: 5px; margin-right: 5px; color: #ff9d00; } span.decoration a { color: #3ad900; text-decoration: none; } span.decoration a:link { } span.decoration a:hover { text-decoration:underline; } span.decoration a:active { text-decoration:underline; } span.decoration a:visited { } </style> </head> <body> <div id="disassembly"> %s </div> </body> </html> ''' report = StringIO.StringIO() try: src_lines = open(co.co_filename).readlines() except: src_lines = [] code = co.co_code labels = dis.findlabels(code) #linestarts = range(0,0) #linestarts = dict(dis.findlinestarts(co)) linestarts = dict(_findlinestarts(co)) n = len(code) i = 0 extended_arg = 0 free = None into_op_block = False while i < n: if not into_op_block: report.write('<ul>') if i in linestarts: report.write('<li class="src_line">') line_no = linestarts[i] try: report.write('<span class="line_no">%d</span><span class="tab"> </span><span class="src">%s</span>' % (line_no, html_format(src_lines[line_no - 1].rstrip()))) except: report.write('<span class="line_no">%d</span><span class="tab"> </span><span class="filename">(\'%s\')</span>' % (line_no, html_format(co.co_filename))) report.write('</li>') if not into_op_block: report.write('<ul>') into_op_block = True # report.write('<li class="op_line_%s"><a name="%d"></a>' % # ('start' if i == lasti else 'jump' if i in labels else 'normal', i)) report.write('<li class="op_line_%s"><a name="%d"></a>' % ('start' , i)) op = ord(code[i]) i = i + 1 opname = opcode.opname[op] if op >= opcode.HAVE_ARGUMENT: oparg_low = ord(code[i]) oparg_high = ord(code[i + 1]) i = i + 2 oparg = oparg_low + oparg_high * 256 + extended_arg extended_arg = 0 if op == opcode.EXTENDED_ARG: extended_arg = oparg * 65536L if op in opcode.hasconst: const = co.co_consts[oparg] if hasattr(const, 'co_code'): decoration = '<a href="%(0)s">(%(0)s)</a>' % {'0': const.co_name} else: decoration = html_format('(%(0)s: %(1)s)' % {'0':repr(const), '1':type(const)}) elif op in opcode.hasname: decoration = html_format('(%(0)s)' % {'0':repr(co.co_names[oparg])}) elif op in opcode.hasjrel: decoration = '<a href="#%(0)s">(=> %(0)s)</a>' % {'0':i + oparg} elif op in opcode.hasjabs: decoration = '<a href="#%(0)s">(=> %(0)s)</a>' % {'0':oparg} elif op in opcode.haslocal: decoration = html_format('(%(0)s)' % {'0': repr(co.co_varnames[oparg])}) elif op in opcode.hascompare: decoration = html_format('(%(0)s)' % {'0': opcode.cmp_op[oparg]}) elif op in opcode.hasfree: if free is None: free = co.co_cellvars + co.co_freevars decoration = html_format('(%(0)s)' % {'0':repr(free[oparg])}) elif opname == 'CALL_FUNCTION': decoration = html_format('(pos args: %(0)s, key args: %(1)s)' % {'0':oparg_low, '1':oparg_high}) elif opname == 'MAKE_FUNCTION': decoration = html_format('(default args: %(0)s)' % {'0':oparg}) else: decoration = '' report.write('<span class="address">%d</span><span class="tab"> </span><span class="op">%02x %02x%02x</span><span class="tab"> </span><span class="opname">%s</span><span class="tab"> </span><span class="oparg">%d</span><span class="tab"> </span><span class="decoration">%s</span>' % (i - 3, op, oparg_low, oparg_high, html_format(opname), oparg, decoration)) else: report.write('<span class="address">%d</span><span class="tab"> </span><span class="op">%02x</span><span class="tab"> </span><span class="opname">%s</span>' % (i - 1, op, html_format(opname))) report.write('</li>') if i in linestarts or i >= n: report.write('</ul></ul>') into_op_block = False return report_template % report.getvalue()