Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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 = 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(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 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
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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
Exemplo n.º 5
0
    def do_execute(self,
                   code,
                   silent,
                   store_history=True,
                   user_expressions=None,
                   allow_stdin=False):

        if not silent:
            from mathics.core.parser import MultiLineFeeder

            definitions = Definitions(add_builtin=True)
            evaluation = Evaluation(definitions, format='xml')

            feeder = MultiLineFeeder(code, '<notebook>')
            results = []
            try:
                while not feeder.empty():
                    expr = evaluation.parse_feeder(feeder)
                    if expr is None:
                        results.append(Result(evaluation.out, None, None))
                        evaluation.out = []
                        continue
                    result = 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': {},
        }
Exemplo n.º 6
0
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()
Exemplo n.º 7
0
def load_settings(shell):
    autoload_files(shell.definitions, get_srcdir(), "autoload")
    settings_file = ensure_settings()
    if settings_file == "":
        return
    with open(settings_file, "r") as src:
        feeder = MathicsFileLineFeeder(src)
        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)
        except (KeyboardInterrupt):
            print("\nKeyboardInterrupt")
    return True
Exemplo n.º 8
0
Arquivo: main.py Projeto: slel/Mathics
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
Exemplo n.º 9
0
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()
Exemplo n.º 10
0
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()
Exemplo n.º 11
0
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',
        }
Exemplo n.º 12
0
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
Exemplo n.º 13
0
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