예제 #1
0
파일: errors_3k.py 프로젝트: Mekyi/crunchy
def simplify_syntax_error(code, ex_type, value, trace, lineno, username):
    """
    print out a syntax error
    closely based on showsyntaxerror from the code module
    in the standard library
    """
    filename = _("User's code")  # will most likely not be used
    # Work hard to stuff the correct filename in the exception
    try:
        msg, (filename, lineno, offset, line) = value
    except:
        # Not the format we expect; leave it alone
        pass
    else:
        # Stuff in the right filename
        value = SyntaxError(msg, (filename, lineno, offset, line))
        sys.last_value = value
    if username and config[username]['friendly']:# ignore that filename stuff!
        tb_list = traceback.format_exception_only(ex_type, value)[1:]
        tb_list.insert(0, "Error on line %s:\n"%lineno)
    else:
        tb_list = traceback.format_exception_only(ex_type, value)
    retval = StringIO()
    list(map(retval.write, tb_list))

    out = retval.getvalue().replace("Error on line",
                             _("Error on line") )
    return out
예제 #2
0
def simplify_syntax_error(code, ex_type, value, trace, lineno, username):
    """
    print out a syntax error
    closely based on showsyntaxerror from the code module
    in the standard library
    """
    filename = _(u"User's code").encode(
        "utf-8")  # will most likely not be used
    # Work hard to stuff the correct filename in the exception
    try:
        msg, (filename, lineno, offset, line) = value
    except:
        # Not the format we expect; leave it alone
        pass
    else:
        # Stuff in the right filename
        value = SyntaxError(msg, (filename, lineno, offset, line))
        sys.last_value = value
    if username and config[username]['friendly']:  # ignore that filename stuff!
        tb_list = traceback.format_exception_only(ex_type, value)[1:]
        tb_list.insert(0, "Error on line %s:\n" % lineno)
    else:
        tb_list = traceback.format_exception_only(ex_type, value)
    retval = StringIO()
    map(retval.write, tb_list)

    out = retval.getvalue().replace("Error on line", _(u"Error on line"))
    return out.encode("utf-8")
예제 #3
0
class CrunchyChecker:
    """Class to configure and start a pychecker analysis
    """

    def __init__(self):
        self._report = None
        self._code = None
        self._output_buffer = None

    def run(self, code):
        """Make the analysis"""
        self._code = code
        # Save the code in a temporary file
        temp = tempfile.NamedTemporaryFile(suffix = '.py')
        temp.write(self._code)
        temp.flush()
        fname = os.path.basename(temp.name)

        self._output_buffer = StringIO()
        checker._printWarnings = self._printWarnings
        checker.main(['dummy_arg', '--only', temp.name])
        # remove all traces of the Temporary file name
        self._report = self._output_buffer.getvalue().replace(temp.name, 'line')
        self._report = self._report.replace(fname[:-3] + ":", "")
        self._output_buffer.close()
        temp.close()

    def get_report(self):
        """Return the full report"""
        return "Report from pychecker:\n" + self._report

    def get_global_score(self):
        """Return the global score or None if not available.

        This score can be formatted with "%.2f/10" % score

        It is not computed by pychecker, but here, by the formule:
        score = 10 - ((number_of_errors / number_of_lines) * 10)
        """
        if not "UNABLE TO IMPORT" in self.get_report():
            # Just count non-empty and non-comment lines
            code_lines = [line for line in self._code.split('\n') \
                          if line.strip() and not line.strip().startswith('#')]
            report_lines = [line for line in self.get_report().split('\n') \
                            if line]
            if len(report_lines) == 1:
                return 10
            number_of_errors = float(len(report_lines)-1)
            number_of_lines = float(len(code_lines))
            return 10 - ((number_of_errors / number_of_lines) * 10)
        else:
            return 0

    def _printWarnings(self, warnings, stream=None):
        """This function call the original checker._printWarnings, but set
        the stream to self._output_buffer
        """
        original_printWarnings(warnings, self._output_buffer)
