
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