Example #1
0
    def trace_code(self, source, module_name=None):
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width

        try:
            tree = parse(source)

            new_tree = Tracer().visit(tree)
            fix_missing_locations(new_tree)
            LineNumberCleaner().visit(new_tree)
#             from ast import dump
#             print(dump(new_tree, include_attributes=False))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')

            self.environment[CONTEXT_NAME] = builder
            if module_name is None:
                environment = self.environment
            else:
                mod = types.ModuleType(module_name)
                sys.modules[module_name] = mod
                # Any reason to set mod.__file__?

                mod.__dict__.update(self.environment)
                environment = mod.__dict__
            exec(code, environment)
            for value in environment.values():
                if isinstance(value, types.GeneratorType):
                    value.close()
        except SyntaxError:
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            builder.add_message(messages[-1].strip() + ' ', ex.lineno)
        except:
            etype, value, tb = sys.exc_info()
            is_reported = False
            builder.message_limit = None  # make sure we don't hit limit
            builder.max_width = None  # make sure we don't hit limit
            messages = traceback.format_exception_only(etype, value)
            message = messages[-1].strip() + ' '
            entries = traceback.extract_tb(tb)
            for filename, line_number, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    builder.add_extra_message(message, line_number)
                    is_reported = True
            if not is_reported:
                builder.add_message(message, 1)
#                print('=== Unexpected Exception in tracing code ===')
#                traceback.print_exception(etype, value, tb)

        return builder.report()
Example #2
0
    def trace_code(self, source):
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width

        try:
            tree = parse(source)

            visitor = TraceAssignments()
            new_tree = visitor.visit(tree)
            fix_missing_locations(new_tree)
            #             from ast import dump
            #             print(dump(new_tree, include_attributes=False))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')

            self.environment[CONTEXT_NAME] = builder
            exec(code, self.environment, self.environment)
        except SyntaxError:
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            builder.add_message(messages[-1].strip() + ' ', ex.lineno)
        except:
            etype, value, tb = sys.exc_info()
            is_reported = False
            builder.message_limit = None  # make sure we don't hit limit
            builder.max_width = None  # make sure we don't hit limit
            messages = traceback.format_exception_only(etype, value)
            message = messages[-1].strip() + ' '
            entries = traceback.extract_tb(tb)
            for filename, line_number, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    builder.add_extra_message(message, line_number)
                    is_reported = True
            if not is_reported:
                builder.add_message(message, 1)


#                print('=== Unexpected Exception in tracing code ===')
#                traceback.print_exception(etype, value, tb)

        return builder.report()
Example #3
0
    def trace_code(self, source):
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width

        try:
            tree = parse(source)
    
            visitor = TraceAssignments()
            new_tree = visitor.visit(tree)
            fix_missing_locations(new_tree)
#             from ast import dump
#             print(dump(new_tree, include_attributes=False))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')
            
            self.environment[CONTEXT_NAME] = builder
            exec(code, self.environment, self.environment)
        except SyntaxError:
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            builder.add_message(messages[-1].strip() + ' ', ex.lineno)
        except:
            etype, value, tb = sys.exc_info()
            is_reported = False
            builder.message_limit = None # make sure we don't hit limit
            builder.max_width = None # make sure we don't hit limit
            messages = traceback.format_exception_only(etype, value)
            message = messages[-1].strip() + ' '
            entries = traceback.extract_tb(tb)
            for filename, line_number, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    builder.add_extra_message(message, line_number)
                    is_reported = True
            if not is_reported:
                builder.add_message(message, 1)
#                print('=== Unexpected Exception in tracing code ===')
#                traceback.print_exception(etype, value, tb)
                
        return builder.report()