예제 #4
0
class CrunchyChecker:
    """Class to configure and start a pychecker analysis
    """
    def __init__(self):
        self._report = None
        self._code = None
        self._output_buffer = None

    def run(self, code):
        """Make the analysis"""
        self._code = code
        # Save the code in a temporary file
        temp = tempfile.NamedTemporaryFile(suffix='.py')
        temp.write(self._code)
        temp.flush()
        fname = os.path.basename(temp.name)

        self._output_buffer = StringIO()
        checker._printWarnings = self._printWarnings
        checker.main(['dummy_arg', '--only', temp.name])
        # remove all traces of the Temporary file name
        self._report = self._output_buffer.getvalue().replace(
            temp.name, 'line')
        self._report = self._report.replace(fname[:-3] + ":", "")
        self._output_buffer.close()
        temp.close()

    def get_report(self):
        """Return the full report"""
        return "Report from pychecker:\n" + self._report

    def get_global_score(self):
        """Return the global score or None if not available.

        This score can be formatted with "%.2f/10" % score

        It is not computed by pychecker, but here, by the formule:
        score = 10 - ((number_of_errors / number_of_lines) * 10)
        """
        if not "UNABLE TO IMPORT" in self.get_report():
            # Just count non-empty and non-comment lines
            code_lines = [line for line in self._code.split('\n') \
                          if line.strip() and not line.strip().startswith('#')]
            report_lines = [line for line in self.get_report().split('\n') \
                            if line]
            if len(report_lines) == 1:
                return 10
            number_of_errors = float(len(report_lines) - 1)
            number_of_lines = float(len(code_lines))
            return 10 - ((number_of_errors / number_of_lines) * 10)
        else:
            return 0

    def _printWarnings(self, warnings, stream=None):
        """This function call the original checker._printWarnings, but set
        the stream to self._output_buffer
        """
        original_printWarnings(warnings, self._output_buffer)
예제 #5
0
파일: vlam.py 프로젝트: Mekyi/crunchy
 def read(self):  # tested
     '''create fake file from a tree, adding DTD and charset information
        and return its value as a string'''
     self.fix_divs()  # fix required when using etree
     fake_file = StringIO()
     fake_file.write(DTD + '\n')
     self.add_charset()
     try:
         self.tree.write(fake_file)
     except Exception:
         return handle_exception()
     return fake_file.getvalue()
예제 #6
0
파일: vlam.py 프로젝트: wolverine2k/crunchy
 def read(self):  # tested
     '''create fake file from a tree, adding DTD and charset information
        and return its value as a string'''
     self.fix_divs()  # fix required when using etree
     fake_file = StringIO()
     fake_file.write(DTD + '\n')
     self.add_charset()
     try:
         self.tree.write(fake_file)
     except Exception:
         return handle_exception()
     return fake_file.getvalue()
예제 #7
0
    def run(self, code):
        """Make the analysis"""
        temp = tempfile.NamedTemporaryFile(suffix='.py')
        temp.write(code)
        temp.flush()

        output_buffer = StringIO()
        self.linter.reporter.set_output(output_buffer)
        self.linter.check(temp.name)
        self._report = output_buffer.getvalue().replace(temp.name, 'line ')

        output_buffer.close()
        temp.close()
예제 #8
0
    def run(self, code):
        """Make the analysis"""
        temp = tempfile.NamedTemporaryFile(suffix = '.py')
        temp.write(code)
        temp.flush()

        output_buffer = StringIO()
        self.linter.reporter.set_output(output_buffer)
        self.linter.check(temp.name)
        self._report = output_buffer.getvalue().replace(temp.name, 'line ')

        output_buffer.close()
        temp.close()
