Tips for Python .Net 2.0

Hello, I noticed some recent posts about creating a Python for .Net 2.0. I went through this about six weeks ago and learned some lessons that i think will help. I started with Michael Eddington's visual studio project (and thanks again Michael for this). However, i ran into some trouble and found some fixes. i communicated these to Michael so he may have incorporated them into his visual studio project already. but just in case he has not, i am writing out this email in case it helps anyone else. Pls feel free to ignore them if you don't need them. Lessons from Michael Eddington's Python for .Net 2.0: 1) the PythonNet2.0-0.1.zip file didn't include a file called "clrmodule.il" but I substituted with the original one from Brian's pythonnet-1.0-rc2-py2.4-clr1.1-src.zip 2) Then everything compiled and linked just fine. TestPython.exe worked fine and the Python.exe launched and I could do "import CLR" and "import CLR.System". However, I could not "import CLR.System.Windows" or "import CLR.System.Drawing": Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import CLR >>> import CLR.System.Windows Traceback (most recent call last): File "<stdin>", line 1, in ? ImportError: No module named Windows >>> import CLR.System.Drawing Traceback (most recent call last): File "<stdin>", line 1, in ? ImportError: No module named Drawing >>> 3) This problem is bc in .Net 2.0, System.Reflection.Assembly.LoadWithPartialName is now supposed to be obsolete (http://msdn2.microsoft.com/en-us/library/0a7zy9z5.aspx). And I recognized the change Michael made inside assemblymanager.cs's LoadAssembly method to reflect this. However, if you undo Michael's change to assemblymanager.LoadAssembly from: assembly = Assembly.Load(name) back to the original: assembly = Assembly.LoadWithPartialName(name) it will work correctly as it used to. LoadWithPartialName is not quite obsolete, it is merely deprecated. it still works in .Net 2.0. Run this code in a simple C# app to see what i mean: ---------------------------------------------------------------------------- ---------------- using System; using System.Collections.Generic; using System.Text; using System.Reflection; namespace Test_Assembly_Load { class Program { static void Main(string[] args) { Assembly assembly = null; Console.WriteLine("Try LoadWithPartialName - System.Windows.Forms"); assembly = Assembly.LoadWithPartialName("System.Windows.Forms"); Console.WriteLine("LoadWithPartialName - System.Windows.Forms: " + assembly.ToString()); Console.WriteLine("Try Load - System.Windows.Forms"); assembly = Assembly.Load("System.Windows.Forms"); // Causes runtime crash in both .net 1.1 and 2.0. Console.WriteLine("Load - System.Windows.Forms: " + assembly.ToString()); } } } ---------------------------------------------------------------------------- ---------------- 4) With the changes so far, I was able to use the PythonNet2.0 generated Python.exe with no problems. However, i wasnt able to use clr.dll and python.runtime.dll with a standard cpython interpretter, such as c:/python24/python.exe, winpython or ipython which i was albe to do with PythonNet 1.0. 5) To fix (4), i made two changes to Michael's project (which i suspect go back to Brian's original code). I commented out the code that performs the import hook replacement in pythonengine.InitEx(): // string code = // "import traceback\n" + // "for item in traceback.extract_stack():\n" + // " line = item[3]\n" + // " if line is not None:\n" + // " if line.startswith('import CLR') or \\\n" + // " line.startswith('from CLR'):\n" + // " exec line\n" + // " break\n"; // PyObject r = PythonEngine.RunString(code); // if (r != null) { // r.Dispose(); // } and rewrote a line of code in inputhook.Initialize(): Runtime.PyObject_SetAttrString(mod, "import_clr_dll", hook.ptr); //<- new line //Runtime.PyObject_SetAttrString(mod, "__import__", hook.ptr); <- replaces this old line What I have now leaves python's original import mechanism alone and for importing python-for-.net dlls I use a separate function that works as follows: C:\Documents and Settings\tbarket>python Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import CLR >>> import_clr_dll('CLR.System.Windows.Forms') <module 'CLR'> >>> CLR.System.Windows.Forms <module 'CLR.System.Windows.Forms'> Yes, I recognize it is a bit of a kludge to use "import_clr_dll('CLR.System.Windows.Forms')" instead of "import CLR.System.Windows.Forms" but i personally find this worth doing to get it to work with a standard c python interpretter via the two dlls and it was the only way i knew how to do it. i am not a profeesional programmer and a great deal of Python for .Net code is above my head and i felt very fortunate just to be able to get it to work again with these few changes. i also dont find this to be too much worse than the confusion generated over having to do an explicit "import CLR" before importing another CLR module. 6) Brian, as a personal note, i would strongly encourage you to keep going with Python for .Net regardless of IronPython. I personally have alot of python C/C++ extensions (and use alot of python modules which rely on other C/C++ extensions) which will keep me with cpython for a long, long, long time to come. Python for .Net allows me to use python as my preferred language of choice and still make use of the C# libraries that i find useful. ie, it continues python's wonderful tradition of gluing anything together. i also use C# to write my Windows GUI objects and utilize/populate them with data from my "real work code" in cpython. Moving from Python for .Net to IronPython would be like moving everything i have in C++ to C# which i am just not willing to do yet and wont for a long, long time. Tom Barket

Good to see some feedback, comments inlined. Should see a new post of my 2.0 release with some fixes today including just a binary release. On 2/20/06, T Barket <thomas_barket@yahoo.com> wrote:
Hello,
1) the PythonNet2.0-0.1.zip file didn't include a file called "clrmodule.il" but I substituted with the original one from Brian's pythonnet-1.0-rc2-py2.4-clr1.1-src.zip
Woops, not sure how that got left out :)
2) Then everything compiled and linked just fine. TestPython.exe worked fine and the Python.exe launched and I could do "import CLR" and "import CLR.System". However, I could not "import CLR.System.Windows" or "import CLR.System.Drawing":
[SNIP[
3) This problem is bc in .Net 2.0, System.Reflection.Assembly.LoadWithPartialName is now supposed to be obsolete (http://msdn2.microsoft.com/en-us/library/0a7zy9z5.aspx). And I
I've added some additional code, but I'm not happy going back to a depricated API as we need a correct solution. Thew loader code will try and locate the assembly in the installed .NET Framework directory if Load() fails. This does not solve loading assemblies in the GAC, but there is no doubt a way to toss that in. I'll investigate in the next week or so and see if I can't locate a current rev.
4) With the changes so far, I was able to use the PythonNet2.0 generated Python.exe with no problems. However, i wasnt able to use clr.dll and python.runtime.dll with a standard cpython interpretter, such as c:/python24/python.exe, winpython or ipython which i was albe to do with PythonNet 1.0.
Correct me if I'm wrong, but I don't think this was an origional intended feature.
5) To fix (4), i made two changes to Michael's project (which i suspect go back to Brian's original code). I commented out the code that performs the import hook replacement in pythonengine.InitEx():
I'm sure we can get the importing to work right, but not a project for today. I recommend just using the .NET console version. Shouldn't be any issues there.
6) Brian, as a personal note, i would strongly encourage you to keep going with Python for .Net regardless of IronPython. I personally have alot of
If anything else we can move the code over to source forge to continue development. mike
participants (2)
-
Michael Eddington
-
T Barket