Example #4
0
    def trace_code(self,
                   source,
                   load_as=SCOPE_NAME,
                   is_module=False,
                   dump=False,
                   driver=None,
                   filename=None,
                   bad_driver=None):
        """ Trace a module of source code, possibly by running a driver script.

        :param str source: the source code to trace
        :param str load_as: the module name to load the source code as
        :param bool is_module: True if the driver is a module name instead of a
        file name
        :param bool dump: True if the source code should be included in the
        output
        :param list driver: the driver script's file name or module name and args
        :param str filename: the file name of the source code
        :param str bad_driver: a message to display if the driver doesn't call
        the module
        """
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width
        self.return_code = 0

        try:
            tree = parse(source, PSEUDO_FILENAME)

            new_tree = Tracer().visit(tree)
            fix_missing_locations(new_tree)
            LineNumberCleaner().visit(new_tree)
            # from ast import dump
            # print(dump(new_tree, include_attributes=True))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')

            # Set sys.argv properly.
            old_argv = sys.argv
            sys.argv = driver or [filename or load_as]

            try:
                self.run_code(code, builder, load_as, is_module, driver,
                              filename, bad_driver)
            finally:
                # Restore the old argv and path
                sys.argv = old_argv

                # During testing, we import these modules for every test case,
                # so force a reload. This is only likely to happen during testing.
                for target in (load_as, SCOPE_NAME):
                    if target in sys.modules:
                        del sys.modules[target]
                for i in reversed(range(len(sys.meta_path))):
                    if isinstance(sys.meta_path[i], TracedModuleImporter):
                        sys.meta_path.pop(i)

            for value in self.environment.values():
                if isinstance(value, types.GeneratorType):
                    value.close()
        except SyntaxError:
            self.return_code = 1
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            message = messages[-1].strip()
            if ex.filename == PSEUDO_FILENAME:
                line_number = ex.lineno
            else:
                line_number = 1
                message = '{} line {}: {}'.format(ex.filename, ex.lineno,
                                                  message)
            builder.add_message(message, line_number)
        except BaseException as ex:
            self.return_code = getattr(ex, 'code', 1)
            etype, value, tb = sys.exc_info()
            is_reported = False
            entries = traceback.extract_tb(tb)
            for filename, _, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    is_reported = True
            while not is_reported and tb is not None:
                frame = tb.tb_frame
                code = frame.f_code
                filename = code.co_filename
                if __file__ not in (filename, filename + 'c'):
                    break
                tb = tb.tb_next
            if not is_reported:
                if tb:
                    messages = traceback.format_exception(etype, value, tb)
                else:
                    messages = traceback.format_exception_only(etype, value)
                self.report_driver_result(builder, messages)

        report = builder.report(source.count('\n'))
        if dump:
            source_lines = source.splitlines()
            report_lines = report.splitlines()
            dump_lines = []
            source_width = max(map(len, source_lines))
            indent = 4
            for source_line, report_line in izip_longest(source_lines,
                                                         report_lines,
                                                         fillvalue=''):
                line = (indent * ' ' + source_line +
                        (source_width - len(source_line)) * ' ' + ' | ' +
                        report_line)
                dump_lines.append(line)
            report = '\n'.join(dump_lines)

        return report
Example #5
0
    def trace_code(self,
                   source,
                   load_as=None,
                   module=None,
                   dump=False,
                   driver=None,
                   filename=None):
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width

        try:
            tree = parse(source)

            new_tree = Tracer().visit(tree)
            fix_missing_locations(new_tree)
            LineNumberCleaner().visit(new_tree)
#             from ast import dump
#             print(dump(new_tree, include_attributes=False))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')

            self.environment[CONTEXT_NAME] = builder
            self.run_instrumented_module(code, load_as or SCOPE_NAME, filename)
            if driver:
                try:
                    with self.swallow_output():
                        if module:
                            self.run_python_module(driver[0], driver)
                        else:
                            self.run_python_file(driver[0], driver)
                except:
                    if not (builder.message_count or builder.history):
                        raise
            for value in self.environment.values():
                if isinstance(value, types.GeneratorType):
                    value.close()
        except SyntaxError:
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            builder.add_message(messages[-1].strip() + ' ', ex.lineno)
        except:
            etype, value, tb = sys.exc_info()
            is_reported = False
            builder.message_limit = None  # make sure we don't hit limit
            builder.max_width = None  # make sure we don't hit limit
            messages = traceback.format_exception_only(etype, value)
            message = messages[-1].strip() + ' '
            entries = traceback.extract_tb(tb)
            for filename, line_number, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    builder.add_extra_message(message, line_number)
                    is_reported = True
            if not is_reported:
                builder.add_message(message, 1)
#                print('=== Unexpected Exception in tracing code ===')
#                traceback.print_exception(etype, value, tb)

        report = builder.report()
        if dump:
            source_lines = source.splitlines()
            report_lines = report.splitlines()
            dump_lines = []
            source_width = max(map(len, source_lines))
            indent = 4
            for source_line, report_line in izip_longest(source_lines,
                                                         report_lines,
                                                         fillvalue=''):
                line = (indent * ' ' + source_line +
                        (source_width-len(source_line))*' ' +
                        ' | ' + report_line)
                dump_lines.append(line)
            report = '\n'.join(dump_lines)

        return report