예제 #9
0
    def __init__(self, code, channel, symbols=None, doctest=False, username=None):
        threading.Thread.__init__(self)
        self.code = trim_empty_lines_from_end(code) + "\n"
        # the extra new line character at the end above prevents a syntax error
        # if the last line is a comment.
        self.channel = channel
        if username is not None:
            self.username = username
            self.friendly = config[self.username]["friendly"]
        else:
            try:
                pageid = self.channel.split("_")[0]
                self.username = names[pageid]
                self.friendly = config[self.username]["friendly"]
            except:
                self.friendly = False
                print("Exception raised in Interpreter.init(); channel = %s" % self.channel)
                try:
                    u_print("username = "******"username not defined...")
                    self.username = None
                try:
                    u_print("pageid in names: ", self.channel.split("_")[0] in names)
                except:
                    pass

        self.symbols = {}
        if symbols is not None:
            self.symbols.update(symbols)
        self.doctest = doctest
        if self.doctest:
            self.doctest_out = StringIO()
            self.symbols["doctest_out"] = self.doctest_out
예제 #10
0
def unicode_urlopen(url, accept_lang=None):
    """Returns a *Unicode* file-like object for non-local documents.
    Client must ensure that the URL points to non-binary data. Pass in
    an Accept-Language value to configure the FancyURLopener we
    use."""

    opener = FancyURLopener()

    if accept_lang:
        opener.addheader("Accept-Language", accept_lang)

    # We want to convert the bytes file-like object returned by
    # urllib, which is bytes in both Python 2 and Python 3
    # fortunately, and turn it into a Unicode file-like object
    # with a little help from our StringIO friend.
    page = opener.open(url)
    encoding = page.headers['content-type']
    encoding = encoding.split('charset=')
    if len(encoding) > 1:
        encoding = encoding[-1]
        page = page.read().decode(encoding)
    else:
        page = page.read()
        encoding = meta_encoding(page) or 'utf8'
        page = page.decode(encoding)

    page = StringIO(page)
    return page
예제 #11
0
    def run(self, code):
        """Make the analysis"""
        self._code = code
        # Save the code in a temporary file
        temp = tempfile.NamedTemporaryFile(suffix='.py')
        temp.write(self._code)
        temp.flush()
        fname = os.path.basename(temp.name)

        self._output_buffer = StringIO()
        checker._printWarnings = self._printWarnings
        checker.main(['dummy_arg', '--only', temp.name])
        # remove all traces of the Temporary file name
        self._report = self._output_buffer.getvalue().replace(
            temp.name, 'line')
        self._report = self._report.replace(fname[:-3] + ":", "")
        self._output_buffer.close()
        temp.close()
예제 #12
0
def run_sample(name):  # tested
    '''Given a setup script, as a precursor, executes a code sample
    and compares the output with some expected result.'''
    if name in code_setups:
        try:
            complete_code = code_setups[name] + '\n' + code_samples[name]
        except KeyError:
            sys.__stderr__.write("There was an error in run_sample().")
    else:
        try:
            complete_code = code_samples[name]
        except KeyError:
            sys.__stderr__.write("There was an error in run_sample.")
    # since Crunchy often redefines sys.stdout, we can't simply set
    # it back to sys.__stdout__ after redirection
    saved_stdout = sys.stdout
    redirected = StringIO()
    sys.stdout = redirected
    exec(complete_code)
    sys.stdout = saved_stdout
    return compare(expected_outputs[name], redirected.getvalue())
예제 #13
0
def run_sample(name):  # tested
    '''Given a setup script, as a precursor, executes a code sample
    and compares the output with some expected result.'''
    if name in code_setups:
        try:
            complete_code = code_setups[name] + '\n' + code_samples[name]
        except KeyError:
            sys.__stderr__.write("There was an error in run_sample().")
    else:
        try:
            complete_code = code_samples[name]
        except KeyError:
            sys.__stderr__.write("There was an error in run_sample.")
    # since Crunchy often redefines sys.stdout, we can't simply set
    # it back to sys.__stdout__ after redirection
    saved_stdout = sys.stdout
    redirected = StringIO()
    sys.stdout = redirected
    exec(complete_code)
    sys.stdout = saved_stdout
    return compare(expected_outputs[name], redirected.getvalue())
