Skip to content

Commit

Permalink
ensure stdout wrapper is disposed
Browse files Browse the repository at this point in the history
  • Loading branch information
eirannejad committed May 29, 2024
1 parent bc0dc05 commit 6e5dfbb
Showing 1 changed file with 23 additions and 12 deletions.
35 changes: 23 additions & 12 deletions src/runtime/McNeel.PythonEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,24 +266,26 @@ public void SetSysArgs(IEnumerable<string> args)
#endregion

#region Standard IO
public void SetStdIO(Stream stdin, Stream stdout)
public void SetStdIO(Stream stdout)
{
using (Py.GIL())
{
using var sys = Runtime.PyImport_ImportModule("sys");
using (PyObject sysObj = sys.MoveToPyObject())
{
using var stdio = PyObject.FromManagedObject(
new RhinoCodePythonEngineIO(stdin, stdout)
);
sysObj.SetAttr("stdin", stdio);
if (sysObj.GetAttr("stdout")
.AsManagedObject(typeof(RhinoCodePythonEngineIO)) is RhinoCodePythonEngineIO currentStdout)
{
currentStdout.Dispose();
}

using var stdio = PyObject.FromManagedObject(new RhinoCodePythonEngineIO(stdout));
sysObj.SetAttr("stdout", stdio);
sysObj.SetAttr("stderr", stdio);
}
}
}

public void ClearStdIO() => SetStdIO(null, null);
public void ClearStdIO() => SetStdIO(null);
#endregion

#region Execution
Expand Down Expand Up @@ -1027,10 +1029,9 @@ static bool IsGenericType(Type type, Type genericType)
[SuppressMessage("Python.Runtime", "IDE1006")]
public class RhinoCodePythonEngineIO : Stream, IDisposable
{
readonly Stream _stdin = null;
readonly Stream _stdout = null;
Stream _stdout = default;

public RhinoCodePythonEngineIO(Stream stdin, Stream stdout) { _stdin = stdin; _stdout = stdout; }
public RhinoCodePythonEngineIO(Stream stdout) { _stdout = stdout; }

#region Python stream
public bool isatty() => false;
Expand Down Expand Up @@ -1062,17 +1063,27 @@ public void write(string content)
#region Stream
public Encoding OutputEncoding { get; set; } = Encoding.UTF8;

public override bool CanRead => true;
public override bool CanRead => false;
public override bool CanWrite => true;
public override bool CanSeek => false;
public override long Length => _stdout?.Length ?? 0;
public override long Position { get => _stdout?.Position ?? 0; set { if (_stdout is null) return; _stdout.Position = value; } }
public override long Seek(long offset, SeekOrigin origin) => _stdout?.Seek(offset, origin) ?? 0;
public override void SetLength(long value) => _stdout.SetLength(value);
public override int Read(byte[] buffer, int offset, int count) => _stdin?.Read(buffer, offset, count) ?? 0;
public override int Read(byte[] buffer, int offset, int count) => 0;
public override void Write(byte[] buffer, int offset, int count) => _stdout?.Write(buffer, offset, count);
public override void Flush() => _stdout?.Flush();
#endregion

protected override void Dispose(bool disposing)
{
if (disposing)
{
_stdout = default;
}

base.Dispose(disposing);
}
}
}
#pragma warning restore

0 comments on commit 6e5dfbb

Please sign in to comment.