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側で決めてスクリプトを読み込んでいるからだと思うけど、不便。