IronLanguages / IronLanguages/ironpython3
SetOutput to stream doesn't work (3.4.0-alpha1)
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 2.8k
- Forks
- 316
- Avg merge
- 1d 9h
- Merged PRs (30d)
- 1
Description
Description
We're attempting to capture the output to a stream. It is never called.
*Note: This used to work in the Iron Python 2 version - we're using the same codebase.
Steps to Reproduce
This example will demonstrate how the stdout isn't being captured by the stream assignment. The iron python script is running in a thread in a loop printing to the stdout. The assignment to the SetOutput stream is set but the stream is never written to.
public class StreamWriteEvent : MemoryStream {
public event EventHandler<string> OnNewText;
public override void Write(byte[] buffer, int offset, int count) {
OnNewText?.Invoke(this, Encoding.Default.GetString(buffer, offset, count));
base.Write(buffer, offset, count);
}
public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) {
OnNewText?.Invoke(this, Encoding.Default.GetString(buffer, offset, count));
return base.WriteAsync(buffer, offset, count, cancellationToken);
}
public override void WriteByte(byte value) {
OnNewText?.Invoke(this, value.ToString());
base.WriteByte(value);
}
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
OnNewText?.Invoke(this, Encoding.Default.GetString(buffer, offset, count));
return base.BeginWrite(buffer, offset, count, callback, state);
}
}
ScriptEngine _engine;
ScriptScope _scope;
// Run a python script in a new thread
private void button2_Click(object sender, EventArgs e) {
Thread ts = new Thread(runScript);
ts.Start();
}
// This thread is running the python script
void runScript() {
var streamWriter = new StreamWriteEvent();
streamWriter.OnNewText += StreamWriter_OnNewText;
_engine = IronPython.Hosting.Python.CreateEngine();
_engine.Runtime.IO.SetErrorOutput(streamWriter, Encoding.ASCII);
_engine.Runtime.IO.SetOutput(streamWriter, Encoding.ASCII);
_scope = _engine.CreateScope();
// Run a script that loops
// We will test both capturing the output stream & the Shutdown command to stop the running script
var sc = _engine.CreateScriptSourceFromString(@"
while True:
print('This should output something')
");
var ret = sc.Execute(_scope);
// This doesn't do anything. It doesn't stop the running script.
Console.WriteLine("Shut down");
}
private void StreamWriter_OnNewText(object sender, string e) {
// This should output but never does
Console.WriteLine("From steam writer" + e);
}
// This is the button that should stop the running python script
private void button3_Click(object sender, EventArgs e) {
Console.WriteLine("Shutting down...");
// This shutdown command doesn't work. The script will continue running.
_scope.Engine.Runtime.Shutdown();
}
Expected behavior:
The stream contains the output of the print() statement
Actual behavior:
No output from print() statements in the stream
Versions
3.4.0-alpha1 for .Net Framework 4.7.2 from nuget
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the example around Runtime.IO.SetOutput, SetErrorOutput, and Runtime.Shutdown with the looping script created by CreateScriptSourceFromString. Trace how output and shutdown are handled across the script's worker thread. Done means print() output reaches the assigned stream and Runtime.Shutdown stops the running loop as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp, python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100