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
_________________________________________________
Python.NET mailing list - [email protected]
http://mail.python.org/mailman/listinfo/pythondotnet