Ejemplo n.º 1
0
def test_run_code():
    # set-up
    bad_code_syntax = "True = 1"
    bad_code_exec = "a = b"  # Not a syntax error, but a NameError
    good_code = "c = 1"

    friendly.set_stream("capture")
    original_level = friendly.get_level()
    installed = friendly.is_installed()
    # ----- end of set-up

    # When a SyntaxError is raised, run_code returns False

    assert not friendly.run_code(source=bad_code_syntax)
    result = friendly.get_output()  # content is flushed
    assert "Python exception" in result
    assert "SyntaxError" in result

    assert not friendly.get_output()  # confirm that content was flushed

    assert not friendly.run_code(source=bad_code_exec)
    result = friendly.get_output()
    assert "Python exception" in result
    assert "NameError" in result

    assert friendly.run_code(source=good_code)
    assert not friendly.get_output()  # no new exceptions recorded

    try:
        exec(bad_code_syntax, {})
    except Exception:
        assert not friendly.get_output()

    # When friendly-traceback is not installed, a call to run_code
    # will end with level set to 0, which corresponds to normal Python
    # tracebacks
    friendly.uninstall()
    friendly.run_code(source=bad_code_syntax)
    assert friendly.get_level() == 0
    friendly.run_code(source=bad_code_syntax, level=4)
    assert friendly.get_level() == 0

    # When friendly-traceback is "installed", a call to run_code
    # leaves its level unchanged.
    friendly.install()

    friendly.set_level(3)
    friendly.run_code(source=bad_code_syntax)
    assert friendly.get_level() == 3
    friendly.run_code(source=bad_code_syntax, level=4)
    assert friendly.get_level() == 3

    # Clean up and restore for other tests
    friendly.get_output()
    friendly.set_stream(None)
    if installed:
        friendly.uninstall()
    friendly.set_level(original_level)
Ejemplo n.º 2
0
def test_uncleaned_traceback():
    """Assert this test filename appear in tracebacks if we don't exclude
    it.
    """
    friendly.install(redirect="capture")

    try:
        raise ValueError
    except ValueError:
        friendly.explain()

    output = friendly.get_output()
    assert "test_clean_traceback" in output

    # cleanup for other tests
    friendly.uninstall()
Ejemplo n.º 3
0
def start_console(
    local_vars=None,
    use_rich=False,
    include="friendly_tb",
    lang="en",
    banner=None,
    theme="dark",
):
    """Starts a console; modified from code.interact"""
    from . import config

    if banner is None:
        banner = BANNER
    if theme != "light":
        theme = "dark"
    if use_rich:
        config.session.set_formatter("rich", theme=theme)

    console_defaults = {
        "explain": explain,
        "what": what,
        "where": where,
        "why": why,
        "more": more,
        "get_lang": friendly_traceback.get_lang,
        "set_lang": friendly_traceback.set_lang,
        "get_include": friendly_traceback.get_include,
        "set_include": friendly_traceback.set_include,
        "hint": hint,
        "friendly_tb": friendly_tb,
        "python_tb": python_tb,
        "debug_tb": debug_tb,
        "debug": debug,
        "show_paths": path_utils.show_paths,
        "_info": _info,
    }
    if not friendly_traceback.is_installed():
        friendly_traceback.install(include=include, lang=lang)
    if local_vars is None:
        local_vars = console_defaults
    else:
        local_vars.update(console_defaults)

    console = FriendlyConsole(locals=local_vars,
                              use_rich=use_rich,
                              theme=theme)
    console.interact(banner=banner)
Ejemplo n.º 4
0
def test_cleaned_traceback():
    """Assert this test filename does not appear in tracebacks if we
    exclude it.
    """
    friendly.install(redirect="capture")
    friendly.exclude_file_from_traceback(__file__)

    try:
        raise ValueError
    except ValueError:
        friendly.explain()

    output = friendly.get_output()
    assert "test_clean_traceback" not in output

    # cleanup for other tests
    friendly.include_file_in_traceback(__file__)
    friendly.uninstall()