예제 #14
0
    def run(self, code):
        """Make the analysis

        This function is inspired from the check function of the pyflakes start
        script.
        """
        print("run called in pychecker")
        self._code = code
        # Open a buffer for the output
        output = StringIO()
        # Start the check
        try:
            tree = compiler.parse(self._code)
        except (SyntaxError, IndentationError):
            value = sys.exc_info()[1]
            try:
                (lineno, offset, line) = value[1][1:]
            except IndexError:
                print >> output, _('Could not compile the code.')
            else:
                if line.endswith("\n"):
                    line = line[:-1]
                print >> output, _('line %d: could not compile') % lineno
                print >> output, line
                print >> output, " " * (offset - 2), "^"
            self._nb_errors = None
        else:
            w = checker.Checker(tree, 'line')
            w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno))
            for warning in w.messages:
                print >> output, warning
            self._nb_errors = len(w.messages)

        # Get the output and remove the irrelevant file path
        self._report = output.getvalue()
        # Close the buffer
        output.close()
예제 #15
0
    def run(self, code):
        """Make the analysis

        This function is inspired from the check function of the pyflakes start
        script.
        """
        print("run called in pychecker")
        self._code = code
        # Open a buffer for the output
        output = StringIO()
        # Start the check
        try:
            tree = compiler.parse(self._code)
        except (SyntaxError, IndentationError):
            value = sys.exc_info()[1]
            try:
                (lineno, offset, line) = value[1][1:]
            except IndexError:
                print >> output, _('Could not compile the code.')
            else :
                if line.endswith("\n"):
                    line = line[:-1]
                print >> output, _('line %d: could not compile') % lineno
                print >> output, line
                print >> output, " " * (offset-2), "^"
            self._nb_errors = None
        else:
            w = checker.Checker(tree, 'line')
            w.messages.sort(lambda a, b: cmp(a.lineno, b.lineno))
            for warning in w.messages:
                print >> output, warning
            self._nb_errors = len(w.messages)

        # Get the output and remove the irrelevant file path
        self._report = output.getvalue()
        # Close the buffer
        output.close()
예제 #16
0
    def __init__(self, code, channel, symbols = None, doctest=False,
                 username=None):
        threading.Thread.__init__(self)
        self.code = trim_empty_lines_from_end(code) + "\n"
        # the extra new line character at the end above prevents a syntax error
        # if the last line is a comment.
        self.channel = channel
        if username is not None:
            self.username = username
            self.friendly = config[self.username]['friendly']
        else:
            try:
                pageid = self.channel.split("_")[0]
                self.username = names[pageid]
                self.friendly = config[self.username]['friendly']
            except:
                self.friendly = False
                print ("Exception raised in Interpreter.init(); channel = %s" %
                                                                    self.channel)
                try:
                    u_print("username = "******"username not defined...")
                    self.username = None
                try:
                    u_print("pageid in names: ", self.channel.split("_")[0] in names)
                except:
                    pass

        self.symbols = {}
        if symbols is not None:
            self.symbols.update(symbols)
        self.doctest = doctest
        if self.doctest:
            self.doctest_out = StringIO()
            self.symbols['doctest_out'] = self.doctest_out
예제 #17
0
    def run(self, code):
        """Make the analysis"""
        self._code = code
        # Save the code in a temporary file
        temp = tempfile.NamedTemporaryFile(suffix = '.py')
        temp.write(self._code)
        temp.flush()
        fname = os.path.basename(temp.name)

        self._output_buffer = StringIO()
        checker._printWarnings = self._printWarnings
        checker.main(['dummy_arg', '--only', temp.name])
        # remove all traces of the Temporary file name
        self._report = self._output_buffer.getvalue().replace(temp.name, 'line')
        self._report = self._report.replace(fname[:-3] + ":", "")
        self._output_buffer.close()
        temp.close()
예제 #18
0
파일: vlam_pdb.py 프로젝트: Mekyi/crunchy
 def __init__(self, old_out):
     self.old_out = old_out
     StringIO.__init__(self)
예제 #19
0
def simplify_traceback(code=None, username=None):
    ''' inspired by simplifytraceback from the code module in the
    standard library.
    The first stack item because it is our own code; it is removed in
    the standard traceback in the code module.
    '''
    try:
        ex_type, value, trace = sys.exc_info()
        sys.last_type = ex_type
        sys.last_traceback = trace
        sys.last_value = value
    except:
        return "Internal error: could not retrieve traceback information."
    try:
        lineno = trace.tb_next.tb_lineno
    except:
        lineno = trace.tb_lineno
    if ex_type is SyntaxError:
        return simplify_syntax_error(code, ex_type, value, trace, lineno,
                                     username)
    if ex_type is SystemExit:
        value = "Your program exited.\n"

    tblist = traceback.extract_tb(trace)
    del tblist[:1]
    tb_list = traceback.format_list(tblist)
    if tb_list:
        tb_list.insert(0, "Traceback (most recent call last):\n")
    tb_list[len(tb_list):] = traceback.format_exception_only(ex_type, value)

    saved_tb_list = []
    for line in tb_list:
        saved_tb_list.append(line)

    if username and config[username]['friendly']:
        try:
            if code is not None:
                code_line = code.split('\n')[lineno - 1]
            else:
                try:
                    dummy_filename, dummy_line_number, dummy_function_name, \
                                    code_line = traceback.extract_tb(trace)[2]
                except:
                    code_line = None
            del tb_list[0]
            tb_list[0] = tb_list[0].replace('  File "Crunchy console", line',
                                            _(u"Error on line"))
            tb_list[0] = tb_list[0].replace(' File "User\'s code", line',
                                            _(u"Error on line"))
            tb_list[0] = tb_list[0].replace(', in <module>', ':')
            if code_line is not None:
                tb_list.insert(1, ">>> " + code_line + "\n")
            for index, line in enumerate(tb_list):
                if ' File "Crunchy console", line' in line:
                    tb_list[index] = line.replace(
                        ' File "Crunchy console", line', _(u"called by line"))
                if ', in <module>' in line:
                    tb_list[index] = line.replace(', in <module>', '')
        except:
            tb_list = saved_tb_list

    retval = StringIO()
    map(retval.write, tb_list)
    if ex_type is SystemExit:
        out = retval.getvalue().replace("Your program exited.",
                                        _(u"Your program exited."))
        return out.encode("utf-8")

    if debug:
        if username:
            added_info = ("Crunchy debug::  In errors.simplify_traceback:\n"
                          "username = %s" % username + "friendly = " +
                          str(config[username]['friendly']))
        else:
            added_info = ("Crunchy debug::  "
                          "In errors.simplify_traceback: username=%s\n" %
                          username)
    else:
        added_info = ''
    return retval.getvalue().encode("utf-8") + added_info
