Search code examples
javapythongraalvm

Getting outer environment arguments from java using graal python


I'm running Java in a GraalVM to use it to execute python.

Context context = Context.create();
Value v = context.getPolyglotBindings();
v.putMember("arguments", arguments);

final Value result = context.eval("python", contentsOfMyScript);
System.out.println(result);
return jsResult;

The question is how the python code should receive "arguments". The graal documentation states that if this were JS, I would do something like this:

const args = Interop.import('arguments');

Indeed, that works. The python equivalent might be:

import Interop
args = Interop.import('arguments')

def main():
    return args

main()

This fails, as there's no such module. I can't find documentation on how to get these arguments from the outer language layer, only docs on pythongraal and how to use python to pass to something else.


Solution

  • Some information on this is available at http://www.graalvm.org/docs/reference-manual/polyglot/.

    The module you're looking for is called polyglot. The operation is called import_value in Python, because import is a keyword.

    You can import from the polyglot bindings using the following:

    import polyglot
    value = polyglot.import_value('name')
    

    btw, it's almost the same in JavaScript: Polyglot.import(name) (Interop still works, for compatibility reasons)

    A complete example:

    import org.graalvm.polyglot.*;
    
    class Test {
        public static void main(String[] args) {
            Context context = Context.newBuilder().allowIO(true).build();
            Value v = context.getPolyglotBindings();
            v.putMember("arguments", 123);
    
            String script = "import polyglot\n" +
                            "polyglot.import_value('arguments')";
            Value array = context.eval("python", "[1,2,42,4]");
            Value result = context.eval("python", script);
            System.out.println(result);
        }
    }