Ejemplo n.º 5
0
def start_console(local_vars=None,
                  use_rich=False,
                  include="friendly_tb",
                  lang="en",
                  banner=None):
    """Starts a console; modified from code.interact"""
    # from . import config

    if banner is None:
        banner = BANNER

    if not friendly_traceback.is_installed():
        friendly_traceback.install(include=include, lang=lang)

    source_cache.idle_get_lines = None

    if local_vars is not None:
        # Make sure we don't overwrite with our own functions
        helpers.update(local_vars)

    console = FriendlyConsole(locals=helpers, use_rich=use_rich)
    console.interact(banner=banner)
Ejemplo n.º 6
0
def install_in_idle_shell():
    """Installs Friendly-traceback in IDLE's shell so that it can retrieve
    code entered in IDLE's repl.
    Note that this requires Python version 3.10+ since IDLE did not support
    custom excepthook in previous versions of Python.

    Furthermore, Friendly-traceback is bypassed when code entered in IDLE's repl
    raises SyntaxErrors.
    """
    import friendly_traceback

    friendly_traceback.exclude_file_from_traceback(idlelib_run.__file__)
    rpchandler = rpc.objecttable["exec"].rpchandler  # noqa

    def get_lines(filename, linenumber):
        lines = rpchandler.remotecall("linecache", "getlines",
                                      (filename, None), {})
        new_lines = []
        for line in lines:
            if not line.endswith("\n"):
                line += "\n"
            if filename.startswith("<pyshell#") and line.startswith("\t"):
                # Remove extra indentation added in the shell (\t == 8 spaces)
                line = "    " + line[1:]
            new_lines.append(line)
        if linenumber is None:
            return new_lines
        return new_lines[linenumber - 1:linenumber]

    source_cache.idle_get_lines = get_lines

    friendly_traceback.install(include="friendly_tb", redirect=idle_writer)
    # Current limitation
    idle_writer("                                WARNING\n", "ERROR")  # noqa
    idle_writer(
        "Friendly-traceback cannot handle SyntaxErrors for code entered in the shell.\n"
    )
def test_check_syntax():
    # set-up
    bad_code_syntax = "True = 1"
    bad_code_exec = "a = b"  # Not a syntax error, but a NameError
    good_code = "c = 1"

    friendly.set_stream("capture")
    original_verbosity = friendly.get_verbosity()
    installed = friendly.is_installed()
    # ----- end of set-up

    # When a SyntaxError is raised, check_syntax returns False

    assert not friendly.advanced_check_syntax(source=bad_code_syntax)
    result = friendly.get_output()  # content is flushed
    assert "Python exception" in result
    assert "SyntaxError" in result

    assert not friendly.get_output()  # confirm that content was flushed

    # When no SyntaxError is raised, check_syntax returns a tuple
    # containing a code object and a file name
    assert friendly.advanced_check_syntax(source=bad_code_exec)
    assert friendly.advanced_check_syntax(source=good_code)
    assert not friendly.get_output()  # no new exceptions recorded

    try:
        exec(bad_code_syntax, {})
    except Exception:
        assert not friendly.get_output()

    # When friendly-traceback is not installed, a call to check_syntax
    # will end with verbosity set to 0, which corresponds to normal Python
    # tracebacks
    friendly.uninstall()
    friendly.advanced_check_syntax(source=bad_code_syntax)
    assert friendly.get_verbosity() == 0
    friendly.advanced_check_syntax(source=bad_code_syntax, verbosity=4)
    assert friendly.get_verbosity() == 0

    # When friendly-traceback is "installed", a call to check_syntax
    # leaves its verbosity unchanged.
    friendly.install(redirect="capture")

    friendly.set_verbosity(3)
    friendly.advanced_check_syntax(source=bad_code_syntax)
    assert friendly.get_verbosity() == 3
    friendly.advanced_check_syntax(source=bad_code_syntax, verbosity=4)
    assert friendly.get_verbosity() == 3

    # A call to advanced_code_syntax, with a language specified as an argument
    # should leave the previous language unchanged.

    friendly.set_lang("en")
    assert not friendly.advanced_check_syntax(source=bad_code_syntax, lang="fr")
    result = friendly.get_output()
    assert "Exception Python" in result  # French heading
    assert friendly.get_lang() == "en"

    # Clean up and restore for other tests
    friendly.get_output()
    friendly.set_stream(None)
    if installed:
        friendly.uninstall()
    friendly.set_verbosity(original_verbosity)
