Exemple #1
0
    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]
Exemple #2
0
    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]
Exemple #3
0
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">&nbsp;</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">&nbsp;</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">&nbsp;</span><span class="op">%02x&nbsp;%02x%02x</span><span class="tab">&nbsp;</span><span class="opname">%s</span><span class="tab">&nbsp;</span><span class="oparg">%d</span><span class="tab">&nbsp;</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">&nbsp;</span><span class="op">%02x</span><span class="tab">&nbsp;</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()