メモの日々


2013年11月12日(火) [長年日記]

[python][java] JythonをScriptEngine経由で使うときにマジックコメントを書くとエラーになる

以前も調べたのに今日また調べてしまったのでメモしておく。

Pythonスクリプト内でエンコード宣言を書いたものをJavaのスクリプティング機能から呼び出すと、例外が投げられてしまう。

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JythonRunner {
    public static void main(String[] args) throws ScriptException {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("python");
        engine.eval(
            "# coding: utf-8\n" +
            "print 'hello'\n");
    }
}
Exception in thread "main" javax.script.ScriptException: org.python.antlr.ParseException: org.python.antlr.ParseException: encoding declaration in Unicode string
	at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:196)
	at org.python.jsr223.PyScriptEngine.compileScript(PyScriptEngine.java:75)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at JythonRunner.main(JythonRunner.java:9)
Caused by: org.python.antlr.ParseException: encoding declaration in Unicode string


org.python.antlr.ParseException: org.python.antlr.ParseException: encoding declaration in Unicode string

	at org.python.core.Py.JavaError(Py.java:481)
	at org.python.core.ParserFacade.parseExpressionOrModule(ParserFacade.java:124)
	at org.python.util.PythonInterpreter.compile(PythonInterpreter.java:259)
	at org.python.util.PythonInterpreter.compile(PythonInterpreter.java:256)
	at org.python.util.PythonInterpreter.compile(PythonInterpreter.java:250)
	at org.python.jsr223.PyScriptEngine.compileScript(PyScriptEngine.java:70)
	... 3 more
Caused by: org.python.antlr.ParseException: encoding declaration in Unicode string
	at org.python.core.ParserFacade.prepBufReader(ParserFacade.java:277)
	at org.python.core.ParserFacade.parseExpressionOrModule(ParserFacade.java:119)
	... 7 more

Javaを使わずJython上で直接実行する場合はエラーにならない。

例外を投げているParserFacade#prepBufReader()のソースコードを見ると、

        if (findEncoding(bufferedReader) != null)
            throw new ParseException("encoding declaration in Unicode string");

となっていて、意図的に例外を投げているみたい。エンコーディングはJava側で決めてスクリプトを読み込んでいるからだと思うけど、不便。