Ejemplo n.º 8
0
"""Contains a function that should raise NameError"""
# flake8: noqa


def test():
    """Should raise NameError"""
    a = 1
    b = c
    d = 3


if __name__ == "__main__":
    import friendly_traceback
    friendly_traceback.install()
    test()
Ejemplo n.º 9
0
try:
    from IPython.core import interactiveshell as shell
    from IPython.core import compilerop
except ImportError:
    raise ValueError("IPython cannot be imported.")

from friendly_traceback import (
    install,
    exclude_file_from_traceback,
    explain_traceback,
    set_formatter,
)
from friendly_traceback.console_helpers import *  # noqa
from friendly_traceback.console_helpers import helpers  # noqa

__all__ = list(helpers.keys())
__all__.append("set_formatter")

shell.InteractiveShell.showtraceback = lambda self, *args, **kwargs: explain_traceback(
)
shell.InteractiveShell.showsyntaxerror = (
    lambda self, *args, **kwargs: explain_traceback())

exclude_file_from_traceback(shell.__file__)
exclude_file_from_traceback(compilerop.__file__)
install(include="friendly_tb")

set_formatter("repl")
print("Friendly-traceback installed.")
"""custom_exception_demo.py


   This simulates a user program that triggers various exceptions caught
   by Friendly-traceback; some of the exceptions are custom exceptions
   and one (NameError) is a standard Python exception
"""
import friendly_traceback
import custom_exception

friendly_traceback.install()  # sets up excepthook; used in the very last case


def next_exception(text):
    print("\n\n", "=" * 50)
    input(text)
    print("-" * 50, "\n")


next_exception("Press enter to see the firstexception")
try:
    raise custom_exception.MyException1("A message")  # noqa
except Exception:
    friendly_traceback.explain()

next_exception("Press enter for second exception")
try:
    raise custom_exception.MyException2("Something went wrong",
                                        (1, 2, 3))  # noqa
except Exception:
    friendly_traceback.explain()
def test_exec_code():
    # set-up
    bad_code_syntax = "True = 1"
    bad_code_exec = "a = b"  # Not a syntax error, but a NameError
    good_code = "c = 1"

    friendly.set_stream("capture")
    original_include = friendly.get_include()
    installed = friendly.is_installed()
    # ----- end of set-up

    # When a SyntaxError is raised, exec_code returns False

    assert not friendly.editors_helper.exec_code(source=bad_code_syntax)
    result = friendly.get_output()  # content is flushed
    assert "SyntaxError" in result

    assert not friendly.get_output()  # confirm that content was flushed

    friendly.editors_helper.exec_code(source=bad_code_exec)
    result = friendly.get_output()
    assert "NameError" in result

    assert friendly.editors_helper.exec_code(source=good_code)
    assert not friendly.get_output()  # no new exceptions recorded

    try:
        exec(bad_code_syntax, {})
    except Exception:
        assert not friendly.get_output()

    # Ensure that a call to exec_code only install() temporarily
    # if it was not installed before.
    friendly.uninstall()
    friendly.editors_helper.exec_code(source=bad_code_syntax)
    assert not friendly.is_installed()
    friendly.editors_helper.exec_code(source=bad_code_syntax, include="no_tb")
    assert not friendly.is_installed()

    # When friendly-traceback is "installed", a call to exec_code
    # leaves its include unchanged.
    friendly.install(redirect="capture")

    friendly.set_include("friendly_tb")
    friendly.editors_helper.exec_code(source=bad_code_syntax)
    assert friendly.get_include() == "friendly_tb"
    friendly.editors_helper.exec_code(source=bad_code_syntax, include="no_tb")
    assert friendly.get_include() == "friendly_tb"

    # A call to exec_code, with a language specified as an argument
    # should leave the previous language unchanged.

    friendly.set_lang("en")
    friendly.editors_helper.exec_code(source=bad_code_exec, lang="fr", include="explain")
    result = friendly.get_output()
    assert "Une exception `NameError` indique" in result
    assert friendly.get_lang() == "en"

    # Clean up and restore for other tests
    friendly.get_output()
    friendly.set_stream(None)
    if installed:
        friendly.uninstall()
    friendly.set_include(original_include)