Reputation: 70344
I am creating an IronPython engine more or less like so:
var engine = IronPython.Hosting.Python.CreateEngine();
var scope = engine.CreateScope();
// my implementation of System.IO.Stream
var stream = new ScriptOutputStream(engine);
engine.Runtime.IO.SetOutput(stream, Encoding.UTF8);
engine.Runtime.IO.SetErrorOutput(stream, Encoding.UTF8);
engine.Runtime.IO.SetInput(stream, Encoding.UTF8);
var script = engine.CreateScriptSourceFromString(source, SourceCodeKind.Statements);
script.Execute(scope);
The variable source
is a string with following contents (python statements):
import code
code.interact(None, None,
{
'__name__' : '__console__',
'__doc__' : None,
})
The stream is being hosted on a windows form. When that form closes, I want the interpreter to quit. Obviously, I tried closing the stream in the Read
method:
/// <summary>
/// Read from the _inputBuffer, block until a new line has been entered...
/// </summary>
public override int Read(byte[] buffer, int offset, int count)
{
if (_gui.IsDisposed)
{
return 0; // msdn says this indicates the stream is closed
}
while (_completedLines.Count < 1)
{
// wait for user to complete a line
Application.DoEvents();
Thread.Sleep(10);
}
var line = _completedLines.Dequeue();
return line.Read(buffer, offset, count);
}
The member variable _completedLines
holds a queue of MemoryStream
objects representing lines the user has entered so far. _gui
is a reference to the windows form - when it is disposed, I somehow want the IronPython engine to stop executing code.interact()
.
Returnin 0
from the Read
method does not work (Read
is just called again). Raising one of the exceptions from the documentation of Read does not work either: It does stop execution of the interpreter, but the IDE breaks inside the Read
method :(
I have also tried returning ^Z
(0x1a) and ^D
(0x04) in Read
's buffer, as these are used on the console to quit the interpreter, but that doesn't work at all...
Upvotes: 0
Views: 1063
Reputation: 7662
It took me a second look to figure out what you wanted, but this looks like a bug in IronPython. code.interact
expects an EOFError to be raised from the raw_input
builtin to signal that it's time for the loop to end, but IronPython doesn't do that - it just returns an empty string. This is IronPython issue #22140.
You could try throwing an EndOfStreamException, which converts to EOFError. That might be enough to trick it.
Upvotes: 1