开发者

How to close the input stream of an IronPython engine executing a script?

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.DoE开发者_Python百科vents();
            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...


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