All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.python.util.InteractiveInterpreter Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version
// Copyright (c) Corporation for National Research Initiatives
package org.python.util;

import org.python.core.*;

/**
 * This class provides the interface for compiling and running code that supports an interactive
 * interpreter.
 */
// Based on CPython-1.5.2's code module
public class InteractiveInterpreter extends PythonInterpreter {

    /**
     * Construct an InteractiveInterpreter with all default characteristics: default state (from
     * {@link Py#getSystemState()}), and a new empty dictionary of local variables.
     * */
    public InteractiveInterpreter() {
        this(null);
    }

    /**
     * Construct an InteractiveInterpreter with state (from {@link Py#getSystemState()}), and the
     * specified dictionary of local variables.
     *
     * @param locals dictionary to use, or if null, a new empty one will be created
     */
    public InteractiveInterpreter(PyObject locals) {
        this(locals, null);
    }

    /**
     * Construct an InteractiveInterpreter with, and system state the specified dictionary of local
     * variables.
     *
     * @param locals dictionary to use, or if null, a new empty one will be created
     * @param systemState interpreter state, or if null use {@link Py#getSystemState()}
     */
    public InteractiveInterpreter(PyObject locals, PySystemState systemState) {
        super(locals, systemState);
    }

    /**
     * Compile and run some source in the interpreter, in the mode {@link CompileMode#single} which
     * is used for incremental compilation at the interactive console, known as {@code }.
     *
     * @param source Python code
     * @return true to indicate a partial statement was entered
     */
    public boolean runsource(String source) {
        return runsource(source, "", CompileMode.single);
    }

    /**
     * Compile and run some source in the interpreter, in the mode {@link CompileMode#single} which
     * is used for incremental compilation at the interactive console.
     *
     * @param source Python code
     * @param filename name with which to label this console input (e.g. in error messages).
     * @return true to indicate a partial statement was entered
     */
    public boolean runsource(String source, String filename) {
        return runsource(source, filename, CompileMode.single);
    }

    /**
     * Compile and run some source in the interpreter, according to the {@link CompileMode} given.
     * This method supports incremental compilation and interpretation through the return value,
     * where {@code true} signifies that more input is expected in order to complete the Python
     * statement. An interpreter can use this to decide whether to use {@code sys.ps1}
     * ("{@code >>> }") or {@code sys.ps2} ("{@code ... }") to prompt the next line. The arguments
     * are the same as the mandatory ones in the Python {@code compile()} command.
     * 

* One the following can happen: *

    *
  1. The input is incorrect; compilation raised an exception (SyntaxError or OverflowError). A * syntax traceback will be printed by calling {@link #showexception(PyException)}. Return is * {@code false}.
  2. * *
  3. The input is incomplete, and more input is required; compilation returned no code. * Nothing happens. Return is {@code true}.
  4. * *
  5. The input is complete; compilation returned a code object. The code is executed by * calling {@link #runcode(PyObject)} (which also handles run-time exceptions, except for * SystemExit). Return is {@code false}.
  6. *
* * @param source Python code * @param filename name with which to label this console input (e.g. in error messages). * @param kind of compilation required: {@link CompileMode#eval}, {@link CompileMode#exec} or * {@link CompileMode#single} * @return {@code true} to indicate a partial statement was provided */ public boolean runsource(String source, String filename, CompileMode kind) { PyObject code; try { code = Py.compile_command_flags(source, filename, kind, cflags, true); } catch (PyException exc) { if (exc.match(Py.SyntaxError)) { // Case 1 showexception(exc); return false; } else if (exc.match(Py.ValueError) || exc.match(Py.OverflowError)) { // Should not print the stack trace, just the error. showexception(exc); return false; } else { throw exc; } } // Case 2 if (code == Py.None) { return true; } // Case 3 runcode(code); return false; } /** * Execute a code object. When an exception occurs, {@link #showexception(PyException)} is * called to display a stack trace, except in the case of SystemExit, which is re-raised. *

* A note about KeyboardInterrupt: this exception may occur elsewhere in this code, and may not * always be caught. The caller should be prepared to deal with it. **/ // Make this run in another thread somehow???? public void runcode(PyObject code) { try { exec(code); } catch (PyException exc) { if (exc.match(Py.SystemExit)) { throw exc; } showexception(exc); } } public void showexception(PyException exc) { // Should probably add code to handle skipping top stack frames // somehow... Py.printException(exc); } public void write(String data) { Py.stderr.write(data); } public StringBuilder buffer = new StringBuilder(); public String filename = ""; public void resetbuffer() { buffer.setLength(0); } /** * Pause the current code, sneak an exception raiser into sys.trace_func, and then continue the * code hoping that Jython will get control to do the break; **/ public void interrupt(ThreadState ts) { TraceFunction breaker = new BreakTraceFunction(); TraceFunction oldTrace = ts.tracefunc; ts.tracefunc = breaker; if (ts.frame != null) { ts.frame.tracefunc = breaker; } ts.tracefunc = oldTrace; // ts.thread.join(); } } class BreakTraceFunction extends TraceFunction { private void doBreak() { throw new Error("Python interrupt"); // Thread.currentThread().interrupt(); } @Override public TraceFunction traceCall(PyFrame frame) { doBreak(); return null; } @Override public TraceFunction traceReturn(PyFrame frame, PyObject ret) { doBreak(); return null; } @Override public TraceFunction traceLine(PyFrame frame, int line) { doBreak(); return null; } @Override public TraceFunction traceException(PyFrame frame, PyException exc) { doBreak(); return null; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy