def query(request): from mathics.core.parser import MultiLineFeeder input = request.POST.get('query', '') if settings.DEBUG and not input: input = request.GET.get('query', '') if settings.LOG_QUERIES: query_log = Query(query=input, error=True, browser=request.META.get('HTTP_USER_AGENT', ''), remote_user=request.META.get('REMOTE_USER', ''), remote_addr=request.META.get('REMOTE_ADDR', ''), remote_host=request.META.get('REMOTE_HOST', ''), meta=six.text_type(request.META), log='', ) query_log.save() user_definitions = request.session.get('definitions') definitions.set_user_definitions(user_definitions) evaluation = Evaluation(definitions, format='xml', output=WebOutput()) feeder = MultiLineFeeder(input, '<notebook>') results = [] try: while not feeder.empty(): expr = evaluation.parse_feeder(feeder) if expr is None: results.append(Result(evaluation.out, None, None)) # syntax errors evaluation.out = [] continue result = evaluation.evaluate(expr, timeout=settings.TIMEOUT) if result is not None: results.append(result) except Exception as exc: if settings.DEBUG and settings.DISPLAY_EXCEPTIONS: info = traceback.format_exception(*sys.exc_info()) info = '\n'.join(info) msg = 'Exception raised: %s\n\n%s' % (exc, info) results.append(Result([Message('System', 'exception', msg)], None, None)) else: raise result = { 'results': [result.get_data() for result in results], } request.session['definitions'] = definitions.get_user_definitions() if settings.LOG_QUERIES: query_log.timeout = evaluation.timeout query_log.result = six.text_type(result) # evaluation.results query_log.error = False query_log.save() return JsonResponse(result)
def test_case(test, tests, index=0, quiet=False): test, wanted_out, wanted = test.test, test.outs, test.result part, chapter, section = tests.part, tests.chapter, tests.section def fail(why): print("%sTest failed: %s in %s / %s\n%s\n%s\n" % ( sep, section, part, chapter, test, why)) return False if not quiet: print('%4d. TEST %s' % (index, test)) feeder = SingleLineFeeder(test, '<test>') evaluation = Evaluation(definitions, catch_interrupt=False, output=TestOutput()) try: query = evaluation.parse_feeder(feeder) if query is None: # parsed expression is None result = None out = evaluation.out else: result = evaluation.evaluate(query) out = result.out result = result.result except Exception as exc: fail("Exception %s" % exc) info = sys.exc_info() sys.excepthook(*info) return False if not compare(result, wanted): fail_msg = "Result: %s\nWanted: %s" % (result, wanted) if out: fail_msg += "\nAdditional output:\n" fail_msg += '\n'.join(six.text_type(o) for o in out) return fail(fail_msg) output_ok = True if len(out) != len(wanted_out): output_ok = False else: for got, wanted in zip(out, wanted_out): if not got == wanted: output_ok = False break if not output_ok: return fail("Output:\n%s\nWanted:\n%s" % ( '\n'.join(six.text_type(o) for o in out), '\n'.join(six.text_type(o) for o in wanted_out))) return True
def mathics_shell(shell): while True: try: evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) query = evaluation.parse_feeder(shell) if query is None: continue result = evaluation.evaluate(query, timeout=settings.TIMEOUT) if result is not None: shell.print_result(result) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): break finally: shell.reset_lineno()
def main() -> int: """ Command-line entry. Return exit code we want to give status of """ exit_rc = 0 argparser = argparse.ArgumentParser( prog="mathics", usage="%(prog)s [options] [FILE]", add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""", ) argparser.add_argument( "FILE", nargs="?", type=argparse.FileType("r"), help="execute commands from FILE", ) argparser.add_argument( "--help", "-h", help="show this help message and exit", action="help" ) argparser.add_argument( "--full-form", "-F", help="Show how input was parsed to FullForm", action="store_true", ) argparser.add_argument( "--pyextensions", "-l", action="append", metavar="PYEXT", help="directory to load extensions in python", ) argparser.add_argument( "--persist", help="go to interactive shell after evaluating FILE or -e", action="store_true", ) # --initfile is different from the combination FILE --persist since the first one # leaves the history empty and sets the current $Line to 1. argparser.add_argument( "--initfile", help="the same that FILE and --persist together", type=argparse.FileType("r"), ) argparser.add_argument( "--quiet", "-q", help="don't print message at startup", action="store_true" ) argparser.add_argument( "-script", help="run a mathics file in script mode", action="store_true" ) argparser.add_argument( "--execute", "-e", action="append", metavar="EXPR", help="evaluate EXPR before processing any input files (may be given " "multiple times)", ) argparser.add_argument("--colors", nargs="?", help="interactive shell colors") argparser.add_argument( "--no-completion", help="disable tab completion", action="store_true" ) argparser.add_argument( "--no-readline", help="disable line editing (implies --no-completion)", action="store_true", ) argparser.add_argument( "--version", "-v", action="version", version="%(prog)s " + __version__ ) args, script_args = argparser.parse_known_args() quit_command = "CTRL-BREAK" if sys.platform == "win32" else "CONTROL-D" extension_modules = [] if args.pyextensions: for ext in args.pyextensions: extension_modules.append(ext) else: from mathics.settings import default_pymathics_modules extension_modules = default_pymathics_modules definitions = Definitions(add_builtin=True, extension_modules=extension_modules) definitions.set_line_no(0) shell = TerminalShell( definitions, args.colors, want_readline=not (args.no_readline), want_completion=not (args.no_completion), ) if args.initfile: feeder = FileLineFeeder(args.initfile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") definitions.set_line_no(0) if args.execute: for expr in args.execute: evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT) shell.print_result(result, no_out_prompt=True) if evaluation.exc_result == Symbol("Null"): exit_rc = 0 elif evaluation.exc_result == Symbol("$Aborted"): exit_rc = -1 elif evaluation.exc_result == Symbol("Overflow"): exit_rc = -2 else: exit_rc = -3 if not args.persist: return exit_rc if args.FILE is not None: feeder = FileLineFeeder(args.FILE) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") if args.persist: definitions.set_line_no(0) else: return exit_rc if not args.quiet: print() print(version_string + "\n") print(license_string + "\n") print("Quit by pressing {0}\n".format(quit_command)) while True: try: evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) query, source_code = evaluation.parse_feeder_returning_code(shell) if len(source_code) and source_code[0] == "!": subprocess.run(source_code[1:], shell=True) shell.definitions.increment_line_no(1) continue if query is None: continue if args.full_form: print(query) result = evaluation.evaluate(query, timeout=settings.TIMEOUT) if result is not None: shell.print_result(result) except (KeyboardInterrupt): print("\nKeyboardInterrupt") except EOFError: print("\n\nGoodbye!\n") break except SystemExit: print("\n\nGoodbye!\n") # raise to pass the error code on, e.g. Quit[1] raise finally: shell.reset_lineno() return exit_rc
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument( 'FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument( '--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE or -e', action='store_true') argparser.add_argument( '--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument( '-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', action='append', metavar='EXPR', help='evaluate EXPR before processing any input files (may be given ' 'multiple times)') argparser.add_argument( '--colors', nargs='?', help='interactive shell colors') argparser.add_argument( '--no-completion', help="disable tab completion", action='store_true') argparser.add_argument( '--no-readline', help="disable line editing (implies --no-completion)", action='store_true') argparser.add_argument( '--version', '-v', action='version', version='%(prog)s ' + __version__) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_line_no(0) shell = TerminalShell( definitions, args.colors, want_readline=not(args.no_readline), want_completion=not(args.no_completion)) if args.execute: for expr in args.execute: print(shell.get_in_prompt() + expr) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT) shell.print_result(result) if not args.persist: return if args.FILE is not None: feeder = FileLineFeeder(args.FILE) try: while not feeder.empty(): evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback, catch_interrupt=False) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print('\nKeyboardInterrupt') if args.persist: definitions.set_line_no(0) else: return if not args.quiet: print() print(version_string + '\n') print(license_string + '\n') print("Quit by pressing {0}\n".format(quit_command)) while True: try: evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) query = evaluation.parse_feeder(shell) if query is None: continue result = evaluation.evaluate(query, timeout=settings.TIMEOUT) if result is not None: shell.print_result(result) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") break finally: shell.reset_lineno()
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument('FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument('--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE or -e', action='store_true') argparser.add_argument('--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument('-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', action='append', metavar='EXPR', help='evaluate EXPR before processing any input files (may be given ' 'multiple times)') argparser.add_argument('--colors', nargs='?', help='interactive shell colors') argparser.add_argument('--no-completion', help="disable tab completion", action='store_true') argparser.add_argument( '--no-readline', help="disable line editing (implies --no-completion)", action='store_true') argparser.add_argument('--version', '-v', action='version', version='%(prog)s ' + __version__) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_line_no(0) shell = TerminalShell(definitions, args.colors, want_readline=not (args.no_readline), want_completion=not (args.no_completion)) if args.execute: for expr in args.execute: print(shell.get_in_prompt() + expr) evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT) shell.print_result(result) if not args.persist: return if args.FILE is not None: feeder = FileLineFeeder(args.FILE) try: while not feeder.empty(): evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell), catch_interrupt=False) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print('\nKeyboardInterrupt') if args.persist: definitions.set_line_no(0) else: return if not args.quiet: print() print(version_string + '\n') print(license_string + '\n') print("Quit by pressing {0}\n".format(quit_command)) while True: try: evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) query = evaluation.parse_feeder(shell) if query is None: continue result = evaluation.evaluate(query, timeout=settings.TIMEOUT) if result is not None: shell.print_result(result) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGoodbye!\n") break finally: shell.reset_lineno()
class MathicsNotebookKernel(Kernel): implementation = 'mathics' implementation_version = '1.0' banner = 'Mathics Jupyter Kernel - Implementation' language_info = { 'version': '1.0', 'name': 'Mathematica', 'mimetype': 'text/x-mathematica', } name = 'MathicsNotebook' """ Initialize Mathics core. """ def __init__(self, **kwargs): super().__init__(**kwargs) self.definitions = Definitions(add_builtin=True) self.evaluation = Evaluation(self.definitions, format='xml') """ Preprocess output for better support for graphics. """ def preprocess_output(self, data): data = re.sub( r"<math><mglyph width=\"(.*)\" height=\"(.*)\" src=\"(.*)\"/></math>", "<img width=\"\\1\" height=\"\\2\" src=\"\\3\" />", data, 0) return data """ Handle jupyter connections. """ def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False): if not silent: from mathics.core.parser import MultiLineFeeder feeder = MultiLineFeeder(code, '<notebook>') results = [] try: while not feeder.empty(): expr = self.evaluation.parse_feeder(feeder) if expr is None: results.append(Result(self.evaluation.out, None, None)) self.evaluation.out = [] continue result = self.evaluation.evaluate(expr, timeout=20) if result is not None: results.append(result) except Exception as exc: raise for result in results: result_data = result.get_data() result_html = self.preprocess_output(result_data['result']) display_data = { 'data': { 'text/html': result_html }, 'metadata': {}, } self.send_response(self.iopub_socket, 'display_data', display_data) return { 'status': 'ok', 'execution_count': self.execution_count, 'payload': [], 'user_expressions': {}, } def do_complete(self, code, cursor_pos): matches_raw = self.definitions.get_matching_names(code + '*') matches = [] for match in matches_raw: matches.append(match.replace('System`', '')) return { 'matches': matches, 'cursor_start': cursor_pos - len(code), 'cursor_end': cursor_pos, 'metadata': {}, 'status': 'ok', }
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument( 'FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument( '--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE or -e', action='store_true') argparser.add_argument( '--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument( '-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', action='append', metavar='EXPR', help='evaluate EXPR before processing any input files (may be given ' 'multiple times)') argparser.add_argument( '--colors', nargs='?', help='interactive shell colors') argparser.add_argument( '--no-completion', help="disable tab completion", action='store_true') argparser.add_argument( '--no-readline', help="disable line editing (implies --no-completion)", action='store_true') argparser.add_argument( '--version', '-v', action='version', version='%(prog)s ' + __version__) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number shell = TerminalShell( definitions, args.colors, want_readline=not(args.no_readline), want_completion=not(args.no_completion)) if not (args.quiet or args.script): print() print(version_string + '\n') print(license_string + '\n') print("Quit by pressing {0}\n".format(quit_command)) if args.execute: for expr in args.execute: print(shell.get_in_prompt() + expr) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) exprs = evaluation.parse(expr) results = evaluation.evaluate(exprs, timeout=settings.TIMEOUT) shell.print_results(results) if not args.persist: return if args.FILE is not None: lines = args.FILE.readlines() if args.script and lines[0].startswith('#!'): lines[0] = '' results = [] query_gen = parse_lines(lines, shell.definitions) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) try: for query in query_gen: results.extend(evaluation.evaluate([query], timeout=settings.TIMEOUT)) except TranslateError as exc: evaluation.recursion_depth = 0 evaluation.stopped = False evaluation.message('Syntax', exc.msg, *exc.args) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") if not args.persist: return total_input = "" while True: try: evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) line = shell.read_line(shell.get_in_prompt(continued=total_input != '')) total_input += line try: query = parse(total_input, shell.definitions) except TranslateError as exc: if line == '' or not isinstance(exc, IncompleteSyntaxError): evaluation.message('Syntax', exc.msg, *exc.args) total_input = "" continue total_input = "" if query is None: continue results = evaluation.evaluate([query], timeout=settings.TIMEOUT) shell.print_results(results) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") break
def test_case(test, tests, index=0, subindex=0, quiet=False, section=None): global check_partial_enlapsed_time test, wanted_out, wanted = test.test, test.outs, test.result def fail(why): part, chapter, section = tests.part, tests.chapter, tests.section print_and_log(f"""{sep}Test failed: {section} in {part} / {chapter} {part} n{why} """.encode("utf-8")) return False if not quiet: if section: print( f"{stars} {tests.chapter} / {section} {stars}".encode("utf-8")) print(f"{index:4d} ({subindex:2d}): TEST {test}".encode("utf-8")) feeder = MathicsSingleLineFeeder(test, "<test>") evaluation = Evaluation(definitions, catch_interrupt=False, output=TestOutput()) try: time_parsing = datetime.now() query = evaluation.parse_feeder(feeder) if check_partial_enlapsed_time: print(" parsing took", datetime.now() - time_parsing) if query is None: # parsed expression is None result = None out = evaluation.out else: result = evaluation.evaluate(query) if check_partial_enlapsed_time: print(" evaluation took", datetime.now() - time_parsing) out = result.out result = result.result except Exception as exc: fail("Exception %s" % exc) info = sys.exc_info() sys.excepthook(*info) return False time_comparing = datetime.now() comparison_result = compare(result, wanted) if check_partial_enlapsed_time: print(" comparison took ", datetime.now() - time_comparing) if not comparison_result: print("result =!=wanted") fail_msg = "Result: %s\nWanted: %s" % (result, wanted) if out: fail_msg += "\nAdditional output:\n" fail_msg += "\n".join(str(o) for o in out) return fail(fail_msg) output_ok = True time_comparing = datetime.now() if len(out) != len(wanted_out): output_ok = False else: for got, wanted in zip(out, wanted_out): if not got == wanted: output_ok = False break if check_partial_enlapsed_time: print(" comparing messages took ", datetime.now() - time_comparing) if not output_ok: return fail( "Output:\n%s\nWanted:\n%s" % ("\n".join(str(o) for o in out), "\n".join(str(o) for o in wanted_out))) return True
def test_case(test, tests, index=0, subindex=0, quiet=False, section=None): test, wanted_out, wanted = test.test, test.outs, test.result def fail(why): part, chapter, section = tests.part, tests.chapter, tests.section print( "%sTest failed: %s in %s / %s\n%s\n%s\n" % (sep, section, part, chapter, test, why) ) return False if not quiet: if section: print("%s %s / %s %s" % (stars, tests.chapter, section, stars)) print("%4d (%2d): TEST %s" % (index, subindex, test)) feeder = MathicsSingleLineFeeder(test, "<test>") evaluation = Evaluation(definitions, catch_interrupt=False, output=TestOutput()) try: query = evaluation.parse_feeder(feeder) if query is None: # parsed expression is None result = None out = evaluation.out else: result = evaluation.evaluate(query) out = result.out result = result.result except Exception as exc: fail("Exception %s" % exc) info = sys.exc_info() sys.excepthook(*info) return False if False: print("out=-----------------") for rr in out: for line in rr.text.splitlines(): print(" <",line,">") print("wanted_out=-------------------") for rr in wanted_out: for line in rr.text.splitlines(): print(" <",line,">") print("---------------------------------") if not compare(result, wanted): print("result =!=wanted") fail_msg = "Result: %s\nWanted: %s" % (result, wanted) if out: fail_msg += "\nAdditional output:\n" fail_msg += "\n".join(str(o) for o in out) return fail(fail_msg) output_ok = True if len(out) != len(wanted_out): output_ok = False else: for got, wanted in zip(out, wanted_out): if False: print("got=<",got,"> wanted=<",wanted,">") if not got == wanted: output_ok = False break if not output_ok: return fail( "Output:\n%s\nWanted:\n%s" % ("\n".join(str(o) for o in out), "\n".join(str(o) for o in wanted_out)) ) return True
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument('FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument('--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE or -e', action='store_true') argparser.add_argument('--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument('-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', action='append', metavar='EXPR', help='evaluate EXPR before processing any input files (may be given ' 'multiple times)') argparser.add_argument('--colors', nargs='?', help='interactive shell colors') argparser.add_argument('--no-completion', help="disable tab completion", action='store_true') argparser.add_argument( '--no-readline', help="disable line editing (implies --no-completion)", action='store_true') argparser.add_argument('--version', '-v', action='version', version='%(prog)s ' + __version__) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_line_no(0) # Reset the line number shell = TerminalShell(definitions, args.colors, want_readline=not (args.no_readline), want_completion=not (args.no_completion)) if not (args.quiet or args.script): print() print(version_string + '\n') print(license_string + '\n') print("Quit by pressing {0}\n".format(quit_command)) if args.execute: for expr in args.execute: print(shell.get_in_prompt() + expr) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) exprs = evaluation.parse(expr) results = evaluation.evaluate(exprs, timeout=settings.TIMEOUT) shell.print_results(results) if not args.persist: return if args.FILE is not None: lines = args.FILE.readlines() if args.script and lines[0].startswith('#!'): lines[0] = '' results = [] query_gen = parse_lines(lines, shell.definitions) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) try: for query in query_gen: results.extend( evaluation.evaluate([query], timeout=settings.TIMEOUT)) except TranslateError as exc: evaluation.recursion_depth = 0 evaluation.stopped = False evaluation.message('Syntax', exc.msg, *exc.args) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") if not args.persist: return total_input = "" while True: try: evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) line = shell.read_line( shell.get_in_prompt(continued=total_input != '')) total_input += line try: query = parse(total_input, shell.definitions) except TranslateError as exc: if line == '' or not isinstance(exc, IncompleteSyntaxError): evaluation.message('Syntax', exc.msg, *exc.args) total_input = "" continue total_input = "" if query is None: continue results = evaluation.evaluate([query], timeout=settings.TIMEOUT) shell.print_results(results) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") break
def main( full_form, persist, quiet, readline, completion, unicode, prompt, pyextensions, execute, run, style, pygments_tokens, strict_wl_output, file, ) -> int: """A command-line interface to Mathics. Mathics is a general-purpose computer algebra system """ exit_rc = 0 quit_command = "CTRL-BREAK" if sys.platform == "win32" else "CONTROL-D" extension_modules = [] if pyextensions: for ext in pyextensions: extension_modules.append(ext) definitions = Definitions(add_builtin=True) definitions.set_line_no(0) # Set a default value for $ShowFullFormInput to False. # Then, it can be changed by the settings file (in WL) # and overwritten by the command line parameter. definitions.set_ownvalue( "Settings`$ShowFullFormInput", from_python(True if full_form else False) ) definitions.set_ownvalue( "Settings`$PygmentsShowTokens", from_python(True if pygments_tokens else False) ) readline = "none" if (execute or file and not persist) else readline.lower() if readline == "prompt": shell = TerminalShellPromptToolKit( definitions, style, completion, unicode, prompt ) else: want_readline = readline == "gnu" shell = TerminalShellGNUReadline( definitions, style, want_readline, completion, unicode, prompt ) load_settings(shell) if run: with open(run, "r") as ifile: feeder = MathicsFileLineFeeder(ifile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, format="text", ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") definitions.set_line_no(0) if execute: for expr in execute: evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), format="text" ) shell.terminal_formatter = None result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT) shell.print_result(result, prompt, "text", strict_wl_output) # After the next release, we can remove the hasattr test. if hasattr(evaluation, "exc_result"): if evaluation.exc_result == Symbol("Null"): exit_rc = 0 elif evaluation.exc_result == Symbol("$Aborted"): exit_rc = -1 elif evaluation.exc_result == Symbol("Overflow"): exit_rc = -2 else: exit_rc = -3 if not persist: return exit_rc if file is not None: with open(file, "r") as ifile: feeder = MathicsFileLineFeeder(ifile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, format="text", ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") if not persist: return exit_rc if not quiet and prompt: print(f"\nMathicscript: {__version__}, {version_string}\n") print(license_string + "\n") print(f"Quit by evaluating Quit[] or by pressing {quit_command}.\n") # If defined, full_form and style overwrite the predefined values. definitions.set_ownvalue( "Settings`$ShowFullFormInput", SymbolTrue if full_form else SymbolFalse ) definitions.set_ownvalue( "Settings`$PygmentsStyle", from_python(shell.pygments_style) ) definitions.set_ownvalue( "Settings`$PygmentsShowTokens", from_python(pygments_tokens) ) definitions.set_ownvalue("Settings`MathicsScriptVersion", from_python(__version__)) definitions.set_attribute("Settings`MathicsScriptVersion", "System`Protected") definitions.set_attribute("Settings`MathicsScriptVersion", "System`Locked") TeXForm = Symbol("System`TeXForm") definitions.set_line_no(0) while True: try: if have_readline and shell.using_readline: import readline as GNU_readline last_pos = GNU_readline.get_current_history_length() full_form = definitions.get_ownvalue( "Settings`$ShowFullFormInput" ).replace.to_python() style = definitions.get_ownvalue("Settings`$PygmentsStyle") fmt = lambda x: x if style: style = style.replace.get_string_value() if shell.terminal_formatter: fmt = lambda x: highlight( str(query), mma_lexer, shell.terminal_formatter ) evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) query, source_code = evaluation.parse_feeder_returning_code(shell) if ( have_readline and shell.using_readline and hasattr(GNU_readline, "remove_history_item") ): current_pos = GNU_readline.get_current_history_length() for pos in range(last_pos, current_pos - 1): GNU_readline.remove_history_item(pos) wl_input = source_code.rstrip() if unicode: wl_input = replace_wl_with_plain_text(wl_input) GNU_readline.add_history(wl_input) if query is None: continue if hasattr(query, "head") and query.head == TeXForm: output_style = "//TeXForm" else: output_style = "" if full_form: print(fmt(query)) result = evaluation.evaluate( query, timeout=settings.TIMEOUT, format="unformatted" ) if result is not None: shell.print_result( result, prompt, output_style, strict_wl_output=strict_wl_output ) except ShellEscapeException as e: source_code = e.line if len(source_code) and source_code[1] == "!": try: print(open(source_code[2:], "r").read()) except: print(str(sys.exc_info()[1])) else: subprocess.run(source_code[1:], shell=True) # Should we test exit code for adding to history? GNU_readline.add_history(source_code.rstrip()) # FIXME add this... when in Mathics core updated # shell.defintions.increment_line(1) except (KeyboardInterrupt): print("\nKeyboardInterrupt") except EOFError: if prompt: print("\n\nGoodbye!\n") break except SystemExit: print("\n\nGoodbye!\n") # raise to pass the error code on, e.g. Quit[1] raise finally: # Reset the input line that would be shown in a parse error. # This is not to be confused with the number of complete # inputs that have been seen, i.e. In[] shell.reset_lineno() return exit_rc