Example #6
0
    def trace_code(self,
                   source,
                   load_as=None,
                   module=False,
                   dump=False,
                   driver=None,
                   filename=None):
        """ Trace a module of source code, possibly by running a driver script.
        
        :param str source: the source code to trace
        :param str load_as: the module name to load the source code as
        :param bool module: True if the driver is a module name instead of a
        file name
        :param bool dump: True if the source code should be included in the
        output
        :param str driver: the driver script's file name or module name
        :param str filename: the file name of the source code
        """
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width
        self.return_code = 0

        try:
            tree = parse(source)

            new_tree = Tracer().visit(tree)
            fix_missing_locations(new_tree)
            LineNumberCleaner().visit(new_tree)
            #             from ast import dump
            #             print(dump(new_tree, include_attributes=False))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')

            self.environment[CONTEXT_NAME] = builder
            is_own_driver = module and driver and driver[0] == load_as
            seed(0)
            self.run_instrumented_module(code, load_as, filename,
                                         is_own_driver)
            if driver and not is_own_driver:
                with self.swallow_output():
                    if not module:
                        self.run_python_file(driver[0], driver)
                    else:
                        module_name = driver[0]
                        try:
                            self.run_python_module(module_name, driver)
                        except SystemExit as ex:
                            if ex.code:
                                if module_name not in ('unittest', 'pytest'):
                                    raise
                                self.return_code = ex.code
                                result = (sys.stderr.last_line
                                          or 'FAIL        ')

                                result = module_name + ': ' + result
                                self.report_driver_result(builder, [result])
            for value in self.environment.values():
                if isinstance(value, types.GeneratorType):
                    value.close()
        except SyntaxError:
            self.return_code = 1
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            builder.add_message(messages[-1].strip() + ' ', ex.lineno)
        except BaseException as ex:
            self.return_code = getattr(ex, 'code', 1)
            etype, value, tb = sys.exc_info()
            is_reported = False
            messages = traceback.format_exception_only(etype, value)
            entries = traceback.extract_tb(tb)
            for filename, _, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    is_reported = True
            while not is_reported and tb is not None:
                frame = tb.tb_frame
                code = frame.f_code
                filename = code.co_filename
                if __file__ not in (filename, filename + 'c'):
                    break
                tb = tb.tb_next
            if not is_reported:
                if tb:
                    messages = traceback.format_exception(etype, value, tb)
                else:
                    messages = traceback.format_exception_only(etype, value)
                self.report_driver_result(builder, messages)

        report = builder.report(source.count('\n'))
        if dump:
            source_lines = source.splitlines()
            report_lines = report.splitlines()
            dump_lines = []
            source_width = max(map(len, source_lines))
            indent = 4
            for source_line, report_line in izip_longest(source_lines,
                                                         report_lines,
                                                         fillvalue=''):
                line = (indent * ' ' + source_line +
                        (source_width - len(source_line)) * ' ' + ' | ' +
                        report_line)
                dump_lines.append(line)
            report = '\n'.join(dump_lines)

        return report
    def trace_code(self,
                   source,
                   load_as=None,
                   module=None,
                   dump=False,
                   driver=None,
                   filename=None):
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width

        try:
            tree = parse(source)

            new_tree = Tracer().visit(tree)
            fix_missing_locations(new_tree)
            LineNumberCleaner().visit(new_tree)