예제 #20
0
class Interpreter(KillableThread):
    """
    Run python source asynchronously
    """
    def __init__(self, code, channel, symbols = None, doctest=False,
                 username=None):
        threading.Thread.__init__(self)
        self.code = trim_empty_lines_from_end(code) + "\n"
        # the extra new line character at the end above prevents a syntax error
        # if the last line is a comment.
        self.channel = channel
        if username is not None:
            self.username = username
            self.friendly = config[self.username]['friendly']
        else:
            try:
                pageid = self.channel.split("_")[0]
                self.username = names[pageid]
                self.friendly = config[self.username]['friendly']
            except:
                self.friendly = False
                print ("Exception raised in Interpreter.init(); channel = %s" %
                                                                    self.channel)
                try:
                    u_print("username = "******"username not defined...")
                    self.username = None
                try:
                    u_print("pageid in names: ", self.channel.split("_")[0] in names)
                except:
                    pass

        self.symbols = {}
        if symbols is not None:
            self.symbols.update(symbols)
        self.doctest = doctest
        if self.doctest:
            self.doctest_out = StringIO()
            self.symbols['doctest_out'] = self.doctest_out

    def run(self):
        """run the code, redirecting stdout, stderr, stdin and
           returning the string representing the output
        """
        sys.stdin.register_thread(self.channel)
        sys.stdout.register_thread(self.channel)
        sys.stderr.register_thread(self.channel)
        try:
            try:
                self.ccode = compile(self.code, "User's code", 'exec')
            except:
                try:
                    if self.friendly:
                        sys.stderr.write(errors.simplify_traceback(self.code, self.username))
                    else:
                        traceback.print_exc()
                    return
                except:
                    sys.stderr.write("Recovering from internal error in Interpreter.run()")
                    sys.stderr.write("self.channel =%s"%self.channel)
                    return
            if not self.ccode:    #code does nothing
                return
            try:
                # logging the user input first, if required
                if self.username and self.channel in config[self.username]['logging_uids']:
                    vlam_type = config[self.username]['logging_uids'][self.channel][1]
                    if vlam_type == 'editor':
                        user_code = self.code.split("\n")
                        log_id = config[self.username]['logging_uids'][self.channel][0]
                        if user_code:
                            user_code = '\n'.join(user_code)
                            if not user_code.endswith('\n'):
                                user_code += '\n'
                        else:
                            user_code = _("# no code entered by user\n")
                        data = "<span class='stdin'>" + user_code + "</span>"
                        config[self.username]['log'][log_id].append(data)
                        log_session(username)
                exec_code(self.ccode, self.symbols, source=None,
                          username=self.username)
                #exec self.ccode in self.symbols#, {}
                # note: previously, the "local" directory used for exec
                # was simply an empty directory.  However, this meant that
                # module names imported outside a function definition
                # were not available inside that function.  This is why
                # we have commented out the {} as a reminder; self.symbols
                # will be used for holding both global and local variables.
            except:
                try:
                    if self.friendly:
                        sys.stderr.write(errors.simplify_traceback(self.code, self.username))
                    else:
                        traceback.print_exc()
                except:
                    sys.stderr.write("Recovering from internal error in Interpreter.run()")
                    sys.stderr.write(".. after trying to call exec_code.")
                    sys.stderr.write("self.channel = %s"%self.channel)
        finally:
            if self.doctest:
                # attempting to log
                if self.username and self.channel in config[self.username]['logging_uids']:
                    code_lines = self.code.split("\n")
                    user_code = []
                    for line in code_lines:
                        # __teststring identifies the beginning of the code
                        # that is passed to a doctest (see vlam_doctest.py)
                        # This will have been appended to the user's code.
                        if line.startswith("__teststring"):
                            break
                        user_code.append(line)
                    log_id = config[self.username]['logging_uids'][self.channel][0]
                    if user_code:
                        user_code = '\n' + '\n'.join(user_code)
                        if not user_code.endswith('\n'):
                            user_code += '\n'
                    else:
                        user_code = _("# no code entered by user\n")
                    # separating each attempts
                    user_code = "\n" + "- "*25 + "\n" + user_code

                    data = "<span class='stdin'>" + user_code + "</span>"
                    config[self.username]['log'][log_id].append(data)
                    log_session(self.username)
                # proceed with regular output
                if self.friendly:
                    message, success = errors.simplify_doctest_error_message(
                           self.doctest_out.getvalue())
                    if success:
                        sys.stdout.write(message)
                    else:
                        sys.stderr.write(message)
                else:
                    sys.stdout.write(self.doctest_out.getvalue())
            sys.stdin.unregister_thread()
            sys.stdout.unregister_thread()
            sys.stderr.unregister_thread()
