I have prototyped a solution to some difficulties with JLine (Issue
2046), but to make it work in the general case will require changes to
how we go about initialisation that may impact users who have embedded
the interpreter in applications. I'm not sure which aspects of the
present classes constitute API we ought to keep stable.
The root of these problems with JLine is the direct use by sys.stdin of
a System.in, after its behaviour has been modified by JLine to suit
itself. Use of jline.ConsoleReader.readLine through
JLineConsole.raw_input works fairly well. Application writers probably
also expect to use System.in without nasty surprises. By replacing
System.in with a stream that wraps JLine (using
jline.ConsoleReaderInputStream.setIn), I am able to get interactive
behaviour very much like CPython's and a coherent System.in that
benefits from JLine history and editing.
dev>java -cp build\exposed;build\classes;dist\javalib\*
Jython 2.7b1+ (default:bb71f88cbe80+, May 17 2013, 18:20:38)
[Java HotSpot(TM) 64-Bit Server VM (Sun Microsystems Inc.)] on java1.6.0_35
>>> import sys
The purpose of JLine is to provide a more convenient way for a user to
get (encoded) characters into a program than typing everything. I'll
call this its "console" function. However, in our current design,
JLineConsole is also a PythonInterpreter, working with lines of
characters treated as commands. It is only by separating the two
concerns, console and interpreter, that I've been able to make it work.
Although one bug fix shouldn't drive architecture, I think this provides
an architectural hint they should be separate.
The second hint this provides is about initialisation. I've hard-wired
use of JLine in my demonstration, but for the console/interpreter to be
selected through configuration, I believe I have to break initialisation
into phases that give the invoking code a chance to act between them.
These phases are probably fill registry, init static state, create
PySystemState instance. I get the feeling this is not the only case
where it would be useful to respond to configuration, or to respond to
static initialisation, before all the plates start spinning.
What do others think? And where are the pitfalls, particularly API
change breaking others' work? I guess we'd like the text-book examples
still to work as written, but what else?