1

I am writing a C# component which takes an ironpython function as a parameter.

    def test():
        x=x+1
        print "Test"

C#:

    var v = engine.Operations.Invoke(scope.GetVariable("test"));

Var v returns null for print statements. It works only if I have return(x). Can I capture print statements using ironpython?

Comments and links are appreciated. Also, can just capture it using commandline?

Mike Corcoran
  • 14,072
  • 4
  • 37
  • 49
user2801184
  • 329
  • 7
  • 27
  • 1
    possible duplicate of [How can I redirect the stdout of ironpython in C#?](http://stackoverflow.com/questions/3055002/how-can-i-redirect-the-stdout-of-ironpython-in-c) – Valentin Lorentz Jun 27 '14 at 16:32
  • The above link works if I have "sys.stdout". My script only has print command? – user2801184 Jun 27 '14 at 16:56
  • The print statement uses `sys.stdout` by default. (See also http://stackoverflow.com/a/3263763/539465) – Valentin Lorentz Jun 27 '14 at 19:32
  • try { var strExpression = @" def test(): x=x+1 print "Test" var engine = Python.CreateEngine(); var scope = engine.CreateScope(); var sourceCode = engine.CreateScriptSourceFromString(strExpression); scope.SetVariable("test", this); var actual = sourceCode.Execute(scope); textBox1.Text += actual; } I tried this but does not work for me – user2801184 Jun 27 '14 at 19:51
  • how about this one: http://stackoverflow.com/a/21754433/1761490 – Pawel Jasinski Jun 28 '14 at 19:47
  • Thanks Pawel, the above solution works: but how can I capture return can you help me with "return"? My code below: public class PythonFile { public string write(string s) { return (s)}} How can I capture this with engine.GetSysModule().SetVariable("stdout", new pythonfile() ) – user2801184 Jun 30 '14 at 17:16

1 Answers1

6

This works for me:

using IronPython.Hosting; 
using Microsoft.Scripting.Hosting; //provides scripting abilities comparable to batch files
using System.IO;
using System;
using System.Text;

var script = @"import sys
def test(): 
    print sys.version
    print >> sys.stderr, 'this goes to stderr'
    return 42";

var scriptEngine = Python.CreateEngine();
var scriptScope = scriptEngine.CreateScope();
scriptEngine.Execute(script, scriptScope);
var testFn = scriptScope.GetVariable("test");
var streamOut = new MemoryStream();
var streamErr = new MemoryStream();
scriptEngine.Runtime.IO.SetOutput(streamOut, Encoding.Default);
scriptEngine.Runtime.IO.SetErrorOutput(streamErr, Encoding.Default);
scriptEngine.Operations.Invoke(testFn);
Console.WriteLine("returned: {0}", scriptEngine.Operations.Invoke(testFn));
Console.WriteLine("captured out:\n{0}", Encoding.Default.GetString(streamOut.ToArray()));
Console.WriteLine("captured err:\n{0}", Encoding.Default.GetString(streamErr.ToArray()));

Output:

returned: 42
captured out:
2.7.5b2 (IronPython 2.7.5b2 (2.7.5.0) on .NET 2.0.50727.5477 (64-bit))

captured err:
this goes to stderr
theduck
  • 2,589
  • 13
  • 17
  • 23
Pawel Jasinski
  • 796
  • 3
  • 10
  • Thank you so much Pawel. I really appreciate your help but can you please answer my above question also above solution explaination if possible. you can give me links too.Eagerly waiting for the response! – user2801184 Jun 30 '14 at 17:18
  • I am confused. Can you restate the question which you would like to have answered? – Pawel Jasinski Jun 30 '14 at 21:24
  • Can you please answer both? I don't know: if Method #1 is used then how can we have return value since it is in different class. And using stream we are able to capture Output? – user2801184 Jun 30 '14 at 22:11
  • Can you update your answer to say how to capture `stderr` or say why it's not possible? – Gabe Jun 30 '14 at 23:21
  • Gabe: Use `scriptEngine.Runtime.IO.SetError` instead. – Jeff Hardy Jul 01 '14 at 09:49
  • @Gabe, I have added capturing of stderr – Pawel Jasinski Jul 01 '14 at 11:28
  • @PawelJasinski: Why doesn't scriptEngine.Operations.Invoke(testFn); work for serial communication? It goes in infinite loop? Can you send me some links where I can get detailed info about above topic? – user2801184 Jul 08 '14 at 00:15
  • @user2801184, can you show us exactly what you are doing? A runnable snippet would be ideal. – Pawel Jasinski Jul 08 '14 at 14:12
  • http://stackoverflow.com/questions/24620217/iron-python-error-expected-type-bytes-or-bytearray-got-type-str-for-se/24628437#24628437 – user2801184 Jul 08 '14 at 17:22
  • Please check the above link! – user2801184 Jul 08 '14 at 17:23
  • let me know if you need more explaination? Appreciate your help Buddy! – user2801184 Jul 08 '14 at 22:59
  • Hi Pawel, I was wondering if we can pause a python script using C#? Thanks for the help! – user2801184 Aug 26 '14 at 00:21
  • If you have a new question, please start a new separate entry. If it is clearly ironpython speciality you can try our mailing list https://mail.python.org/mailman/listinfo/ironpython-users or chat https://jabbr.net/#/rooms/ironpython – Pawel Jasinski Aug 26 '14 at 07:03