[Python.NET] avoiding runtime error R6034
I’ve started using the version of PythonDotNet from https://github.com/renshawbay/pythonnet to call my Python modules from C#. I encountered the Microsoft runtime error R6034 which (according to <http://stackoverflow.com/questions/14552348/runtime-error-r6034-in-embedded-python-application>) is caused by extra copies of the file "msvcr90.dll” in folders on the Windows execution PATH. I worked around this problem by calling the following function in my initialization code. def cleanWindowsPathOfCRuntimeDll(): """ This function changes the Windows execution PATH environment variable so as to exclude any folders that contain the file "msvcr90.dll". Apparently the existence of this file in the PATH causes runtime error R6034 when using embedded Python. See: http://stackoverflow.com/questions/14552348/runtime-error-r6034-in-embedded-python-application """ folderPaths = os.environ['path'].split(';') toExclude = list() for folderPath in folderPaths: if "msvcr90.dll" in map((lambda x:x.lower()), os.listdir(folderPath)): toExclude.append(folderPath) debugMsg(0, "excluding folder '%s' from PATH" % folderPath) os.environ['path'] = ';'.join([x for x in folderPaths if x not in toExclude]) # —— -- Cameron Hayne cameron.ha...@introspect.ca _ Python.NET mailing list - PythonDotNet@python.org https://mail.python.org/mailman/listinfo/pythondotnet
[Python.NET] changes to Python.Runtime.Converter and Python.Runtime.Object
I have been using the version of PythonDotNet from https://github.com/renshawbay/pythonnet for embedding - i.e. to call Python code in C# programs. I have made a few changes to the source code in order to make using Python objects in C# easier, or to fix problems. Here are the changes: 1) In the source file “converter.cs” which defines the class Python.Runtime.Converter, I added the following to the switch case ‘TypeCode.Object’ in the ‘ToPython’ function: case TypeCode.Object: // The following ‘if’ clause is needed (as suggested by Patrick Stewart) to make the examples in the README work. if (value is IEnumerable) { using (var resultlist = new PyList()) { foreach (object o in (IEnumerable)value) { Type oType = o.GetType(); TypeCode oTc = Type.GetTypeCode(oType); // The following 'if' clause for Object entries is needed so that the entries // in lists of Python objects don't lose their types. // I.e. so that if you do something like: // dynamic obj1 = myPythonClass(); // List myList = new List { obj1 }; // myPythonFunc(myList); // then the type of myList[0] inside myPythonFunc will be the same as the type of obj1 // whereas the 'else' clause would make it be of type Python.Runtime.PyObject if (oTc == TypeCode.Object) { resultlist.Append((PyObject)o); } else { using (var p = new PyObject(ToPython(o, oType))) resultlist.Append(p); } } Runtime.Incref(resultlist.Handle); return resultlist.Handle; } } 2) In the source file “pyobject.cs” which defines the class Python.Runtime.PyObject, I replaced the line: this.SetAttr(binder.Name, (PyObject)value); in the ‘if (this.HasAttr(binder.Name))’ clause in the function ‘TrySetMember’ with the following: // Use ‘ToPython’ if an exception occurs when casting to (PyObject) // Without this, get exception e.g. when assign a C# String to a Python member // like: myPyObj.name = name; PyObject pyValue; try { pyValue = (PyObject)value; } catch (Exception) { pyValue = value.ToPython(); } this.SetAttr(binder.Name, pyValue); I would be interested in any comments about these changes - especially if there are better ways of fixing the problems. I am also interested to hear if anyone has other improvements to suggest. -- Cameron Hayne cameron.ha...@introspect.ca _ Python.NET mailing list - PythonDotNet@python.org https://mail.python.org/mailman/listinfo/pythondotnet
[Python.NET] calling Python via Python.Runtime DLL from IronPython
Should it be possible to call Python (CPython) code from IronPython (an IronPython script) via the Python.Runtime DLL ? I.e. an IronPython script that imports the Python.Runtime DLL and then calls the functions provided by that DLL. In my preliminary tests, I get an error about ‘copy_reg’ not being found. This error seems to happen when calling PythonEngine.Initialize(). -- Cameron Hayne cameron.ha...@introspect.ca _ Python.NET mailing list - PythonDotNet@python.org https://mail.python.org/mailman/listinfo/pythondotnet
Re: [Python.NET] calling Python via Python.Runtime DLL from IronPython
I tried calling Py_SetPythonHome("C:\\Python27") before calling PythonEngine.Initialize(), but I got the same problem (re ‘copy_reg’ not found). Any other suggestions? -- Cameron Hayne cameron.ha...@introspect.ca On Apr 19, 2016, at 4:37 PM, Tony Roberts wrote: > No need to import the c Python extension - from IronPython you would be able > to reference the Python.runtime assembly without it. The problem you're > having sounds like the python path isn't correct for cPython. You could try > setting the PYTHONHOME environment variable and see if that gets you any > further. > > Best regards, > Tony > On Tue, Apr 19, 2016 at 9:30 PM Denis Akhiyarov > wrote: > Did you try this code? > > http://www.voidspace.org.uk/ironpython/cpython_extensions.shtml > > On Tue, Apr 19, 2016 at 2:09 PM, Cameron Hayne > wrote: > Should it be possible to call Python (CPython) code from IronPython (an > IronPython script) via the Python.Runtime DLL ? > I.e. an IronPython script that imports the Python.Runtime DLL and then calls > the functions provided by that DLL. > In my preliminary tests, I get an error about ‘copy_reg’ not being found. > This error seems to happen when calling PythonEngine.Initialize(). _ Python.NET mailing list - PythonDotNet@python.org https://mail.python.org/mailman/listinfo/pythondotnet
Re: [Python.NET] Embedding a Python interactive shell in a .NET application
I’m using a similar method for redirecting Python output to a .NET textBox: #-- public static void redirectPythonOutput(TextWriter writer) { Output output = new Output(writer); using (Py.GIL()) { dynamic sys = Py.Import("sys"); sys.stdout = output; sys.stderr = output; } } #-- where ‘Output’ is my own .NET class that implements the method expected of a Python file object: #-- public class Output { private TextWriter myWriter = null; // ctor public Output(TextWriter writer) { myWriter = writer; } public void write(String str) { str = str.Replace("\n", Environment.NewLine); if (myWriter != null) { myWriter.Write(str); } else { Console.Write(str); } } public void writelines(String[] str) { foreach (String line in str) { if (myWriter != null) { myWriter.Write(str); } else { Console.Write(str); } } } public void flush() { if (myWriter != null) { myWriter.Flush(); } } public void close() { if (myWriter != null) { myWriter.Close(); } } } #-- and I pass an instance of my TextBoxStreamWriter class to the constructor of Output: #-- public class TextBoxStreamWriter : TextWriter { TextBox myTextBox = null; // ctor public TextBoxStreamWriter(TextBox textBox) { myTextBox = textBox; } // TODO: isn't this inefficient? Should we supply a method to write a string? public override void Write(char value) { base.Write(value); MethodInvoker action = delegate { myTextBox.AppendText(value.ToString()); }; myTextBox.BeginInvoke(action); } public override System.Text.Encoding Encoding { get { return System.Text.Encoding.UTF8; } } } #-- On May 27, 2016, at 5:40 PM, Saparya K wrote: > Just in case someone stumbles on this post looking for an answer: > > A solution that worked for me was redirecting the Python stdout/stderr to a > stream in Python. I was then able to route this stream into the .NET text box. > > private void button1_Click(object sender, EventArgs e) > { > using > (Py.GIL()) > { > // Redirect stdout to text box > dynamic sys = PythonEngine.ImportModule("sys"); > > string codeToRedirectOutput = > "import sys\n" + > "from io import StringIO\n" + > "sys.stdout = mystdout = StringIO()\n" + > "sys.stdout.flush()\n" + > "sys.stderr = mystderr = StringIO()\n" + > "sys.stderr.flush()\n"; > > PythonEngine.RunString(codeToRedirectOutput); > > > // Run Python code > string pyCode = "print(1 + 2)"; > PyObject result = PythonEngine.RunString(pyCode); // null in case of error > if (result != null) > { > string pyStdout = sys.stdout.getvalue(); // Get stdout > pyStdout > = pyStdout.Replace("\n", "\r\n"); // To support newline for textbox > textBox1 > .Text = pyStdout; > } > else > { > PythonEngine.PrintError(); // Make Python engine print errors > string pyStderr = sys.stderr.getvalue(); // Get stderr > pyStderr = pyStderr.Replace("\n", "\r\n"); // To support newline > for textbox > > textBox1.Text = pyStderr; > } > } > } > With this code, I was able to redirect the stdout (and stderr in the case of > an error) from the Python engine to a .NET text box. > > > On Wed, May 18, 2016 at 12:02 AM, Saparya K wrote: > Hi Denis, > Thanks for pointing me to the new API. I am now able to embed Python in my C# > code and access Python classes and methods from C#! > > Hi Nils, > Your application looks very interesting and some of the features (e.g. > ma