#             from ast import dump
#             print(dump(new_tree, include_attributes=False))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')

            self.environment[CONTEXT_NAME] = builder
            self.run_instrumented_module(code, load_as or SCOPE_NAME, filename)
            if driver:
                with self.swallow_output():
                    if module:
                        module_name = driver[0]
                        try:
                            self.run_python_module(module_name, driver)
                        except SystemExit as ex:
                            if module_name != 'unittest':
                                raise
                            result = (sys.stderr.last_line or
                                      ex.code and 'FAIL        ' or 'OK') 
                                
                            result = 'unittest: ' + result
                            self.report_driver_result(builder, [result])
                    else:
                        self.run_python_file(driver[0], driver)
            for value in self.environment.values():
                if isinstance(value, types.GeneratorType):
                    value.close()
        except SyntaxError:
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            builder.add_message(messages[-1].strip() + ' ', ex.lineno)
        except:
            etype, value, tb = sys.exc_info()
            is_reported = False
            builder.message_limit = None  # make sure we don't hit limit
            builder.max_width = None  # make sure we don't hit limit
            messages = traceback.format_exception_only(etype, value)
            entries = traceback.extract_tb(tb)
            for filename, _, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    is_reported = True
            while not is_reported and tb is not None:
                frame = tb.tb_frame
                code = frame.f_code
                filename = code.co_filename
                if __file__ not in (filename, filename + 'c'):
                    break
                tb = tb.tb_next
            if not is_reported:
                if tb:
                    messages = traceback.format_exception(etype, value, tb)
                else:
                    messages = traceback.format_exception_only(etype, value)
                self.report_driver_result(builder, messages)

        report = builder.report()
        if dump:
            source_lines = source.splitlines()
            report_lines = report.splitlines()
            dump_lines = []
            source_width = max(map(len, source_lines))
            indent = 4
            for source_line, report_line in izip_longest(source_lines,
                                                         report_lines,
                                                         fillvalue=''):
                line = (indent * ' ' + source_line +
                        (source_width-len(source_line))*' ' +
                        ' | ' + report_line)
                dump_lines.append(line)
            report = '\n'.join(dump_lines)

        return report
Example #8
0
    def trace_code(self,
                   source,
                   global_context=dict(),
                   local_context=dict(),
                   dump=False):
        """ Trace a module of source code, possibly by running a driver script.
        
        :param str source: the source code to trace
        :param global_context: the context the code is executed in (globals)
        :param local_context:  the local context the code is executed in (locals)
        :param bool dump: True if the source code should be included in the
        output
        """
        builder = ReportBuilder(self.message_limit)
        builder.max_width = self.max_width
        self.report_builder = builder
        self.return_code = 0

        try:
            # Parse the original AST
            tree = parse(source, PSEUDO_FILENAME)

            # Modify the tree to add the insert statements
            new_tree = Tracer().visit(tree)
            fix_missing_locations(new_tree)
            LineNumberCleaner().visit(new_tree)
            # from ast import dump
            # print(dump(new_tree, include_attributes=True))
            code = compile(new_tree, PSEUDO_FILENAME, 'exec')

            # RUN CODE
            self.environment[CONTEXT_NAME] = builder

            # Make a copy of globals so as not to mutate
            global_context_copy = dict(global_context.items())
            global_context_copy[CONTEXT_NAME] = builder
            seed(0)
            with swallow_output():
                # ret_val = eval(code, context_copy)
                exec(code, global_context_copy, local_context)

            for value in self.environment.values():
                if isinstance(value, types.GeneratorType):
                    value.close()

        except SyntaxError:
            self.return_code = 1
            ex = sys.exc_info()[1]
            messages = traceback.format_exception_only(type(ex), ex)
            message = messages[-1].strip()
            if ex.filename == PSEUDO_FILENAME:
                line_number = ex.lineno
            else:
                line_number = 1
                message = '{} line {}: {}'.format(ex.filename, ex.lineno,
                                                  message)
            builder.add_message(message, line_number)

        except BaseException as ex:
            self.return_code = getattr(ex, 'code', 1)
            etype, value, tb = sys.exc_info()
            is_reported = False
            entries = traceback.extract_tb(tb)
            for filename, _, _, _ in entries:
                if filename == PSEUDO_FILENAME:
                    is_reported = True
            while not is_reported and tb is not None:
                frame = tb.tb_frame
                code = frame.f_code
                filename = code.co_filename
                if __file__ not in (filename, filename + 'c'):
                    break
                tb = tb.tb_next
            if not is_reported:
                if tb:
                    messages = traceback.format_exception(etype, value, tb)
                else:
                    messages = traceback.format_exception_only(etype, value)
                self.report_driver_result(builder, messages)

        report = builder.report(source.count('\n'))
        if dump:
            source_lines = source.splitlines()
            report_lines = report.splitlines()
            dump_lines = []
            source_width = max(map(len, source_lines))
            indent = 4
            for source_line, report_line in izip_longest(source_lines,
                                                         report_lines,
                                                         fillvalue=''):
                line = (indent * ' ' + source_line +
                        (source_width - len(source_line)) * ' ' + ' | ' +
                        report_line)
                dump_lines.append(line)
            report = '\n'.join(dump_lines)
        return report