def test_no_false_positive():
    # The following tests use valid syntax.
    # They should never have raised a Syntax error, and thus
    # we should not be able to find a likely cause of a problem.
    set_lang("en")
    no_cause = "I cannot guess the likely cause of this error"

    assert no_cause in find(["def test(arg1, arg2):"])
    assert no_cause in find(["def test(arg1, arg2=None):"])
    assert no_cause in find(["def test(arg1=(None, 1)):"])
    assert no_cause in find(["def test(arg1=(1, None)):"])
    assert no_cause in find(["def test(arg1=[1, None]):"])
    assert no_cause in find(["def test(arg1={1, None}):"])
    # assert no_cause in find(multiline_def.split("\n"))

    assert no_cause in find(["for i in range(3):"])
    assert no_cause in find(["while True:"])
    assert no_cause in find(["pass"])
    assert no_cause in find(["else:"])

    walrus_test = ["a := 1"]
    if sys.version_info >= (3, 8):
        assert no_cause in find(walrus_test, offset=3)
    else:
        assert "walrus operator" in find(walrus_test, offset=3)
Beispiel #2
0
def test_run_error_fr():
    friendly_traceback.run(
        "tests/name_error.py",
        lang="fr",
        include="why",  # more restricted than the English test
        console=False,
        redirect="capture",
    )
    result = friendly_traceback.get_output()
    friendly_traceback.set_lang('en')
    friendly_traceback.uninstall()
    assert "Le nom semblable `pi` a été trouvé dans la portée locale." in result
Beispiel #3
0
def what(exception=None, lang="en", pre=False):
    """If known, shows the generic explanation about a given exception."""

    if exception is not None:
        if hasattr(exception, "__name__"):
            exception = exception.__name__
        if lang is not None:
            old_lang = friendly_traceback.get_lang()
            friendly_traceback.set_lang(lang)
        result = info_generic.get_generic_explanation(exception)
        if lang is not None:
            friendly_traceback.set_lang(old_lang)
        if pre:  # for documentation
            lines = result.split("\n")
            for line in lines:
                session.write_err("    " + line + "\n")
            session.write_err("\n")
        else:
            session.write_err(result)
        return

    explain("what")
Beispiel #4
0
    def set_lang(self, lang):
        """Sets the current language.

           Raises an exception if the language is unknown.

           If current dialect is set to None, an attempt will be made
           to set dialect to the value corresponding to language.
        """
        if not self.is_lang(lang):
            raise exceptions.UnknownLanguageError(
                "Unknown language %s" % lang, (lang, self.languages)
            )
        else:
            self.current_lang = lang
            self.install_gettext(lang)
            if self.current_dialect is None:
                try:
                    self.set_dialect("py" + lang)
                except exceptions.UnknownDialectError:
                    pass
            elif self.console_active:
                self.print_lang_info()
            friendly_traceback.set_lang(lang)
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)
   by Python and its corresponding linenumber. [The offset is ignored.]

2. Next, it will try to look at the content of the line flagged by Python as
   the last line it could analyze, going through a series of individual
   tests.  Here, only the last line of code is passed, which is broken
   down into a series of tokens prior to be sent to individual analyzers.
   [The message, linenumber and offset arguments are not used.]

3. Finally, it will look at the entire content, mostly focusing on checking
   if (), [], and {}, are properly matched and closed. In doing so, it might
   identify other errors along the way.
"""
import sys
from friendly_traceback import analyze_syntax, set_lang

set_lang("en")


def find(lines=[" "], linenumber=1, message="invalid syntax", offset=1):
    return analyze_syntax._find_likely_cause(
        source_lines=lines, linenumber=linenumber, message=message, offset=offset
    )


def test_no_false_positive():
    # The following tests use valid syntax.
    # They should never have raised a Syntax error, and thus
    # we should not be able to find a likely cause of a problem.
    no_cause = "I cannot guess the likely cause of this error"

    assert no_cause in find(["def test(arg1, arg2):"])
Beispiel #7
0
import sys
import platform
import friendly_traceback


# Make it possible to find docs and tests source
this_dir = os.path.dirname(__file__)
docs_root_dir = os.path.abspath(
    os.path.join(this_dir, "..", "..", "friendly-traceback-docs")
)
assert os.path.isdir(docs_root_dir), "Separate docs repo need to exist"
# sys.path.insert(0, root_dir)

LANG = "en"
friendly_traceback.install()
friendly_traceback.set_lang(LANG)

sys.path.insert(0, this_dir)
py_version = f"{sys.version_info.major}.{sys.version_info.minor}"

import trb_syntax_common

target = os.path.normpath(
    os.path.join(docs_root_dir, f"docs/source/syntax_tracebacks_{LANG}_{py_version}.rst")
)

intro_text = """
Friendly SyntaxError tracebacks - in English
=============================================

Friendly-traceback aims to provide friendlier feedback when an exception
Beispiel #8
0
 def change_lang(self, event=None):
     """Keeping all the translations in sync"""
     lang = self.lang.get()
     friendly_traceback.set_lang(lang)
     demo_lang.install(lang)
     self.set_ui_lang()
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)
import sys

import pytest

import friendly_traceback

friendly_traceback.set_lang("en")

# Format of the dict below
# filename : "partial content of the Friendly traceback information"

causes = {
    "raise_indentation_error1":
    "expected to begin a new indented block",
    "raise_indentation_error2":
    "does not match the indentation of the previous line",
    "raise_indentation_error3":
    "not aligned vertically with another block of code",
    "raise_tab_error":
    "A `TabError` indicates that you have used",
    "raise_syntax_error1":
    "assign a value to the Python keyword `def`",
    "raise_syntax_error2":
    "`if` but forgot to add a colon `:`",
    "raise_syntax_error3":
    "wrote a `while` loop but",
    "raise_syntax_error4":
    "wrote `else if` instead",
    "raise_syntax_error5":
    "wrote `elseif` instead",
    "raise_syntax_error6":
import sys
import traceback

from core import translation as t

for attr in "type value traceback".split():
    sys.__dict__.pop("last_" + attr, None)

from friendly_traceback.core import FriendlyTraceback
import friendly_traceback

friendly_traceback.set_lang(t.current_language or "en")


def friendly_syntax_error(e, filename):
    lines = iter(traceback.format_exception(type(e), e, e.__traceback__))
    for line in lines:
        if line.strip().startswith(f'File "{filename}"'):
            break
    return f"""\
{''.join(lines).rstrip()}
{t.Terms.syntax_error_at_line} {e.lineno}

{friendly_message(e, double_newline=False)}

"""


def friendly_message(e, double_newline: bool):
    try:
        fr = FriendlyTraceback(type(e), e, e.__traceback__)