예제 #21
0
 def __init__(self, old_out):
     self.old_out = old_out
     StringIO.__init__(self)
예제 #22
0
 def do_output_off(self, arg=None):
     '''do command and capture the output'''
     self.old_stdout = self.stdout
     self.stdout = StringIO()
예제 #23
0
class Interpreter(KillableThread):
    """
    Run python source asynchronously
    """

    def __init__(self, code, channel, symbols=None, doctest=False, username=None):
        threading.Thread.__init__(self)
        self.code = trim_empty_lines_from_end(code) + "\n"
        # the extra new line character at the end above prevents a syntax error
        # if the last line is a comment.
        self.channel = channel
        if username is not None:
            self.username = username
            self.friendly = config[self.username]["friendly"]
        else:
            try:
                pageid = self.channel.split("_")[0]
                self.username = names[pageid]
                self.friendly = config[self.username]["friendly"]
            except:
                self.friendly = False
                print("Exception raised in Interpreter.init(); channel = %s" % self.channel)
                try:
                    u_print("username = "******"username not defined...")
                    self.username = None
                try:
                    u_print("pageid in names: ", self.channel.split("_")[0] in names)
                except:
                    pass

        self.symbols = {}
        if symbols is not None:
            self.symbols.update(symbols)
        self.doctest = doctest
        if self.doctest:
            self.doctest_out = StringIO()
            self.symbols["doctest_out"] = self.doctest_out

    def run(self):
        """run the code, redirecting stdout, stderr, stdin and
           returning the string representing the output
        """
        sys.stdin.register_thread(self.channel)
        sys.stdout.register_thread(self.channel)
        sys.stderr.register_thread(self.channel)
        try:
            try:
                self.ccode = compile(self.code, "User's code", "exec")
            except:
                try:
                    if self.friendly:
                        sys.stderr.write(errors.simplify_traceback(self.code, self.username))
                    else:
                        traceback.print_exc()
                    return
                except:
                    sys.stderr.write("Recovering from internal error in Interpreter.run()")
                    sys.stderr.write("self.channel =%s" % self.channel)
                    return
            if not self.ccode:  # code does nothing
                return
            try:
                # logging the user input first, if required
                if self.username and self.channel in config[self.username]["logging_uids"]:
                    vlam_type = config[self.username]["logging_uids"][self.channel][1]
                    if vlam_type == "editor":
                        user_code = self.code.split("\n")
                        log_id = config[self.username]["logging_uids"][self.channel][0]
                        if user_code:
                            user_code = "\n".join(user_code)
                            if not user_code.endswith("\n"):
                                user_code += "\n"
                        else:
                            user_code = _("# no code entered by user\n")
                        data = "<span class='stdin'>" + user_code + "</span>"
                        config[self.username]["log"][log_id].append(data)
                        log_session(username)
                exec_code(self.ccode, self.symbols, source=None, username=self.username)
                # exec self.ccode in self.symbols#, {}
                # note: previously, the "local" directory used for exec
                # was simply an empty directory.  However, this meant that
                # module names imported outside a function definition
                # were not available inside that function.  This is why
                # we have commented out the {} as a reminder; self.symbols
                # will be used for holding both global and local variables.
            except:
                try:
                    if self.friendly:
                        sys.stderr.write(errors.simplify_traceback(self.code, self.username))
                    else:
                        traceback.print_exc()
                except:
                    sys.stderr.write("Recovering from internal error in Interpreter.run()")
                    sys.stderr.write(".. after trying to call exec_code.")
                    sys.stderr.write("self.channel = %s" % self.channel)
        finally:
            if self.doctest:
                # attempting to log
                if self.username and self.channel in config[self.username]["logging_uids"]:
                    code_lines = self.code.split("\n")
                    user_code = []
                    for line in code_lines:
                        # __teststring identifies the beginning of the code
                        # that is passed to a doctest (see vlam_doctest.py)
                        # This will have been appended to the user's code.
                        if line.startswith("__teststring"):
                            break
                        user_code.append(line)
                    log_id = config[self.username]["logging_uids"][self.channel][0]
                    if user_code:
                        user_code = "\n" + "\n".join(user_code)
                        if not user_code.endswith("\n"):
                            user_code += "\n"
                    else:
                        user_code = _("# no code entered by user\n")
                    # separating each attempts
                    user_code = "\n" + "- " * 25 + "\n" + user_code

                    data = "<span class='stdin'>" + user_code + "</span>"
                    config[self.username]["log"][log_id].append(data)
                    log_session(self.username)
                # proceed with regular output
                if self.friendly:
                    message, success = errors.simplify_doctest_error_message(self.doctest_out.getvalue())
                    if success:
                        sys.stdout.write(message)
                    else:
                        sys.stderr.write(message)
                else:
                    sys.stdout.write(self.doctest_out.getvalue())
            sys.stdin.unregister_thread()
            sys.stdout.unregister_thread()
            sys.stderr.unregister_thread()
