[Zope-CVS] CVS: PythonNet/src/runtime - ClassManager.cs:1.9
ClassObject.cs:1.11 Converter.cs:1.9 MetaType.cs:1.9
MethodBinder.cs:1.9 ModuleObject.cs:1.5 Python.cs:1.6
Runtime.cs:1.14 TypeManager.cs:1.11
Brian Lloyd
brian at zope.com
Sat Jan 17 23:30:07 EST 2004
Update of /cvs-repository/PythonNet/src/runtime
In directory cvs.zope.org:/tmp/cvs-serv26381/src/runtime
Modified Files:
ClassManager.cs ClassObject.cs Converter.cs MetaType.cs
MethodBinder.cs ModuleObject.cs Python.cs Runtime.cs
TypeManager.cs
Log Message:
Checkin miscellaneous stuff done since Nov.
=== PythonNet/src/runtime/ClassManager.cs 1.8 => 1.9 ===
--- PythonNet/src/runtime/ClassManager.cs:1.8 Mon Oct 27 21:07:00 2003
+++ PythonNet/src/runtime/ClassManager.cs Sat Jan 17 23:29:36 2004
@@ -105,15 +105,20 @@
// Finally, initialize the class __dict__ and return the object.
IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict);
- IDictionaryEnumerator iter;
- ManagedType item;
- string name;
-
- iter = info.members.GetEnumerator();
+ IDictionaryEnumerator iter = info.members.GetEnumerator();
while(iter.MoveNext()) {
- item = (ManagedType)iter.Value;
- name = (string)iter.Key;
+ ManagedType item = (ManagedType)iter.Value;
+ string name = (string)iter.Key;
Runtime.PyDict_SetItemString(dict, name, item.pyHandle);
+ }
+
+ // If class has constructors, generate an __doc__ attribute.
+
+ ClassObject co = impl as ClassObject;
+ if (co != null) {
+ IntPtr doc = co.GetDocString();
+ Runtime.PyDict_SetItemString(dict, "__doc__", doc);
+ Runtime.Decref(doc);
}
return impl;
=== PythonNet/src/runtime/ClassObject.cs 1.10 => 1.11 ===
--- PythonNet/src/runtime/ClassObject.cs:1.10 Thu Nov 6 23:05:05 2003
+++ PythonNet/src/runtime/ClassObject.cs Sat Jan 17 23:29:36 2004
@@ -37,6 +37,22 @@
//====================================================================
+ // Helper to get docstring from reflected constructor info.
+ //====================================================================
+
+ internal IntPtr GetDocString() {
+ MethodBase[] methods = binder.GetMethods();
+ string str = "";
+ for (int i = 0; i < methods.Length; i++) {
+ if (str.Length > 0)
+ str += Environment.NewLine;
+ str += methods[i].ToString();
+ }
+ return Runtime.PyString_FromString(str);
+ }
+
+
+ //====================================================================
// Implements __new__ for reflected classes and value types.
//====================================================================
=== PythonNet/src/runtime/Converter.cs 1.8 => 1.9 ===
--- PythonNet/src/runtime/Converter.cs:1.8 Mon Oct 27 23:00:45 2003
+++ PythonNet/src/runtime/Converter.cs Sat Jan 17 23:29:36 2004
@@ -183,17 +183,17 @@
return false;
}
+ if (value == Runtime.PyNone && !obType.IsValueType) {
+ result = null;
+ return true;
+ }
+
if (obType.IsArray) {
return ToArray(value, obType, out result, setError);
}
if (obType.IsEnum) {
return ToEnum(value, obType, out result, setError);
- }
-
- if (value == Runtime.PyNone && !obType.IsValueType) {
- result = null;
- return true;
}
// Conversion to 'Object' is done based on some reasonable
=== PythonNet/src/runtime/MetaType.cs 1.8 => 1.9 ===
--- PythonNet/src/runtime/MetaType.cs:1.8 Mon Oct 27 21:07:00 2003
+++ PythonNet/src/runtime/MetaType.cs Sat Jan 17 23:29:36 2004
@@ -99,36 +99,44 @@
}
// hack for now... fix for 1.0
- return TypeManager.CreateSubType(args);
+ //return TypeManager.CreateSubType(args);
- // Now that we've done sanity checking to make sure that it is
- // appropriate to subclass the given class,
-// IntPtr func = Marshal.ReadIntPtr(Runtime.PyTypeType,
-// TypeOffset.tp_new);
-// IntPtr type = NativeCall.Call_3(func, tp, args, kw);
-// if (type == IntPtr.Zero) {
-// return IntPtr.Zero;
-// }
-
-// int flags = TypeFlags.Default;
-// flags |= TypeFlags.Managed;
-// flags |= TypeFlags.HeapType;
-// flags |= TypeFlags.BaseType;
-// flags |= TypeFlags.Subclass;
-// flags |= TypeFlags.HaveGC;
-// Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
-
-// TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc);
-
-// // for now, move up hidden handle...
-// IntPtr gc = Marshal.ReadIntPtr(base_type, TypeOffset.magic());
-// Marshal.WriteIntPtr(type, TypeOffset.magic(), gc);
+ // right way
-// //DebugUtil.DumpType(base_type);
-// //DebugUtil.DumpType(type);
+ IntPtr func = Marshal.ReadIntPtr(Runtime.PyTypeType,
+ TypeOffset.tp_new);
+ IntPtr type = NativeCall.Call_3(func, tp, args, kw);
+ if (type == IntPtr.Zero) {
+ return IntPtr.Zero;
+ }
+
+ int flags = TypeFlags.Default;
+ flags |= TypeFlags.Managed;
+ flags |= TypeFlags.HeapType;
+ flags |= TypeFlags.BaseType;
+ flags |= TypeFlags.Subclass;
+ flags |= TypeFlags.HaveGC;
+ Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
+
+ TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc);
+
+ // Hmm - the standard subtype_traverse, clear look at ob_size to
+ // do things, so to allow gc to work correctly we need to move
+ // our hidden handle out of ob_size. Then, in theory we can
+ // comment this out and still not crash.
+ TypeManager.CopySlot(base_type, type, TypeOffset.tp_traverse);
+ TypeManager.CopySlot(base_type, type, TypeOffset.tp_clear);
+
+
+ // for now, move up hidden handle...
+ IntPtr gc = Marshal.ReadIntPtr(base_type, TypeOffset.magic());
+ Marshal.WriteIntPtr(type, TypeOffset.magic(), gc);
-// return type;
+ //DebugUtil.DumpType(base_type);
+ //DebugUtil.DumpType(type);
+
+ return type;
}
@@ -230,7 +238,6 @@
[CallConvCdecl()]
public static void tp_dealloc(IntPtr tp) {
-
// Fix this when we dont cheat on the handle for subclasses!
int flags = (int)Marshal.ReadIntPtr(tp, TypeOffset.tp_flags);
=== PythonNet/src/runtime/MethodBinder.cs 1.8 => 1.9 ===
--- PythonNet/src/runtime/MethodBinder.cs:1.8 Mon Oct 27 23:00:45 2003
+++ PythonNet/src/runtime/MethodBinder.cs Sat Jan 17 23:29:36 2004
@@ -130,7 +130,7 @@
for (int i = 0; i < _methods.Length; i++) {
MethodBase mi = _methods[i];
-
+ //Console.WriteLine("trying: {0}", mi.ToString());
ParameterInfo[] pi = mi.GetParameters();
int count = pi.Length;
@@ -143,6 +143,8 @@
Type type = pi[n].ParameterType;
Object arg;
if (!Converter.ToManaged(op, type, out arg, false)) {
+ //Console.WriteLine("failed on: {0}", type.ToString());
+ //DebugUtil.Print("ob is: ", op);
Exceptions.Clear();
margs = null;
break;
=== PythonNet/src/runtime/ModuleObject.cs 1.4 => 1.5 ===
--- PythonNet/src/runtime/ModuleObject.cs:1.4 Wed Oct 22 22:53:10 2003
+++ PythonNet/src/runtime/ModuleObject.cs Sat Jan 17 23:29:36 2004
@@ -30,7 +30,7 @@
string moduleName;
string _namespace;
Hashtable cache;
- bool hacked;
+ static bool hacked;
IntPtr dict;
public ModuleObject(string name) : base() {
@@ -41,6 +41,7 @@
dict = Runtime.PyDict_New();
IntPtr pyname = Runtime.PyString_FromString(moduleName);
Runtime.PyDict_SetItemString(dict, "__name__", pyname);
+ Runtime.PyDict_SetItemString(dict, "__file__", Runtime.PyNone);
Runtime.PyDict_SetItemString(dict, "__doc__", Runtime.PyNone);
Runtime.Decref(pyname);
=== PythonNet/src/runtime/Python.cs 1.5 => 1.6 ===
--- PythonNet/src/runtime/Python.cs:1.5 Thu Nov 6 23:05:05 2003
+++ PythonNet/src/runtime/Python.cs Sat Jan 17 23:29:36 2004
@@ -60,6 +60,132 @@
public static void InitExt() {
Initialize();
+
+ // Trickery - when the import hook is installed into an already
+ // running Python, the standard import machinery is still in
+ // control for the duration of the import that caused bootstrap.
+ //
+ // That is problematic because the std machinery tries to get
+ // sub-names directly from the module __dict__ rather than going
+ // through our module object's getattr hook. This workaround
+ // replaces the __dict__ of the root module with a proxy that
+ // delegates to the getattr of the root module. ;^/
+
+ string code =
+"import sys\n" +
+
+"class module(type(sys)):\n" +
+" def __init__(self, real):\n" +
+" self.dict = self.proxy(real)\n" +
+" self.real = real\n" +
+"\n" +
+" def __getattribute__(self, name):\n" +
+" print 'getattr: %s' % name\n" +
+" if name in ('dict', 'real', 'proxy'):\n" +
+" return super(type(self), self).__getattribute__(name)\n" +
+" real = super(type(self), self).__getattribute__('real')\n" +
+" return getattr(real, name)\n" +
+"\n" +
+" class proxy(dict):\n" +
+" def __init__(self, real):\n" +
+" self.real = real\n" +
+" def __getitem__(self, name):\n" +
+" print 'getitem: %s' % name\n" +
+" return getattr(self.real, name)\n" +
+" def __setitem__(self, name, val):\n" +
+" obj = self.real.__dict__\n" +
+" dict.__setitem__(obj, name, val)\n" +
+" def keys(self):\n" +
+" return self.real.__dict__.keys()\n" +
+"\n" +
+"clr = sys.modules['CLR']\n" +
+"sys.modules['CLR'] = module(clr)\n" +
+"dict = sys.modules['CLR'].dict\n";
+
+ IntPtr globals = Runtime.PyEval_GetGlobals();
+ IntPtr locals = Runtime.PyDict_New();
+ IntPtr flag = (IntPtr)257; /* Py_file_input */
+ IntPtr done = Runtime.PyRun_String(code, flag, globals, locals);
+
+ IntPtr dict = Runtime.PyDict_GetItemString(locals, "dict");
+ Runtime.Decref(globals);
+ Runtime.Decref(locals);
+ Runtime.Decref(done);
+
+ IntPtr temp = Runtime.PyImport_GetModuleDict();
+ IntPtr mod = Runtime.PyDict_GetItemString(temp, "CLR");
+ Marshal.WriteIntPtr(mod, ObjectOffset.ob_dict, dict);
+ }
+
+
+ public static void OldInitExt() {
+ Initialize();
+
+ // Trickery - when the import hook is installed into an already
+ // running Python, the standard import machinery is still in
+ // control for the duration of the import that caused bootstrap.
+ //
+ // That is problematic because the std machinery tries to get
+ // sub-names directly from the module __dict__ rather than going
+ // through our module object's getattr hook. This workaround
+ // replaces the __dict__ of the root module with a proxy that
+ // delegates to the getattr of the root module. ;^/
+
+ IntPtr temp = Runtime.PyImport_GetModuleDict();
+ IntPtr mod = Runtime.PyDict_GetItemString(temp, "CLR");
+
+ string code = "class faux(dict):\n" +
+ " def __init__(self, ob, dict):\n" +
+ " self.dict = dict\n" +
+ " self.ob = ob\n" +
+ " def __getitem__(self, key):\n" +
+ " print 'getitem called!'\n" +
+ " v = self.dict.get(key)\n" +
+ " if v is not None:\n" +
+ " return v\n" +
+ " return getattr(self.ob, key)\n"+
+ " def __setitem__(self, key, val):\n" +
+ " self.dict[key] = val\n\n" +
+
+ "import pdb; pdb.set_trace()\n";
+
+
+
+ IntPtr globals = Runtime.PyEval_GetGlobals();
+ IntPtr locals = Runtime.PyDict_New();
+ IntPtr flag = (IntPtr)257; /* Py_file_input */
+ IntPtr cls = Runtime.PyRun_String(code, flag, globals, locals);
+
+ Runtime.Decref(globals);
+ Runtime.Decref(cls);
+
+ cls = Runtime.PyDict_GetItemString(locals, "faux");
+ Runtime.Decref(locals);
+
+ IntPtr old = Marshal.ReadIntPtr(mod, ObjectOffset.ob_dict);
+ IntPtr args = Runtime.PyTuple_New(2);
+ Runtime.Incref(mod);
+ Runtime.PyTuple_SetItem(args, 0, mod);
+ Runtime.Incref(old);
+ Runtime.PyTuple_SetItem(args, 1, old);
+
+ IntPtr dict = Runtime.PyObject_CallObject(cls, args);
+ Runtime.Decref(cls);
+ Runtime.Decref(args);
+
+ Marshal.WriteIntPtr(mod, ObjectOffset.ob_dict, dict);
+
+ //Runtime.PyObject_SetAttrString(mod, "__dict__", dict);
+ /*
+
+ import sys
+ clr = sys.modules['CLR']
+
+
+ */
+ Runtime.Decref(mod);
+
+
}
@@ -197,6 +323,7 @@
public static int RunSimpleString(string code) {
return Runtime.PyRun_SimpleString(code);
}
+
/// <summary>
=== PythonNet/src/runtime/Runtime.cs 1.13 => 1.14 ===
--- PythonNet/src/runtime/Runtime.cs:1.13 Thu Nov 6 23:05:05 2003
+++ PythonNet/src/runtime/Runtime.cs Sat Jan 17 23:29:36 2004
@@ -312,6 +312,17 @@
[DllImport("python23", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
+ internal unsafe static extern IntPtr
+ PyEval_GetGlobals();
+
+ [DllImport("python23", CallingConvention=CallingConvention.Cdecl,
+ ExactSpelling=true, CharSet=CharSet.Ansi)]
+ internal unsafe static extern IntPtr
+ PyEval_GetLocals();
+
+
+ [DllImport("python23", CallingConvention=CallingConvention.Cdecl,
+ ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern string
Py_GetProgramName();
@@ -359,6 +370,11 @@
ExactSpelling=true, CharSet=CharSet.Ansi)]
internal unsafe static extern int
PyRun_SimpleString(string code);
+
+ [DllImport("python23", CallingConvention=CallingConvention.Cdecl,
+ ExactSpelling=true, CharSet=CharSet.Ansi)]
+ internal unsafe static extern IntPtr
+ PyRun_String(string code, IntPtr st, IntPtr globals, IntPtr locals);
[DllImport("python23", CallingConvention=CallingConvention.Cdecl,
ExactSpelling=true, CharSet=CharSet.Ansi)]
=== PythonNet/src/runtime/TypeManager.cs 1.10 => 1.11 ===
--- PythonNet/src/runtime/TypeManager.cs:1.10 Mon Oct 27 21:07:00 2003
+++ PythonNet/src/runtime/TypeManager.cs Sat Jan 17 23:29:36 2004
@@ -175,10 +175,11 @@
impl.gcHandle = gc;
impl.pyHandle = type;
+ //DebugUtil.DumpType(type);
+
return type;
}
-
internal static IntPtr CreateSubType(IntPtr args) {
IntPtr py_name = Runtime.PyTuple_GetItem(args, 0);
@@ -231,7 +232,6 @@
}
-
internal static IntPtr CreateMetaType(Type impl) {
// The managed metatype is functionally little different than the
@@ -274,6 +274,47 @@
Runtime.PyDict_SetItemString(dict, "__module__", mod);
//DebugUtil.DumpType(type);
+
+ return type;
+ }
+
+
+ internal static IntPtr BasicSubType(string name, IntPtr base_,
+ Type impl) {
+
+ // Utility to create a subtype of a std Python type, but with
+ // a managed type able to override implementation
+
+ IntPtr type = AllocateTypeObject(name);
+ //Marshal.WriteIntPtr(type, TypeOffset.tp_basicsize, (IntPtr)obSize);
+ //Marshal.WriteIntPtr(type, TypeOffset.tp_itemsize, IntPtr.Zero);
+
+ //IntPtr offset = (IntPtr)ObjectOffset.ob_dict;
+ //Marshal.WriteIntPtr(type, TypeOffset.tp_dictoffset, offset);
+
+ //IntPtr dc = Runtime.PyDict_Copy(dict);
+ //Marshal.WriteIntPtr(type, TypeOffset.tp_dict, dc);
+
+ Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_);
+ Runtime.Incref(base_);
+
+ int flags = TypeFlags.Default;
+ flags |= TypeFlags.Managed;
+ flags |= TypeFlags.HeapType;
+ flags |= TypeFlags.HaveGC;
+ Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);
+
+ CopySlot(base_, type, TypeOffset.tp_traverse);
+ CopySlot(base_, type, TypeOffset.tp_clear);
+ CopySlot(base_, type, TypeOffset.tp_is_gc);
+
+ InitializeSlots(type, impl);
+
+ Runtime.PyType_Ready(type);
+
+ IntPtr tp_dict = Marshal.ReadIntPtr(type, TypeOffset.tp_dict);
+ IntPtr mod = Runtime.PyString_FromString("CLR");
+ Runtime.PyDict_SetItemString(tp_dict, "__module__", mod);
return type;
}
More information about the Zope-CVS
mailing list