/// <summary> /// Set the 'args' slot on a python exception object that wraps /// a CLR exception. This is needed for pickling CLR exceptions as /// BaseException_reduce will only check the slots, bypassing the /// __getattr__ implementation, and thus dereferencing a NULL /// pointer. /// </summary> /// <param name="ob">The python object wrapping </param> internal static void SetArgsAndCause(IntPtr ob) { // e: A CLR Exception Exception e = ExceptionClassObject.ToException(ob); if (e == null) { return; } IntPtr args; if (!string.IsNullOrEmpty(e.Message)) { args = Runtime.PyTuple_New(1); IntPtr msg = Runtime.PyUnicode_FromString(e.Message); Runtime.PyTuple_SetItem(args, 0, msg); } else { args = Runtime.PyTuple_New(0); } Marshal.WriteIntPtr(ob, ExceptionOffset.args, args); #if PYTHON3 if (e.InnerException != null) { IntPtr cause = CLRObject.GetInstHandle(e.InnerException); Marshal.WriteIntPtr(ob, ExceptionOffset.cause, cause); } #endif }
//==================================================================== // Exceptions __getattribute__ implementation. // handles Python's args and message attributes //==================================================================== public static IntPtr tp_getattro(IntPtr ob, IntPtr key) { if (!Runtime.PyString_Check(key)) { Exceptions.SetError(Exceptions.TypeError, "string expected"); return(IntPtr.Zero); } string name = Runtime.GetManagedString(key); if (name == "args") { Exception e = ToException(ob); IntPtr args; if (e.Message != String.Empty) { args = Runtime.PyTuple_New(1); IntPtr msg = Runtime.PyUnicode_FromString(e.Message); Runtime.PyTuple_SetItem(args, 0, msg); } else { args = Runtime.PyTuple_New(0); } return(args); } if (name == "message") { return(ExceptionClassObject.tp_str(ob)); } return(Runtime.PyObject_GenericGetAttr(ob, key)); }
//=================================================================== // Preloads all currently-known names for the module namespace. This // can be called multiple times, to add names from assemblies that // may have been loaded since the last call to the method. //=================================================================== public void LoadNames() { ManagedType m = null; foreach (string name in AssemblyManager.GetNames(_namespace)) { this.cache.TryGetValue(name, out m); if (m == null) { ManagedType attr = this.GetAttribute(name, true); if (Runtime.wrap_exceptions) { if (attr is ExceptionClassObject) { ExceptionClassObject c = attr as ExceptionClassObject; if (c != null) { IntPtr p = attr.pyHandle; IntPtr r = Exceptions.GetExceptionClassWrapper(p); Runtime.PyDict_SetItemString(dict, name, r); Runtime.Incref(r); } } } } } }
/// <summary> /// Create a new ClassBase-derived instance that implements a reflected /// managed type. The new object will be associated with a generated /// Python type object. /// </summary> private static ClassBase CreateClass(Type type) { // Next, select the appropriate managed implementation class. // Different kinds of types, such as array types or interface // types, want to vary certain implementation details to make // sure that the type semantics are consistent in Python. ClassBase impl; // Check to see if the given type extends System.Exception. This // lets us check once (vs. on every lookup) in case we need to // wrap Exception-derived types in old-style classes if (type.ContainsGenericParameters) { impl = new GenericType(type); } else if (type.IsSubclassOf(dtype)) { impl = new DelegateObject(type); } else if (type.IsArray) { impl = new ArrayObject(type); } else if (type.IsKeyValuePairEnumerable()) { impl = new KeyValuePairEnumerableObject(type); } else if (type.IsInterface) { impl = new InterfaceObject(type); } else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception))) { impl = new ExceptionClassObject(type); } else if (null != type.GetField("__pyobj__")) { impl = new ClassDerivedObject(type); } else { impl = new ClassObject(type); } return(impl); }
//==================================================================== // ModuleObject __getattribute__ implementation. Module attributes // are always either classes or sub-modules representing subordinate // namespaces. CLR modules implement a lazy pattern - the sub-modules // and classes are created when accessed and cached for future use. //==================================================================== public static IntPtr tp_getattro(IntPtr ob, IntPtr key) { ModuleObject self = (ModuleObject)GetManagedObject(ob); if (!Runtime.PyString_Check(key)) { Exceptions.SetError(Exceptions.TypeError, "string expected"); return(IntPtr.Zero); } IntPtr op = Runtime.PyDict_GetItem(self.dict, key); if (op != IntPtr.Zero) { Runtime.Incref(op); return(op); } string name = Runtime.GetManagedString(key); if (name == "__dict__") { Runtime.Incref(self.dict); return(self.dict); } ManagedType attr = self.GetAttribute(name, true); if (attr == null) { Exceptions.SetError(Exceptions.AttributeError, name); return(IntPtr.Zero); } // XXX - hack required to recognize exception types. These types // may need to be wrapped in old-style class wrappers in versions // of Python where new-style classes cannot be used as exceptions. if (Runtime.wrap_exceptions) { if (attr is ExceptionClassObject) { ExceptionClassObject c = attr as ExceptionClassObject; if (c != null) { IntPtr p = attr.pyHandle; IntPtr r = Exceptions.GetExceptionClassWrapper(p); Runtime.PyDict_SetItemString(self.dict, name, r); Runtime.Incref(r); return(r); } } } Runtime.Incref(attr.pyHandle); return(attr.pyHandle); }
//==================================================================== // Create a new ClassBase-derived instance that implements a reflected // managed type. The new object will be associated with a generated // Python type object. //==================================================================== private static ClassBase CreateClass(Type type) { // First, we introspect the managed type and build some class // information, including generating the member descriptors // that we'll be putting in the Python class __dict__. ClassInfo info = GetClassInfo(type); // Next, select the appropriate managed implementation class. // Different kinds of types, such as array types or interface // types, want to vary certain implementation details to make // sure that the type semantics are consistent in Python. ClassBase impl; // Check to see if the given type extends System.Exception. This // lets us check once (vs. on every lookup) in case we need to // wrap Exception-derived types in old-style classes if (type.ContainsGenericParameters) { impl = new GenericType(type); } else if (type.IsSubclassOf(dtype)) { impl = new DelegateObject(type); } else if (type.IsArray) { impl = new ArrayObject(type); } else if (type.IsInterface) { impl = new InterfaceObject(type); } else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception))) { impl = new ExceptionClassObject(type); } else { impl = new ClassObject(type); } impl.indexer = info.indexer; // Now we allocate the Python type object to reflect the given // managed type, filling the Python type slots with thunks that // point to the managed methods providing the implementation. IntPtr tp = TypeManager.GetTypeHandle(impl, type); impl.tpHandle = tp; // Finally, initialize the class __dict__ and return the object. IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict); IDictionaryEnumerator iter = info.members.GetEnumerator(); while (iter.MoveNext()) { 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); }
//==================================================================== // Create a new ClassBase-derived instance that implements a reflected // managed type. The new object will be associated with a generated // Python type object. //==================================================================== private static ClassBase CreateClass(Type type) { // Next, select the appropriate managed implementation class. // Different kinds of types, such as array types or interface // types, want to vary certain implementation details to make // sure that the type semantics are consistent in Python. ClassBase impl; // Check to see if the given type extends System.Exception. This // lets us check once (vs. on every lookup) in case we need to // wrap Exception-derived types in old-style classes if (type.ContainsGenericParameters) { impl = new GenericType(type); } else if (type.IsSubclassOf(dtype)) { impl = new DelegateObject(type); } else if (type.IsArray) { impl = new ArrayObject(type); } else if (type.IsInterface) { impl = new InterfaceObject(type); } else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception))) { impl = new ExceptionClassObject(type); } else if (null != type.GetField("__pyobj__")) { impl = new ClassDerivedObject(type); } else { impl = new ClassObject(type); } return impl; }
//==================================================================== // Create a new ClassBase-derived instance that implements a reflected // managed type. The new object will be associated with a generated // Python type object. //==================================================================== private static ClassBase CreateClass(Type type) { // First, we introspect the managed type and build some class // information, including generating the member descriptors // that we'll be putting in the Python class __dict__. ClassInfo info = GetClassInfo(type); // Next, select the appropriate managed implementation class. // Different kinds of types, such as array types or interface // types, want to vary certain implementation details to make // sure that the type semantics are consistent in Python. ClassBase impl; // Check to see if the given type extends System.Exception. This // lets us check once (vs. on every lookup) in case we need to // wrap Exception-derived types in old-style classes if (type.ContainsGenericParameters) { impl = new GenericType(type); } else if (type.IsSubclassOf(dtype)) { impl = new DelegateObject(type); } else if (type.IsArray) { impl = new ArrayObject(type); } else if (type.IsInterface) { impl = new InterfaceObject(type); } else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception))) { impl = new ExceptionClassObject(type); } else { impl = new ClassObject(type); } impl.indexer = info.indexer; // Now we allocate the Python type object to reflect the given // managed type, filling the Python type slots with thunks that // point to the managed methods providing the implementation. IntPtr tp = TypeManager.GetTypeHandle(impl, type); impl.tpHandle = tp; // Finally, initialize the class __dict__ and return the object. IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict); IDictionaryEnumerator iter = info.members.GetEnumerator(); while (iter.MoveNext()) { 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. IntPtr doc; Type marker = typeof(DocStringAttribute); Attribute[] attrs = (Attribute[])type.GetCustomAttributes(marker, false); if (attrs.Length == 0) { doc = IntPtr.Zero; } else { DocStringAttribute attr = (DocStringAttribute)attrs[0]; string docStr = attr.DocString; doc = Runtime.PyString_FromString(docStr); Runtime.PyDict_SetItemString(dict, "__doc__", doc); Runtime.Decref(doc); } ClassObject co = impl as ClassObject; // If this is a ClassObject AND it has constructors, generate a __doc__ attribute. // required that the ClassObject.ctors be changed to internal if (co != null) { if (co.ctors.Length > 0) { // Implement Overloads on the class object if (!CLRModule._SuppressOverloads) { ConstructorBinding ctors = new ConstructorBinding(type, tp, co.binder); // ExtensionType types are untracked, so don't Incref() them. // XXX deprecate __overloads__ soon... Runtime.PyDict_SetItemString(dict, "__overloads__", ctors.pyHandle); Runtime.PyDict_SetItemString(dict, "Overloads", ctors.pyHandle); } if (!CLRModule._SuppressDocs) { doc = co.GetDocString(); Runtime.PyDict_SetItemString(dict, "__doc__", doc); Runtime.Decref(doc); } } } return(impl); }
//==================================================================== // Create a new ClassBase-derived instance that implements a reflected // managed type. The new object will be associated with a generated // Python type object. //==================================================================== private static ClassBase CreateClass(Type type) { // First, we introspect the managed type and build some class // information, including generating the member descriptors // that we'll be putting in the Python class __dict__. ClassInfo info = GetClassInfo(type); // Next, select the appropriate managed implementation class. // Different kinds of types, such as array types or interface // types, want to vary certain implementation details to make // sure that the type semantics are consistent in Python. ClassBase impl; // Check to see if the given type extends System.Exception. This // lets us check once (vs. on every lookup) in case we need to // wrap Exception-derived types in old-style classes if (type.ContainsGenericParameters) { impl = new GenericType(type); } else if (type.IsSubclassOf(dtype)) { impl = new DelegateObject(type); } else if (type.IsArray) { impl = new ArrayObject(type); } else if (type.IsInterface) { impl = new InterfaceObject(type); } else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception))) { impl = new ExceptionClassObject(type); } else { impl = new ClassObject(type); } impl.indexer = info.indexer; // Now we allocate the Python type object to reflect the given // managed type, filling the Python type slots with thunks that // point to the managed methods providing the implementation. IntPtr tp = TypeManager.GetTypeHandle(impl, type); impl.tpHandle = tp; // Finally, initialize the class __dict__ and return the object. IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict); IDictionaryEnumerator iter = info.members.GetEnumerator(); while(iter.MoveNext()) { 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. IntPtr doc; Type marker = typeof(DocStringAttribute); Attribute[] attrs = (Attribute[])type.GetCustomAttributes(marker, false); if (attrs.Length == 0) { doc = IntPtr.Zero; } else { DocStringAttribute attr = (DocStringAttribute)attrs[0]; string docStr = attr.DocString; doc = Runtime.PyString_FromString(docStr); Runtime.PyDict_SetItemString(dict, "__doc__", doc); Runtime.Decref(doc); } ClassObject co = impl as ClassObject; // If this is a ClassObject AND it has constructors, generate a __doc__ attribute. // required that the ClassObject.ctors be changed to internal if (co != null) { if (co.ctors.Length > 0) { // Implement Overloads on the class object ConstructorBinding ctors = new ConstructorBinding(type, tp, co.binder); // ExtensionType types are untracked, so don't Incref() them. // XXX deprecate __overloads__ soon... Runtime.PyDict_SetItemString(dict, "__overloads__", ctors.pyHandle); Runtime.PyDict_SetItemString(dict, "Overloads", ctors.pyHandle); if (doc == IntPtr.Zero) { doc = co.GetDocString(); Runtime.PyDict_SetItemString(dict, "__doc__", doc); Runtime.Decref(doc); } } } return impl; }
//==================================================================== // Create a new ClassBase-derived instance that implements a reflected // managed type. The new object will be associated with a generated // Python type object. //==================================================================== private static ClassBase CreateClass(Type type) { // First, we introspect the managed type and build some class // information, including generating the member descriptors // that we'll be putting in the Python class __dict__. ClassInfo info = GetClassInfo(type); // Next, select the appropriate managed implementation class. // Different kinds of types, such as array types or interface // types, want to vary certain implementation details to make // sure that the type semantics are consistent in Python. ClassBase impl; // Check to see if the given type extends System.Exception. This // lets us check once (vs. on every lookup) in case we need to // wrap Exception-derived types in old-style classes if (type.ContainsGenericParameters) { impl = new GenericType(type); } else if (type.IsSubclassOf(dtype)) { impl = new DelegateObject(type); } else if (type.IsArray) { impl = new ArrayObject(type); } else if (type.IsInterface) { impl = new InterfaceObject(type); } else if (type == typeof(Exception) || type.IsSubclassOf(typeof(Exception))) { impl = new ExceptionClassObject(type); } else { impl = new ClassObject(type); } impl.indexer = info.indexer; // Now we allocate the Python type object to reflect the given // managed type, filling the Python type slots with thunks that // point to the managed methods providing the implementation. IntPtr tp = TypeManager.GetTypeHandle(impl, type); impl.tpHandle = tp; // Finally, initialize the class __dict__ and return the object. IntPtr dict = Marshal.ReadIntPtr(tp, TypeOffset.tp_dict); IDictionaryEnumerator iter = info.members.GetEnumerator(); while(iter.MoveNext()) { 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; }