예제 #24
0
파일: errors_3k.py 프로젝트: Mekyi/crunchy
def simplify_traceback(code=None, username=None):
    ''' inspired by simplifytraceback from the code module in the
    standard library.
    The first stack item because it is our own code; it is removed in
    the standard traceback in the code module.
    '''
    try:
        ex_type, value, trace = sys.exc_info()
        sys.last_type = ex_type
        sys.last_traceback = trace
        sys.last_value = value
    except:
        return "Internal error: could not retrieve traceback information."
    try:
        lineno = trace.tb_next.tb_lineno
    except:
        lineno = trace.tb_lineno
    if ex_type is SyntaxError:
        return simplify_syntax_error(code, ex_type, value, trace, lineno, username)
    if ex_type is SystemExit:
        value = "Your program exited.\n"

    tblist = traceback.extract_tb(trace)
    del tblist[:1]
    tb_list = traceback.format_list(tblist)
    if tb_list:
        tb_list.insert(0, "Traceback (most recent call last):\n")
    tb_list[len(tb_list):] = traceback.format_exception_only(ex_type, value)

    saved_tb_list = []
    for line in tb_list:
        saved_tb_list.append(line)

    if username and config[username]['friendly']:
        try:
            if code is not None:
                code_line = code.split('\n')[lineno - 1]
            else:
                try:
                    dummy_filename, dummy_line_number, dummy_function_name, \
                                    code_line = traceback.extract_tb(trace)[2]
                except:
                    code_line = None
            del tb_list[0]
            tb_list[0] = tb_list[0].replace('  File "Crunchy console", line',
                                   _("Error on line"))
            tb_list[0] = tb_list[0].replace(' File "User\'s code", line',
                                   _("Error on line"))
            tb_list[0] = tb_list[0].replace(', in <module>', ':')
            if code_line is not None:
                tb_list.insert(1, ">>> " + code_line + "\n")
            for index, line in enumerate(tb_list):
                if ' File "Crunchy console", line' in line:
                    tb_list[index] = line.replace(' File "Crunchy console", line',
                                        _("called by line"))
                if ', in <module>' in line:
                    tb_list[index] = line.replace(', in <module>', '')
        except:
            tb_list = saved_tb_list

    retval = StringIO()
    list(map(retval.write, tb_list))
    if ex_type is SystemExit:
        out = retval.getvalue().replace("Your program exited.",
                             _("Your program exited.") )
        return out

    if debug:
        if username:
            added_info = ("Crunchy debug::  In errors.simplify_traceback:\n"
                          "username = %s"%username + "friendly = " +
                                            str(config[username]['friendly']))
        else:
            added_info = ("Crunchy debug::  "
                          "In errors.simplify_traceback: username=%s\n"%username)
    else:
        added_info = ''
    return retval.getvalue() + added_info