def start_console(): """Starts a Friendly console with a custom formatter for IDLE""" import friendly_traceback # noqa sys.stderr = sys.stdout.shell # noqa friendly_traceback.set_formatter(idle_formatter) friendly_traceback.set_stream(idle_writer) friendly_traceback.start_console()
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)
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)
def run(filename, lang=None, include="friendly_tb", args=None, console=True): """This function executes the code found in a python file. ``filename`` should be either an absolute path or, it should be the name of a file (filename.py) found in the same directory as the file from which ``run()`` is called. If friendly_console is set to ``False`` (the default) and the Python version is greater or equal to 3.10, ``run()`` returns an empty dict if a ``SyntaxError`` was raised, otherwise returns the dict in which the module (``filename``) was executed. If console is set to ``True`` (the default), the execution continues as an interactive session in a Friendly console, with the module dict being used as the locals dict. Other arguments include: ``lang``: language used; currently only ``en`` (default) and ``fr`` are available. ``include``: specifies what information is to be included if an exception is raised. ``args``: strings tuple that is passed to the program as though it was run on the command line as follows:: python filename.py arg1 arg2 ... """ import friendly_traceback _ = current_lang.translate sys.stderr = sys.stdout.shell # noqa friendly_traceback.set_formatter(idle_formatter) friendly_traceback.set_stream(idle_writer) filename = Path(filename) if not filename.is_absolute(): frame = inspect.stack()[1] # This is the file from which run() is called run_filename = Path(frame[0].f_code.co_filename) run_dir = run_filename.parent.absolute() filename = run_dir.joinpath(filename) if not filename.exists(): print( _("The file {filename} does not exist.").format(filename=filename)) return if not console: if sys.version_info >= (3, 10): install_in_idle_shell() elif sys.version_info < (3, 10): sys.stderr.write( "Friendly-traceback cannot be installed in this version of IDLE.\n" ) return friendly_traceback.run(filename, lang=lang, include=include, args=args, console=console)
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)